def test_substitute(): init_tok = getTokens("x") subs_tok = getTokens("2") tok_list = getTokens("3zx^2 + x^3 + 5x") assert tokensToString(substitute(init_tok, subs_tok, tok_list)) == "12.0z + 8.0 + 10.0" init_tok = getTokens("2x") subs_tok = getTokens("4yz^2") tok_list = getTokens("3 + 2x + zx^4 + 3xyz") assert tokensToString(substitute(init_tok, subs_tok, tok_list)) == "3.0 + 4.0yz^(2.0) + 16.0z^(9.0)y^(4.0) + 6.0y^(2.0)z^(3.0)" init_tok = getTokens("4x^2") subs_tok = getTokens("9yz") tok_list = getTokens("2x + zx^3 + 3xyz") assert tokensToString(substitute(init_tok, subs_tok, tok_list)) == "3.0y^(0.5)z^(0.5) + 3.375z^(2.5)y^(1.5) + 4.5y^(1.5)z^(1.5)" init_tok = getTokens("2xy^3") subs_tok = getTokens("4z") tok_list = getTokens("3 + 2xy^3 + z + 3x^(2)y^(6)z") assert tokensToString(substitute(init_tok, subs_tok, tok_list)) == "3.0 + 4.0z + z + 12.0z^(3.0)" init_tok = getTokens("5x") subs_tok = Expression(getTokens("y + 2")) tok_list = getTokens("3 + 4x + 2xy^3 + 3x^(2)y^(3)z") assert tokensToString(substitute(init_tok, subs_tok, tok_list)) == "3.0 + 0.8*(y + 2.0) + (0.4y^(3.0) * (y + 2.0)) + (0.12y^(3.0)z * (y + 2.0)^(2.0))"
def test_tokensToString(): # Matrix token to string mat = getTokens("[1+x, 2; \ 3 , 4]") assert tokensToString([mat]) == "[1.0 + x,2.0;3.0,4.0]" mat = getTokens("[1+x, 2] + [1, y + z^2]") assert tokensToString(mat) == "[1.0 + x,2.0] + [1.0,y + z^(2.0)]"
def convertMatrixToString(self, Latex=False): from visma.io.parser import tokensToString MatrixString = '' self.dim[0] = len(self.value) self.dim[1] = len(self.value[0]) for i in range(self.dim[0]): for j in range(self.dim[1]): if not Latex: MatrixString += tokensToString(self.value[i][j]) + '\t' else: MatrixString += tokensToString(self.value[i][j]) + ' ' MatrixString += '\n' return MatrixString
def test_traceMat(): mat = getTokens("[1, 2, 3; \ 3, 4, 7; \ 4, 6, 9]") mat.isSquare() trace = mat.traceMat() assert tokensToString(trace) == "14.0" mat = getTokens("[7, 5; \ 2, 0]") mat.isSquare() trace = mat.traceMat() assert tokensToString(trace) == "7.0"
def factorial(tokens): '''Used to get factorial of tokens provided Argument: tokens {list} -- list of tokens Returns: result {list} -- list of result 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 ''' tokens, _, _, _, _ = simplify(tokens) animation = [] comments = [] if (isinstance(tokens[0], Constant) & len(tokens) == 1): value = int(tokens[0].calculate()) if value == 0: result = [Constant(1)] comments += [['Factorial of ZERO is defined to be 1']] animation += [tokenizer('f = ' + str(1))] else: resultString = '' for i in range(1, value + 1): resultString += (str(i) + '*') resultString = resultString[:-1] resultTokens = tokenizer(resultString) comments += [['Expanding the factorial as']] animation += [resultTokens] result, _, _, _, _ = simplify(resultTokens) token_string = tokensToString(result) comments += [['Hence result: ']] animation += [tokenizer('f = ' + token_string)] return result, [], token_string, animation, comments
def division(tokens, direct=False): """Function deals with division related operations (driver function in division module) Arguments: tokens {list} -- list of 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 """ animation = [copy.deepcopy(tokens)] comments = [] if direct: comments = [[]] variables = [] variables.extend(getLevelVariables(tokens)) availableOperations = getOperationsExpression(variables, tokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(variables, tokens) tokens = removeToken(tok, rem) comments.append(com) animation.append(copy.deepcopy(tokens)) variables = getLevelVariables(tokens) availableOperations = getOperationsExpression(variables, tokens) token_string = tokensToString(tokens) return tokens, availableOperations, token_string, animation, comments
def solveFor(lTokens, rTokens, wrtVar): """Solve the input equation wrt to selected variable Arguments: lTokens {list} -- LHS tokens list rTokens {list} -- RHS tokens list wrtVar {string} -- variable to be solved Returns: lTokens {list} -- LHS tokens list rTokens {list} -- RHS tokens list availableOperations {list} -- list of operations token_string {string} -- final result in string animation {list} -- list of equation solving progress comments {list} -- list of solution steps """ lTokens, rTokens, availableOperations, token_string, animation, comments = simplifyEquation( lTokens, rTokens) lTokens, rTokens, animNew, commentsNew = solveTokens( lTokens, rTokens, wrtVar) tokenToStringBuilder = copy.deepcopy(lTokens) tokenToStringBuilder.append(EqualTo()) tokenToStringBuilder.extend(rTokens) token_string = tokensToString(tokenToStringBuilder) animation.extend(animNew) comments.extend(commentsNew) return lTokens, rTokens, availableOperations, token_string, animation, comments
def printOnCLI(equationTokens, operation, comments, solutionType): equationString = [] for x in equationTokens: equationString.append(tokensToString(x)) commentsString = [] for x in comments: for y in x: commentsString.append( [y.translate({ord(c): None for c in '${\}'})]) commentsString = [[]] + commentsString finalSteps = "" finalSteps = "INPUT: " + equationString[0] + "\n" finalSteps += "OPERATION: " + operation + "\n" finalSteps += "OUTPUT: " + equationString[-1] + "\n" for i, _ in enumerate(equationString): if comments[i] != []: finalSteps += "(" + str(commentsString[i][0]) + ")" + "\n" else: finalSteps += "\n" finalSteps += equationString[i] + 2 * "\n" if (mathError(equationTokens[-1])): finalSteps += 'Math Error: LHS not equal to RHS' + "\n" print(finalSteps)
def combination(nTokens, rTokens): '''Used to get Combination (nCr) Argument: nTokens {list} -- list of tokens of "n" in nCr rTokens {list} -- list of tokens of "r" in nCr Returns: result {list} -- list of result 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 ''' nTokens, _, _, _, _ = simplify(nTokens) rTokens, _, _, _, _ = simplify(rTokens) animation = [] comments = [] if (isinstance(nTokens[0], Constant) & len(nTokens) == 1) & (isinstance(rTokens[0], Constant) & len(rTokens) == 1): comments += [['nCr is defined as (n!)/(r!)*(n-r)!']] animation += [[]] comments += [['Solving for n!']] animation += [[]] numerator, _, _, animNew1, commentNew1 = factorial(nTokens) commentNew1[1] = ['(n)! is thus solved as: '] animation.extend(animNew1) comments.extend(commentNew1) denominator1 = nTokens[0] - rTokens[0] comments += [['Solving for (n - r)!']] animation += [[]] denominator1, _, _, animNew2, commentNew2 = factorial([denominator1]) commentNew2[1] = ['(n - r)! is thus solved as: '] comments.extend(commentNew2) animation.extend(animNew2) comments += [['Solving for r!']] animation += [[]] denominator2, _, _, animNew3, commentNew3 = factorial([rTokens[0]]) commentNew3[1] = ['r! is thus solved as: '] comments.extend(commentNew3) animation.extend(animNew3) denominator = denominator1[0] * denominator2[0] result = [numerator[0] / denominator] comments += [['On placing values in (n!)/(r!)*(n-r)!']] animation += [tokenizer('r = ' + tokensToString(result))] token_string = tokensToString(result) return result, [], token_string, animation, comments
def integrationByParts(tokens, wrtVar): if (isinstance(tokens[1], Binary) and tokens[1].value == '*'): u = tokens[0] v = tokens[2] vIntegral, _, _, _, _ = integrate(v, wrtVar) uDerivative, _, _, _, _ = differentiate(u, wrtVar) term1 = u * vIntegral term2, _, _, _, _ = integrate(uDerivative * vIntegral, 'x') resultToken = term1 - term2 token_string = tokensToString(resultToken) return resultToken, [], token_string, [], []
def factorize(tokens): tokens, availableOperations, token_string, animation, comments = simplify( tokens) tokens, animNew, commentsNew = (factorizeTokens(tokens)) animation.extend(animNew) comments.append(commentsNew) token_string = tokensToString(tokens) return tokens, availableOperations, token_string, animation, comments
def simplifification(tokens): """Simplifies given expression tokens Arguments: tokens {list} -- tokens list Returns: tokens {list} -- 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 """ tokens_orig = copy.deepcopy(tokens) animation = [tokens_orig] variables = [] comments = [] variables.extend(getLevelVariables(tokens)) availableOperations = getOperationsExpression(variables, tokens) while len(availableOperations) > 0: if '/' in availableOperations: tokens_temp = copy.deepcopy(tokens) tokens, availableOperations, token_string, anim, com = division( tokens_temp) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '*' in availableOperations: tokens_temp = copy.deepcopy(tokens) tokens, availableOperations, token_string, anim, com = multiplication( tokens_temp) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '+' in availableOperations: tokens_temp = copy.deepcopy(tokens) tokens, availableOperations, token_string, anim, com = addition( tokens_temp) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '-' in availableOperations: tokens_temp = copy.deepcopy(tokens) tokens, availableOperations, token_string, anim, com = subtraction( tokens_temp) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) tokens, animation = postSimplification(tokens, animation) token_string = tokensToString(tokens) return tokens, availableOperations, token_string, animation, comments
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 division(tokens, direct=False): animation = [copy.deepcopy(tokens)] comments = [] if direct: comments = [[]] variables = [] variables.extend(getLevelVariables(tokens)) availableOperations = getOperationsExpression(variables, tokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(variables, tokens) tokens = removeToken(tok, rem) comments.append(com) animation.append(copy.deepcopy(tokens)) variables = getLevelVariables(tokens) availableOperations = getOperationsExpression(variables, tokens) token_string = tokensToString(tokens) return tokens, availableOperations, token_string, animation, comments
def multiplication(tokens, direct=False): # FIXME: Fix multiplication for variables (Ex: x^-1 * x^2) animation = [copy.deepcopy(tokens)] comments = [] if direct: comments = [[]] variables = [] variables.extend(getLevelVariables(tokens)) availableOperations = getOperationsExpression(variables, tokens) while '*' in availableOperations: _, tok, rem, com = expressionMultiplication(variables, tokens) tokens = removeToken(tok, rem) comments.append(com) animation.append(copy.deepcopy(tokens)) variables = getLevelVariables(tokens) availableOperations = getOperationsExpression(variables, tokens) token_string = tokensToString(tokens) return tokens, availableOperations, token_string, animation, comments
def ArithemeticMean(sampleSpace): """Implements arithemetic mean Arguments: sampleSpace -- {visma.discreteMaths.statistics.ArithemeticMean} Returns: 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 """ animations = [] comments = [] if sampleSpace.values is not []: sm = sum(sampleSpace.values) animations += [[]] comments += [[ 'Sum of all the values of the sample space provided by user: '******'' for val in sampleSpace.values: summationString += str(val) + '+' summationString = summationString[:-1] summationTokens = tokenizer(summationString) resultTokens, _, _, _, _ = simplify(summationTokens) if len(resultTokens) == 1 and isinstance(resultTokens[0], Constant): ArithemeticMean = resultTokens[0] / Constant( len(sampleSpace.values)) animations += [[]] comments += [[ 'Considering ' + str(len(sampleSpace.values)) + ' values.' ]] animations += [[tokenizer('mean = ' + str(ArithemeticMean.calculate))]] token_string = tokensToString([ArithemeticMean]) return token_string, animations, comments else: return '', [], []
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
def expressionSimplification(tokens_now, scope, tokens1): '''Makes an input equation free from Expressions, i.e. solving each Expression recursively to convert them in other tokens. Arguments: tokens_now {list} -- list of original tokens as function gets called recursively scope {list} -- integers (bounds) indicating which Expression we are currently solving tokens1 {list} -- list of current tokens as function gets called recursively Returns: simToks {list} -- list of simplified tokens of each Expression 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 ''' animation = [] comments = [] pfTokens = [] i = 0 while (i < len(tokens1)): if (i + 1 < len(tokens1)): if isinstance(tokens1[i], Binary) and tokens1[i].value == '^': if isinstance(tokens1[i - 1], Expression): tokens1[i - 1].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i - 1].tokens) if isinstance(tokens1[i + 1], Expression): tokens1[i + 1].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i + 1].tokens) if len(tokens1[i + 1].tokens) == 1 and isinstance( tokens1[i + 1].tokens[0], Constant): tokens1[i + 1] = Constant( tokens1[i + 1].tokens[0].calculate(), 1, 1) if (isinstance(tokens1[i], Binary) and tokens1[i].value == '^') and isinstance( tokens1[i + 1], Constant): if float(tokens1[i + 1].calculate()).is_integer(): rep = int(tokens1[i + 1].calculate()) for _ in range(rep - 1): pfTokens.extend([Binary('*'), tokens1[i - 1]]) i += 1 else: pfTokens.append(tokens1[i]) else: pfTokens.append(tokens1[i]) else: pfTokens.append(tokens1[i]) i += 1 tokens1 = copy.deepcopy(pfTokens) animation.append(pfTokens) comments.append(['Expanding the powers of expressions']) mulFlag = True expressionMultiplication = False # Check for the case: {Non-Expression} * {Expression} for _ in range(50): for i, _ in enumerate(tokens1): mulFlag = False if isinstance(tokens1[i], Expression): if (i > 1): if (tokens1[i - 1].value == '*'): scope.append(i) tokens1[ i].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i].tokens) if isinstance(tokens1[i - 2], Expression): scope.append(i - 2) tokens1[ i - 2].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i - 2].tokens) a = tokens1[i - 2] b = tokens1[i] c = a * b mulFlag = True expressionMultiplication = True if isinstance(c, Expression): scope.append(i) c.tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, c.tokens) tokens1[i] = c del tokens1[i - 1] del tokens1[i - 2] break trigonometricError = False # Check for the case: {Expression} * {Non-Expression} if not trigonometricError: for _ in range(50): for i, _ in enumerate(tokens1): mulFlag = False if isinstance(tokens1[i], Expression): if i + 2 < len(tokens1): if (tokens1[i + 1].value == '*'): scope.append(i) tokens1[ i].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i].tokens) if isinstance(tokens1[i + 2], Expression): scope.append(i + 2) tokens1[ i + 2].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i + 2].tokens) a = tokens1[i + 2] b = tokens1[i] trigonometricError = False for ec in b.tokens: if isinstance(ec, Trigonometric): trigonometricError = True break if not trigonometricError: c = a * b mulFlag = True expressionMultiplication = True if isinstance(c, Expression): scope.append(i) c.tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, c.tokens) tokens1[i] = c del tokens1[i + 1] del tokens1[i + 1] break if not mulFlag: break if expressionMultiplication: animation.append(tokens1) comments.append(['Multiplying expressions']) # TODO: Implement verbose multiplication steps. simToks = [] expressionPresent = False for i, _ in enumerate(tokens1): if isinstance(tokens1[i], Expression): expressionPresent = True scope.append(i) newToks, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i].tokens) if not simToks: simToks.extend(newToks) elif (simToks[len(simToks) - 1].value == '+'): if isinstance(newToks[0], Constant): if (newToks[0].value < 0): simToks.pop() simToks.extend(newToks) elif (simToks[len(simToks) - 1].value == '-'): for _, x in enumerate(newToks): if x.value == '+': x.value = '-' elif x.value == '-': x.value = '+' if (isinstance(newToks[0], Constant)): if (newToks[0].value < 0): simToks[-1].value = '+' newToks[0].value = abs(newToks[0].value) elif (isinstance(newToks[0], Variable)): if (newToks[0].coefficient < 0): simToks[-1].value = '+' newToks[0].coefficient = abs(newToks[0].coefficient) simToks.extend(newToks) else: simToks.extend([tokens1[i]]) simToks = tokenizer(tokensToString(simToks)) if expressionPresent: animation += [simToks] comments += [['Opening up all the brackets']] # TODO: Implement Trigonometric functions in the simplify module. trigonometricError = False for tk in simToks: if isinstance(tk, Trigonometric): trigonometricError = True break if not trigonometricError: if scope == []: simToks, availableOperations, token_string, animExtra, commentExtra = simplifification( simToks) animExtra.pop(0) animation += animExtra comments += commentExtra else: availableOperations = '' token_string = '' else: availableOperations = [] token_string = tokensToString(simToks) # TODO: Implement verbose steps in simplification of Expressions (steps shown can be varied depending on length of expression) if scope != []: scope.pop() return simToks, availableOperations, token_string, animation, comments
def inverse(self): """Calculates the inverse of the matrix using Gauss-Jordan Elimination Arguments: matrix {visma.matrix.structure.Matrix} -- matrix token Returns: inv {visma.matrix.structure.Matrix} -- result matrix token """ from visma.simplify.simplify import simplify from visma.io.tokenize import tokenizer from visma.io.parser import tokensToString if tokensToString(self.determinant()) == "0": return -1 self.dim[0] = len(self.value) self.dim[1] = len(self.value[0]) n = self.dim[0] mat = Matrix() mat.empty([n, 2 * n]) for i in range(0, n): for j in range(0, 2 * n): if j < n: mat.value[i][j] = self.value[i][j] else: mat.value[i][j] = [] for i in range(0, n): for j in range(n, 2 * n): if j == (i + n): mat.value[i][j].extend(tokenizer('1')) else: mat.value[i][j].extend(tokenizer("0")) for i in range(n - 1, 0, -1): if mat.value[i - 1][0][0].value < mat.value[i][0][0].value: for j in range(0, 2 * n): temp = mat.value[i][j] mat.value[i][j] = mat.value[i - 1][j] mat.value[i - 1][j] = temp for i in range(0, n): for j in range(0, n): if j != i: temp = [] if len(mat.value[j][i]) != 1: temp.append(Expression(mat.value[j][i])) else: temp.extend(mat.value[j][i]) temp.append(Binary('/')) if len(mat.value[i][i]) != 1: temp.append(Expression(mat.value[i][i])) else: temp.extend(mat.value[i][i]) temp, _, _, _, _ = simplify(temp) for k in range(0, 2 * n): t = [] if mat.value[i][k][0].value != 0: if len(mat.value[i][k]) != 1: t.append(Expression(mat.value[i][k])) else: t.extend(mat.value[i][k]) t.append(Binary('*')) if len(temp) != 1: t.append(Expression(temp)) else: t.extend(temp) t, _, _, _, _ = simplify(t) mat.value[j][k].append(Binary('-')) if len(t) != 1: mat.value[j][k].append(Expression(t)) else: mat.value[j][k].extend(t) mat.value[j][k], _, _, _, _ = simplify( mat.value[j][k]) for i in range(0, n): temp = [] temp.extend(mat.value[i][i]) for j in range(0, 2 * n): if mat.value[i][j][0].value != 0: mat.value[i][j].append(Binary('/')) mat.value[i][j].extend(temp) mat.value[i][j], _, _, _, _ = simplify(mat.value[i][j]) inv = SquareMat() inv.empty([n, n]) for i in range(0, n): for j in range(n, 2 * n): inv.value[i][j - n] = mat.value[i][j] return inv
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 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 test_Variable(): variable1 = Variable(2, 'x', 3) assert variable1.__str__() == "2{x}^{3}" variable1, _ = variable1.integrate('x') assert variable1.__str__() == "0.5{x}^{4}" constant = Constant(3) variable = Variable(2, 'x', 3) add = variable + constant assert add.__str__() == "{(2{x}^{3}+{3})}" variable1 = Variable(2, 'x', 3) variable2 = Variable(4, 'x', 3) add1 = variable1 + variable2 assert add1.__str__() == "6{x}^{3}" variable1 = Variable(2, 'x', 3) constant = Constant(3) exp1 = Expression([variable1, Plus(), constant]) variable2 = Variable(4, 'x', 3) add2 = variable2 + exp1 assert add2.__str__() == "{(6{x}^{3}+{3})}" variable1 = Variable(2, 'x', 3) constant = Constant(3) exp1 = variable1 + constant variable2 = Variable(4, 'x', 3) add2 = variable2 - exp1 assert add2.__str__() == "{(2{x}^{3}-{3})}" variable1 = Variable(2, 'x', 3) constant = Constant(3) exp1 = Expression([variable1, Plus(), constant]) variable2 = Variable(4, 'x', 3) add2 = exp1 - variable2 assert add2.__str__() == "{(-2{x}^{3}+{3})}" constant = Constant(3) variable = Variable(2, 'x', 3) add = variable - constant assert add.__str__() == "{(2{x}^{3}-{3})}" variable1 = Variable(2, 'x', 3) variable2 = Variable(4, 'x', 3) variable3 = Variable(2, 'x', 4) variable4 = Variable(2, 'x', 3) add1 = variable1 - variable2 add2 = variable3 - variable4 assert add1.__str__() == "-2{x}^{3}" assert add2.__str__() == "{(2{x}^{4}-2{x}^{3})}" constant = Constant(3) variable = Variable(2, 'x', 3) add = variable * constant assert add.__str__() == "6{x}^{3}" variable1 = Variable(2, 'x', 3) variable2 = Variable(4, 'x', 3) add2 = variable1 * variable2 assert add2.__str__() == "8{x}^{6}" variable1 = Variable(2, 'x', 3) variable2 = Variable(4, 'y', 3) add2 = variable1 * variable2 assert add2.__str__() == "8{x}^{3}{y}^{3}" variable1 = Variable(2, 'x', 3) variable2 = Variable(4, 'y', 4) add1 = variable1 / variable2 assert add1.__str__() == "0.5{x}^{3}{y}^{-4}" variable1 = Variable(2, 'x', 3) constant = Constant(3) exp1 = variable1 - constant variable2 = Variable(4, 'x', 3) add2 = variable2 / exp1 assert add2.__str__() == "{(4.0{x}^{3}*{(2{x}^{3}-{3})}^{-1})}" variable1 = Variable(2, 'x', 3) constant = Constant(3) exp1 = variable1 - constant variable2 = Variable(4, 'x', 3) add2 = variable2 * exp1 assert add2.__str__() == "{(8{x}^{6}-12{x}^{3})}" variable1 = Variable(2, 'x', 3) constant1 = Constant(3) exp1 = variable1 - constant1 variable2 = Variable(4, 'x', 3) constant2 = Constant(4) exp2 = variable2 - constant2 add2 = exp1 * exp2 assert add2.__str__() == "{({(8{x}^{6}-8{x}^{3})}-{(12{x}^{3}-{12})})}" variable2 = Variable(3, 'x', -1) variable2, _ = variable2.integrate('x') assert tokensToString(variable2) == '3 * log(x)'
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