def integrate(self, wrtVar=None): from visma.functions.constant import Constant result = copy.deepcopy(self) log = False for i, var in enumerate(result.value): if var == wrtVar: if (result.power[i] == -1): log = True funcLog = Logarithm() funcLog.operand = Variable() funcLog.operand.coefficient = 1 funcLog.operand.value.append(result.value[i]) funcLog.operand.power.append(1) del result.power[i] del result.value[i] if result.value == []: result.__class__ = Constant result.value = result.coefficient result.coefficient = 1 result.power = 1 result = [result] funcJoin = Binary() funcJoin.value = '*' result.append(funcJoin) result.append(funcLog) else: result.power[i] += 1 result.coefficient /= result.power[i] print(result) return result, log
def equationAnimationBuilder(lTokens, rTokens): """Given LHS & RHS tokens for an equation it builds the tokens of complete equation Arguments: lTokens {list} -- Tokens of LHS rTokens {list} -- Tokens of RHS Returns: animBulder {list} -- list of tokens of complete equation """ animBuilder = [] lToks = copy.deepcopy(lTokens) rToks = copy.deepcopy(rTokens) animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) return animBuilder
def moveRTokensToLTokens(lTokens, rTokens): """Moves tokens in RHS to LHS Arguments: ltokens {list} -- LHS tokens list rtokens {list} -- RHS tokens list Returns: ltokens {list} -- LHS tokens list rtokens {list} -- RHS tokens list """ if len(lTokens) == 0 and len(rTokens) > 0: return rTokens, lTokens elif isEquation(lTokens, rTokens): return lTokens, rTokens elif len(lTokens) != 0: for i, token in enumerate(rTokens): if i == 0 and not isinstance(token, Binary): binary = Binary() binary.value = '-' binary.scope = copy.copy(token.scope) binary.scope[-1] -= 1 lTokens.append(binary) if isinstance(token, Binary): if token.value in ['+', '-']: if token.value == '-': token.value = '+' else: token.value = '-' elif isinstance(token, Constant): if token.value < 0: if isinstance(lTokens[-1], Binary): if lTokens[-1].value == '-': token.value *= -1 lTokens[-1].value = '+' elif lTokens[-1].value == '+': token.value *= -1 lTokens[-1].value = '-' elif isinstance(token, Variable): if token.coefficient < 0: if isinstance(lTokens[-1], Binary): if lTokens[-1].value == '-': token.coefficient *= -1 lTokens[-1].value = '+' elif lTokens[-1].value == '+': token.coefficient *= -1 lTokens[-1].value = '-' lTokens.append(token) rTokens = [] return lTokens, rTokens
def multiplyExpressions(expression1, expression2): tokens = [] tokens1 = expression1.tokens tokens2 = expression2.tokens coeff = expression1.coefficient * expression2.coefficient for i, token1 in enumerate(tokens1): # print(token1.value) op = 1 if i != 0: if isinstance(tokens1[i - 1], Binary): if tokens1[i - 1].value == '+': op *= 1 elif tokens1[i - 1].value == '-': op *= -1 if isinstance(token1, Variable) or isinstance(token1, Constant): for j, token2 in enumerate(tokens2): # print(token2.value) op2 = op if isinstance(token2, Variable) or isinstance(token2, Constant): if j == 0 and i == 0: pass else: if j != 0: if isinstance(tokens2[j - 1], Binary): if tokens2[j - 1].value == '+': op2 *= 1 elif tokens2[j - 1].value == '-': op2 *= -1 binary = Binary() if op2 == -1: binary.value = '-' elif op2 == 1: binary.value = '+' tokens.append(binary) tokens.append(multiplySelect(token1, token2, coeff))
def divisionEquation(lToks, rToks, direct=False): lTokens = copy.deepcopy(lToks) rTokens = copy.deepcopy(rToks) animation = [] comments = [] if direct: comments = [[]] animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) animation.append(copy.deepcopy(animBuilder)) lVariables = [] lVariables.extend(getLevelVariables(lTokens)) rVariables = [] rVariables.extend(getLevelVariables(rTokens)) availableOperations = getOperationsExpression(lVariables, lTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(lVariables, lTokens) lTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) lVariables = getLevelVariables(lTokens) availableOperations = getOperationsExpression(lVariables, lTokens) availableOperations = getOperationsExpression(rVariables, rTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(rVariables, rTokens) rTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsExpression(rVariables, rTokens) tokenToStringBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' tokenToStringBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] tokenToStringBuilder.append(zero) else: tokenToStringBuilder.extend(rTokens) token_string = tokensToString(tokenToStringBuilder) lVariables = getLevelVariables(lTokens) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsEquation( lVariables, lTokens, rVariables, rTokens) return lTokens, rTokens, availableOperations, token_string, animation, comments
def simplifyEquation(lToks, rToks): """Simplifies given equation tokens Arguments: lToks {list} -- LHS tokens list rToks {list} -- RHS tokens list Returns: lTokens {list} -- LHS tokens list rTokens {list} -- RHS tokens list availableOperations {list} -- list of operations token_string {string} -- simplified result in string animation {list} -- list of equation simplification progress comments {list} -- list of solution steps """ lTokens = copy.deepcopy(lToks) rTokens = copy.deepcopy(rToks) animation = [] comments = [[]] lVariables = [] lVariables.extend(getLevelVariables(lTokens)) rVariables = [] rVariables.extend(getLevelVariables(rTokens)) animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) animation.append(copy.deepcopy(animBuilder)) availableOperations = getOperationsEquation(lVariables, lTokens, rVariables, rTokens) while len(availableOperations) > 0: if '/' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = divisionEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '*' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = multiplicationEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '+' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = additionEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '-' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = subtractionEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) lVariables = getLevelVariables(lTokens) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsEquation(lVariables, lTokens, rVariables, rTokens) moved = False if len(rTokens) > 0: moved = True lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens) tokenToStringBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' tokenToStringBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] tokenToStringBuilder.append(zero) else: tokenToStringBuilder.extend(rTokens) if moved: animation.append(copy.deepcopy(tokenToStringBuilder)) comments.append(['Moving the rest of variables/constants to LHS']) token_string = tokensToString(tokenToStringBuilder) return lTokens, rTokens, availableOperations, token_string, animation, comments
def integrateTokens(funclist, wrtVar): """Integrates given tokens wrt given variable Arguments: funclist {list} -- list of funtion tokens wrtVar {string} -- with respect to variable Returns: intFunc {list} -- list of integrated tokens animNew {list} -- equation tokens for step-by-step commentsNew {list} -- comments for step-by-step """ intFunc = [] animNew = [] commentsNew = [ "Integrating with respect to " + r"$" + wrtVar + r"$" + "\n" ] for func in funclist: if isinstance(func, Operator): # add isFuntionOf intFunc.append(func) else: newfunc = [] while (isinstance(func, Function)): commentsNew[0] += r"$" + "\int \ " + "( " + func.__str__( ) + ")" + " d" + wrtVar + r"$" funcCopy = copy.deepcopy(func) if wrtVar in funcCopy.functionOf(): if not isinstance(funcCopy, Constant): for i, var in enumerate(funcCopy.value): log = False if var == wrtVar: if (funcCopy.power[i] == -1): log = True funcLog = Logarithm() funcLog.operand = Variable() funcLog.operand.coefficient = 1 funcLog.operand.value.append( funcCopy.value[i]) funcLog.operand.power.append(1) del funcCopy.power[i] del funcCopy.value[i] if funcCopy.value == []: funcCopy.__class__ = Constant funcCopy.value = funcCopy.coefficient funcCopy.coefficient = 1 funcCopy.power = 1 funcCopy = [funcCopy] funcJoin = Binary() funcJoin.value = '*' funcCopy.append(funcJoin) funcCopy.append(funcLog) else: funcCopy.power[i] += 1 funcCopy.coefficient /= funcCopy.power[i] if log: commentsNew[0] += r"$" + "= " + funcCopy[0].__str__( ) + "*" + funcCopy[2].__str__() + "\ ;\ " + r"$" newfunc.extend(funcCopy) else: commentsNew[0] += r"$" + "= " + funcCopy.__str__( ) + "\ ;\ " + r"$" newfunc.append(funcCopy) else: if isinstance(funcCopy, Variable): funcCopy.value.append(wrtVar) funcCopy.power.append(1) if isinstance(funcCopy, Constant): coeff = funcCopy.value funcCopy = Variable() funcCopy.coefficient = coeff funcCopy.value.append(wrtVar) funcCopy.power.append(1) newfunc.append(funcCopy) commentsNew[0] += r"$" + "= " + funcCopy.__str__( ) + "\ ;\ " + r"$" if func.operand is None: break else: func = func.operand if isinstance(func, Constant): intFunc = Zero() break intFunc.extend(newfunc) animNew.extend(intFunc) return intFunc, animNew, commentsNew
def divisionEquation(lToks, rToks, direct=False): """Function deals with division related operations FOR EQUATIONS (driver function in division module) Arguments: rtoks {list} -- list of right tokens ltoks {list} -- list of left tokens direct {bool} -- True when we are only concerned about multiplications terms in the input Returns: availableOperations {list} -- list of operations which can be performed on a equation token 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 """ lTokens = copy.deepcopy(lToks) rTokens = copy.deepcopy(rToks) animation = [] comments = [] if direct: comments = [[]] animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) animation.append(copy.deepcopy(animBuilder)) lVariables = [] lVariables.extend(getLevelVariables(lTokens)) rVariables = [] rVariables.extend(getLevelVariables(rTokens)) availableOperations = getOperationsExpression(lVariables, lTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(lVariables, lTokens) lTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) lVariables = getLevelVariables(lTokens) availableOperations = getOperationsExpression(lVariables, lTokens) availableOperations = getOperationsExpression(rVariables, rTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(rVariables, rTokens) rTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsExpression(rVariables, rTokens) tokenToStringBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' tokenToStringBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] tokenToStringBuilder.append(zero) else: tokenToStringBuilder.extend(rTokens) token_string = tokensToString(tokenToStringBuilder) lVariables = getLevelVariables(lTokens) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsEquation(lVariables, lTokens, rVariables, rTokens) return lTokens, rTokens, availableOperations, token_string, animation, comments
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