Last active
October 29, 2019 16:33
-
-
Save erose/fa924ea0b7ebc0e09b2a18f3da85b329 to your computer and use it in GitHub Desktop.
Recurse Center application code -- symbolic differentiation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import * | |
import sys | |
import re | |
def differentiate(expression: List[str], with_respect_to: str) -> List[str]: | |
# We do the differentiation in one pass, then simplify the result. | |
first_pass = [_differentiate_single_term(t, with_respect_to) for t in expression] | |
simplified = _simplify_expression(first_pass) | |
return simplified | |
def _differentiate_single_term(term: str, x: str) -> str: | |
# The derivative of a constant is zero. | |
if not x in term: | |
return "0" | |
# The derivative of x is 1. | |
if (f'{x}^' not in term): # If x occurs in term, but has an exponent of 1. | |
if term == x: | |
return "1" | |
else: | |
return term.replace(x, "") | |
# The derivative of x^n is nx^(n-1). | |
if (f'{x}^' in term): | |
pattern = f'{x}\^(\d+)' | |
match = re.search(pattern, term) | |
if match is None: | |
raise ValueError("Something has gone wrong.") | |
n = int(match.group(1)) | |
return re.sub(pattern, f'{n}{x}^{n - 1}', term) | |
return term | |
def _simplify_expression(expression: List[str]): | |
# Remove zero terms. | |
expression = [t for t in expression if t != "0"] | |
# x^1 == x | |
expression = [t.replace("^1", "") for t in expression] | |
return expression | |
def raise_usage_error(): | |
raise RuntimeError("Use like this: python differentiate.py d/dx '1 + 2x + x^2'") | |
if __name__ == "__main__": | |
if len(sys.argv) < 2: | |
raise_usage_error() | |
first_token = sys.argv[1] | |
other_tokens = sys.argv[2].split(' ') | |
if not first_token.startswith("d/d"): | |
raise_usage_error() | |
variable = first_token[-1] | |
resulting_expression = differentiate(other_tokens, variable) | |
print(' + '.join(resulting_expression)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment