def __sub__(self, other): if isinstance(other, Constant): self = self + Constant(-1, 1, 1) * other return self elif isinstance(other, Variable): if self.value == 0: other.coefficient *= -1 return other expression = Expression() expression.tokens = [self] expression.tokens.extend([Minus(), other]) elif isinstance(other, Expression): expression = Expression() expression.tokens = [self] if other.power == 1: coeff = other.coefficient for i, token in enumerate(other.tokens): print(expression, " ", type(token), other.tokens[i-1]) if isinstance(token, Constant): if other.tokens[i-1].value == '+' or i == 0: expression.tokens[0] = Constant(self.calculate() - token.calculate()*coeff) elif other.tokens[i-1].value == '-': expression.tokens[0] = Constant(self.calculate() + token.calculate()*coeff) elif isinstance(token, Variable): if other.tokens[i-1].value == '+' or i == 0: expression.tokens.extend([Minus(), Variable(token)]) elif other.tokens[i-1].value == '-': expression.tokens.extend([Plus(), Variable(token)]) else: expression.tokens.extend([Minus(), other]) self = expression return expression
def __sub__(self, other): from visma.functions.constant import Constant if isinstance(other, Variable): otherValueSorted = sorted(other.value) selfValueSorted = sorted(self.value) if (other.power == self.power) & (selfValueSorted == otherValueSorted): self = self + Constant(-1, 1, 1) * other return self else: expression = Expression() expression.tokens = [self] expression.tokens.extend([Minus(), other]) self = expression return expression elif isinstance(other, Constant): if other.isZero(): return self expression = Expression() expression.tokens = [self] expression.tokens.extend([Minus(), other]) self = expression return expression elif isinstance(other, Expression): expression = Expression() expression.tokens = [self] for i, token in enumerate(other.tokens): if isinstance(token, Variable): tokenValueSorted = sorted(token.value) selfValueSorted = sorted(self.value) if (token.power == self.power) & (tokenValueSorted == selfValueSorted): if other.tokens[i - 1].value == '+' or (i == 0): self.coefficient -= other.tokens[i].coefficient elif other.tokens[i - 1].value == '-': self.coefficient += other.tokens[i].coefficient else: if other.tokens[i - 1].value == '+' or i == 0: expression.tokens.extend([Plus(), Variable(token)]) elif other.tokens[i - 1].value == '-': expression.tokens.extend( [Minus(), Variable(token)]) elif not isinstance(token, Binary): if other.tokens[i - 1].value == '+' or (i == 0): expression.tokens.extend([Minus(), token]) elif other.tokens[i - 1].value == '-': expression.tokens.extend([Plus(), token]) expression.tokens[0] = self self = expression return expression
def integrate(self, wrtVar): term1 = Constant(-1, 1, 1) term2 = NaturalLog() result = Expression() term3 = Cosecant() term3.operand = self.operand term4 = Cotangent() term4.operand = self.operand inExpression = Expression() inExpression.tokens = [term3, Plus(), term4] term2.operand = inExpression term2.power = 1 term2.coefficient = 1 result.tokens = [term1, Multiply(), term2] return result
def differentiate(self, wrtVar): term1 = Constant(-1, 1, 1) term2 = copy.deepcopy(self) term2.__class__ = Sine term2.value = 'sin' result = Expression() result.tokens = [term1, Multiply(), term2] return result
def integrate(self, wrtVar=None): term1 = Constant(-1, 1, 1) term2 = copy.deepcopy(self) term2.__class__ = Cosine term2.value = 'cos' term2.coefficient = 1 result = Expression() result.tokens = [term1, Multiply(), term2] return result
def differentiate(self, wrtVar): term1 = Constant(-1, 1, 1) term2 = copy.deepcopy(self) term2.__class__ = Cosecant term2.value = 'csc' term2.coefficient = 1 term2.power = 2 result = Expression() result.tokens = [term1, Multiply(), term2] return result
def differentiate(self, wrtVar): term1 = Constant(-1, 1, 1) term2 = Cosecant() term2.operand = self.operand term2.coefficient = 1 term3 = Cotangent() term3.operand = self.operand term3.coefficient = 1 result = Expression() result.tokens = [term1, Multiply(), term2, Multiply(), term3] return result
def integrate(self, wrtVar): term1 = Constant(-1, 1, 1) term2 = NaturalLog() term3 = Cosine() term3.operand = self.operand term2.operand = term3 term2.power = 1 term2.coefficient = 1 result = Expression() result.tokens = [term1, Multiply(), term2] return result
def integrate(self, wrtVar): resultTerm = NaturalLog() term3 = Secant() term3.operand = self.operand term4 = Tangent() term4.operand = self.operand inExpression = Expression() inExpression.tokens = [term3, Plus(), term4] resultTerm.operand = inExpression resultTerm.power = 1 resultTerm.coefficient = 1 return resultTerm
def __truediv__(self, other): from visma.functions.constant import Constant if isinstance(other, Variable) or isinstance(other, Constant): self = self * (other**Constant(-1, 1, 1)) return self elif isinstance(other, Expression): expression = Expression() self.coefficient /= other.coefficient other.power *= -1 expression.tokens = [self] expression.tokens.extend([Multiply(), other]) self = expression return expression
def differentiationProductRule(tokens, wrtVar): resultTokens = [] for i in range(0, len(tokens), 2): currentDiff = Expression() currentDiffTokens, _, _, _, _ = differentiate([tokens[i]], wrtVar) currentDiff.tokens = currentDiffTokens tempTokens = copy.deepcopy(tokens) tempTokens[i] = currentDiff resultTokens.extend(tempTokens) resultTokens.append(Plus()) resultTokens.pop() token_string = tokensToString(resultTokens) # TODO: Make simplify module to simplify expressions involving Trigonometric Expressions (to some extent) # resultTokens, _, token_string, _, _ = simplify(resultTokens) return tokens, [], token_string, [], []
def differentiateTokens(funclist, wrtVar): """Differentiates given tokens wrt given variable Arguments: funclist {list} -- list of function tokens wrtVar {string} -- with respect to variable Returns: diffFunc {list} -- list of differentiated tokens animNew {list} -- equation tokens for step-by-step commentsNew {list} -- comments for step-by-step """ diffFunc = [] animNew = [] commentsNew = ["Differentiating with respect to " + r"$" + wrtVar + r"$" + "\n"] for func in funclist: if isinstance(func, Operator): diffFunc.append(func) else: newExpression = Expression() newfunc = [] while(isinstance(func, Function)): commentsNew[0] += r"$" + "\\frac{d}{d" + wrtVar + "} ( " + func.__str__() + ")" + r"$" funcCopy = copy.deepcopy(func) if wrtVar in funcCopy.functionOf(): if isinstance(funcCopy, Trigonometric) or isinstance(funcCopy, Logarithm) or isinstance(funcCopy, Variable) or isinstance(funcCopy, Exponential): funcCopy = funcCopy.differentiate(wrtVar) newfunc.append(funcCopy) commentsNew[0] += r"$" + r"= " + funcCopy.__str__() + r"\ ;\ " + r"$" else: funcCopy = Zero() newfunc.append(funcCopy) commentsNew[0] += r"$" + r"= " + funcCopy.__str__() + r"\ ;\ " + r"$" newfunc.append(Multiply()) if func.operand is None: break else: func = func.operand if isinstance(func, Constant): diffFunc = Zero() break newfunc.pop() newExpression.tokens = newfunc diffFunc.extend([newExpression]) animNew.extend(diffFunc) return diffFunc, animNew, commentsNew
def integrate(self, wrtVar): if wrtVar not in self.value: self.value.append(wrtVar) self.power.append(1) else: for i, val in enumerate(self.value): if val == 'wrtVar': break if self.power[i] == -1: self.power.pop(i) self.value.pop(i) expression = Expression() expression.tokens = [self] variable = Variable(1, 'wrtVar', 1) expression.tokens.append(Logarithm(variable)) self.__class__ = Expression self = expression else: self.coefficient /= self.power[i] + 1 self.power[i] += 1
def cubicRoots(lTokens, rTokens): '''Used to get roots of a cubic equation This functions also translates roots {list} into final result of solution Argument: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens Returns: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens {empty list} token_string {string} -- final result stored in a string animation {list} -- list of equation solving process comments {list} -- list of comments in equation solving process ''' from visma.solvers.polynomial.roots import getCoefficients animations = [] comments = [] lTokens, rTokens, _, token_string, animNew1, commentNew1 = simplifyEquation( lTokens, rTokens) animations.extend(animNew1) comments.extend(commentNew1) if len(rTokens) > 0: lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens) coeffs = getCoefficients(lTokens, rTokens, 3) var = getVariables(lTokens) roots, animNew2, commentNew2 = getRootsCubic(coeffs) animations.extend(animNew2) comments.extend(commentNew2) tokens1 = [] expression1 = Expression(coefficient=1, power=3) variable = Variable(1, var[0], 1) tokens1.append(variable) if roots[0][1] == 0: binary = Binary() if roots[0][0] < 0: roots[0][0] *= -1 binary.value = '+' else: binary.value = '-' tokens1.append(binary) constant = Constant(round(roots[0][0], ROUNDOFF), 1) tokens1.append(constant) expression1.tokens = tokens1 lTokens = [expression1, Binary('*')] if len(roots) > 1: expression1.power = 1 for _, root in enumerate(roots[1:]): tokens2 = [] expression2 = Expression(coefficient=1, power=1) variable = Variable(1, var[0], 1) tokens2.append(variable) binary = Binary() if root[1] == 0: if root[0] < 0: root[0] *= -1 binary.value = '+' else: binary.value = '-' tokens2.append(binary) constant = Constant(round(root[0], ROUNDOFF), 1) tokens2.append(constant) else: binary.value = '-' tokens2.append(binary) expressionResult = Expression(coefficient=1, power=1) tokensResult = [] real = Constant(round(root[0], ROUNDOFF), 1) tokensResult.append(real) imaginary = Constant(round(root[1], ROUNDOFF), 1) if imaginary.value < 0: tokensResult.append(Minus()) imaginary.value = abs(imaginary.value) tokensResult.append(imaginary) else: tokensResult.extend([Plus(), imaginary]) sqrt = Sqrt(Constant(2, 1), Constant(-1, 1)) tokensResult.append(Binary('*')) tokensResult.append(sqrt) expressionResult.tokens = tokensResult tokens2.append(expressionResult) expression2.tokens = tokens2 lTokens.extend([expression2, Binary('*')]) lTokens.pop() rTokens = [Zero()] tokenToStringBuilder = copy.deepcopy(lTokens) tokLen = len(lTokens) equalTo = Binary() equalTo.scope = [tokLen] equalTo.value = '=' tokenToStringBuilder.append(equalTo) tokenToStringBuilder.extend(rTokens) token_string = tokensToString(tokenToStringBuilder) animations.append(copy.deepcopy(tokenToStringBuilder)) comments.append([]) return lTokens, rTokens, [], token_string, animations, comments
def quadraticRoots(lTokens, rTokens): '''Used to get quadratic roots of an equation Argument: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens Returns: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens {empty list} token_string {string} -- final result stored in a string animation {list} -- list of equation solving process comments {list} -- list of comments in equation solving process ''' from visma.solvers.polynomial.roots import getCoefficients animations = [] comments = [] lTokens, rTokens, _, token_string, animNew1, commentNew1 = simplifyEquation(lTokens, rTokens) animations.extend(animNew1) comments.extend(commentNew1) if len(rTokens) > 0: lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens) coeffs = getCoefficients(lTokens, rTokens, 2) var = getVariables(lTokens) roots, animNew2, commentNew2 = getRootsQuadratic(coeffs) animations.extend(animNew2) comments.extend(commentNew2) if len(roots) == 1: tokens = [] expression = Expression(coefficient=1, power=2) variable = Variable(1, var[0], 1) tokens.append(variable) binary = Binary() if roots[0] < 0: roots[0] *= -1 binary.value = '+' else: binary.value = '-' tokens.append(binary) constant = Constant(round(roots[0], ROUNDOFF), 1) tokens.append(constant) expression.tokens = tokens lTokens = [expression] elif len(roots) == 2: tokens = [] expression = Expression(coefficient=1, power=1) variable = Variable(1, var[0], 1) tokens.append(variable) binary = Binary() if roots[0] < 0: roots[0] *= -1 binary.value = '+' else: binary.value = '-' tokens.append(binary) constant = Constant(round(roots[0], ROUNDOFF), 1) tokens.append(constant) expression.tokens = tokens tokens2 = [] expression2 = Expression(coefficient=1, power=1) tokens2.append(variable) binary2 = Binary() if roots[1] < 0: roots[1] *= -1 binary2.value = '+' else: binary2.value = '-' tokens2.append(binary2) constant2 = Constant(round(roots[1], ROUNDOFF), 1) tokens2.append(constant2) expression2.tokens = tokens2 binary3 = Binary() binary3.value = '*' lTokens = [expression, binary3, expression2] elif len(roots) == 3: binary4 = Binary() if roots[0] < 0: roots[0] *= -1 binary4.value = '+' else: binary4.value = '-' constant3 = Constant(round(roots[0], ROUNDOFF), 1) binary5 = Binary() binary5.value = '*' constant2 = Constant(round(roots[2], ROUNDOFF), 1) tokens = [] expression = Expression(coefficient=1, power=1) variable = Variable(1, var[0], 1) tokens.extend([variable, binary4, constant3]) binary = Binary() binary.value = '+' tokens.extend([binary, constant2, binary5]) constant = Constant(round(roots[1], ROUNDOFF), 1) sqrt = Sqrt(Constant(2, 1), constant) tokens.append(sqrt) expression.tokens = tokens tokens2 = [] expression2 = Expression(coefficient=1, power=1) variable2 = Variable(1, var[0], 1) tokens2.extend([variable2, binary4, constant3]) binary2 = Binary() binary2.value = '-' tokens2.extend([binary2, constant2, binary5, sqrt]) expression2.tokens = tokens2 binary3 = Binary() binary3.value = '*' lTokens = [expression, binary3, expression2] zero = Zero() rTokens = [zero] comments.append([]) tokenToStringBuilder = copy.deepcopy(lTokens) tokLen = len(lTokens) equalTo = Binary() equalTo.scope = [tokLen] equalTo.value = '=' tokenToStringBuilder.append(equalTo) tokenToStringBuilder.extend(rTokens) animations.append(copy.deepcopy(tokenToStringBuilder)) token_string = tokensToString(tokenToStringBuilder) return lTokens, rTokens, [], token_string, animations, comments