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 logicalAND(token1, token2): """Implements Bitwise AND Arguments: token1 -- {list} -- List of tokens of a constant number token2 -- {list} -- List of tokens of a constant number 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 """ comments = [] animations = [] token1, _, _, _, _ = simplify(token1) token2, _, _, _, _ = simplify(token2) if isinstance(token1, Constant) and isinstance(token2, Constant): comments += [['Converting numbers to Binary Illustrations: ']] animations += [[]] binaryValue1 = token1.binary() binaryValue2 = token2.binary() comments += [[]] animations += [[tokenizer('a = ' + str(binaryValue1))]] comments += [[]] animations += [[tokenizer('b = ' + str(binaryValue2))]] comments += [['Doing AND operation for each of the consecutive bit']] animations += [[]] resultValue = token1.calculate() & token2.calculate() comments += [['Final result is']] animations += [[tokenizer('r = ' + str(resultValue))]] token_string = 'r = ' + str(resultValue) return token_string, animations, comments else: return '', [], []
def differentiate(tokens, wrtVar): """Simplifies and then differentiates given tokens wrt given variable Arguments: tokens {list} -- list of function tokens wrtVar {string} -- with respect to variable Returns: tokens {list} -- list of differentiated tokens availableOperations {list} -- list of operations token_string {string} -- output equation string animation {list} -- equation tokens for step-by-step comments {list} -- comments for step-by-step """ animation = [] comments = [] tokens, availableOperations, token_string, animation, comments = simplify(tokens) tokens, animNew, commentsNew = differentiateTokens(tokens, wrtVar) animation.append(animNew) comments.append(commentsNew) tokens, availableOperations, token_string, animation2, comments2 = simplify(tokens) animation2.pop(0) comments2.pop(0) animation.extend(animation2) comments.extend(comments2) return tokens, availableOperations, token_string, animation, comments
def gauss_elim(mat): """ Returns calculated values of unknown variables Arguments: mat {visma.matrix.structure.Matrix} -- matrix token Returns: result {visma.matrix.structure.Matrix} -- result matrix token Note: result is a Nx1 matrix """ echelon = Matrix() echelon = row_echelon(mat) result = Matrix() result.empty([mat.dim[0], 1]) N = mat.dim[0] M = mat.dim[1] index = N - 1 for i in range(N - 1, -1, -1): sum_ = [] temp = [] if echelon.value[i][i][ 0].value == 0.0: # no unique solution for this case return -1 for j in range(i + 1, M - 1): temp = [] temp.extend(echelon.value[i][j]) temp.append(Binary('*')) temp.extend(result.value[j][0]) temp, _, _, _, _ = simplify(temp) sum_.extend(temp) if j != M - 2: sum_.append(Binary('+')) sum_, _, _, _, _ = simplify(sum_) result.value[index][0].extend(echelon.value[i][M - 1]) if sum_: if sum_[0].value < 0: result.value[index][0].append( Binary('-') ) # negative sign makes the negative sign in value positive else: result.value[index][0].append(Binary('-')) result.value[index][0].extend(sum_) result.value[index][0], _, _, _, _ = simplify(result.value[index][0]) result.value[index][0].append(Binary('/')) result.value[index][0].extend(echelon.value[i][i]) result.value[index][0], _, _, _, _ = simplify(result.value[index][0]) index -= 1 return result
def moveToRHS(lTokens, rTokens, wrtVar): """Moves all variables which are not equal to wrtVar to RHS 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 animation {list} -- list of equation solving progress comments {list} -- list of solution steps """ comment = "Moving " i = 0 while i < len(lTokens): if isinstance(lTokens[i], Function) and not isVarInToken(lTokens[i], wrtVar): if i - 1 >= 0 and isinstance(lTokens[i - 1], Operator): comment += r"$" + lTokens[i - 1].__str__() + r"$" if lTokens[i - 1].value == '-': lTokens[i - 1].value = '+' rTokens.append(lTokens.pop(i - 1)) elif lTokens[i - 1].value == '+': lTokens[i - 1].value = '-' rTokens.append(lTokens.pop(i - 1)) i -= 1 elif i == 0: rTokens.append(Minus()) comment += r"$" + lTokens[i].__str__() + r"$" rTokens.append(lTokens.pop(i)) i -= 1 i += 1 comment += " to RHS" if isinstance(lTokens[0], Operator): if lTokens[0].value == '+': lTokens.pop(0) elif lTokens[0].value == '-': lTokens.pop(0) lTokens[0].coefficient *= -1 lTokens, _, _, _, _ = simplify(lTokens) rTokens, _, _, _, _ = simplify(rTokens) animation = copy.deepcopy(lTokens) animation.append(EqualTo()) animation.extend(rTokens) return lTokens, rTokens, animation, [comment]
def logicalNOT(token1): """Implements Bitwise NOT Arguments: token1 -- {list} -- List of tokens of a constant number 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 """ comments = [] animations = [] token1, _, _, _, _ = simplify(token1) if isinstance(token1, Constant): comments += [['Converting numbers to Binary Illustrations: ']] animations += [[]] binaryValue1 = token1.binary() comments += [[]] animations += [[tokenizer('a = ' + str(binaryValue1))]] resultValueBinary = bin((1 << 8) - 1 - int(binaryValue1, 2)) resultValue = int(resultValueBinary, 2) comments += [['Final binary is']] animations += [[tokenizer('r = ' + str(resultValueBinary))]] comments += [['Final result is']] animations += [[tokenizer('r = ' + str(resultValue))]] token_string = 'r = ' + str(resultValue) return token_string, animations, comments else: return '', [], []
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 row_echelon(mat): """ Returns the row echelon form of the given matrix Arguments: mat {visma.matrix.structure.Matrix} -- matrix token Returns: row_echelon {visma.matrix.structure.Matrix} -- result matrix token """ N = mat.dim[0] M = mat.dim[1] for k in range(0, N): if abs(mat.value[k][k][0].value) == 0.0: if k == N - 1: return simplifyMatrix(mat) else: for i in range(0, N): t = mat.value[k][i] mat.value[k][i] = mat.value[k + 1][i] mat.value[k + 1][i] = t else: for i in range(k + 1, N): temp = [] temp.extend(mat.value[i][k]) temp.append(Binary('/')) temp.extend(mat.value[k][k]) temp, _, _, _, _ = simplify(temp) for j in range(k + 1, M): temp2 = [] temp2.extend(mat.value[k][j]) temp2.append(Binary('*')) temp2.extend(temp) temp2, _, _, _, _ = simplify(temp2) mat.value[i][j].append(Binary('-')) mat.value[i][j].extend(temp2) mat.value[i][k].append(Binary('*')) mat.value[i][k].append(Constant(0)) mat = simplifyMatrix(mat) return simplifyMatrix(mat)
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 quickSimplify(workspace): """Dynamic simplifier for simplifying expression as it is being typed Arguments: workspace {QtWidgets.QWidget} -- main layout Returns: qSolution/log {string} -- quick solution or error log enableInteraction {bool} -- if False disables 'visma'(interaction) button """ # FIXME: Crashes for some cases. Find and fix. logger.setLogName('qsolver') logger.setLevel(0) qSolution = "" strIn = workspace.textedit.toPlainText() cleanInput = removeSpaces(strIn) if ';' in cleanInput: return "", True, True terms = getTerms(cleanInput) normalizedTerms = normalize(terms) symTokens = tokenizeSymbols(normalizedTerms) normalizedTerms, symTokens = removeUnary(normalizedTerms, symTokens) if checkEquation(normalizedTerms, symTokens) is True and strIn != "": if symTokens and symTokens[-1] is not False: tokens = getToken(normalizedTerms, symTokens) tokens = tokens.tokens lhs, rhs = getLHSandRHS(tokens) _, solutionType = checkTypes(lhs, rhs) lhs, rhs = getLHSandRHS(tokens) if solutionType == 'expression': _, _, _, equationTokens, _ = simplify(tokens) qSolution = r'$ ' + '= \ ' else: _, _, _, _, equationTokens, _ = simplifyEquation(lhs, rhs) qSolution = r'$ ' + '\Rightarrow \ ' qSolution += tokensToLatex(equationTokens[-1]) + ' $' # workspace.eqToks = equationTokens # plot(workspace) return qSolution, True, False elif symTokens: log = "Invalid Expression" workspace.logBox.append(logger.error(log)) return log, False, _ else: log = "" workspace.logBox.append(logger.error(log)) return log, False, _ else: log = "" if strIn != "": _, log = checkEquation(normalizedTerms, symTokens) workspace.logBox.append(logger.error(log)) return log, False, _
def simplifyMatrix(mat): """Simplifies each element in the matrix Arguments: mat {visma.matrix.structure.Matrix} -- matrix token Returns: mat {visma.matrix.structure.Matrix} -- simplified matrix token """ for i in range(mat.dim[0]): for j in range(mat.dim[1]): mat.value[i][j], _, _, _, _ = simplify(mat.value[i][j]) return mat
def traceMat(self): """Returns the trace of a square matrix (sum of diagonal elements) Arguments: mat {visma.matrix.structure.Matrix} -- matrix token Returns: trace {visma.matrix.structure.Matrix} -- string token """ from visma.simplify.simplify import simplify trace = [] for i in range(self.dim[0]): trace.extend(self.value[i][i]) trace.append(Binary('+')) trace.append(Constant(0)) trace, _, _, _, _ = simplify(trace) return trace
def determinant(self, mat=None): """Calculates square matrices' determinant Returns: list of tokens forming the determinant """ from visma.simplify.simplify import simplify if mat is None: self.dimension() mat = np.array(self.value) if (mat.shape[0] > 2): ans = [] for i in range(mat.shape[0]): mat1 = SquareMat() mat1.value = np.concatenate((mat[1:, :i], mat[1:, i + 1:]), axis=1).tolist() a, _, _, _, _ = simplify(mat1.determinant()) if (a[0].value != 0 and a != []): a, _, _, _, _ = simplify(a + [Multiply()] + mat[0][i].tolist()) if (i % 2 == 0): if (ans != []): ans, _, _, _, _ = simplify(ans + [Plus()] + a) else: ans = a else: ans, _, _, _, _ = simplify(ans + [Minus()] + a) elif (mat.shape[0] == 2): a = Multiply() b = Minus() mat = mat.tolist() a1, _, _, _, _ = simplify(mat[0][0] + [a] + mat[1][1]) a2, _, _, _, _ = simplify(mat[0][1] + [a] + mat[1][0]) ans, _, _, _, _ = simplify([a1[0], b, a2[0]]) if (isinstance(ans[0], Minus) or isinstance( ans[0], Plus)) and ans[0].value not in ['+', '-']: ans[0] = Constant(ans[0].value) else: ans, _, _, _, _ = simplify(mat[0][0]) if not ans: ans = Zero() return ans
def quickSimplify(workspace): """Dynamic simplifier for simplifying expression as it is being typed Arguments: workspace {QtWidgets.QWidget} -- main layout Returns: qSolution/log {string} -- quick solution or error log """ # FIXME: Crashes for some cases. Find and fix. qSolution = "" input = workspace.textedit.toPlainText() cleanInput = removeSpaces(input) terms = getTerms(cleanInput) normalizedTerms = normalize(terms) symTokens = tokenizeSymbols(normalizedTerms) terms, symTokens = removeUnary(normalizedTerms, symTokens) if checkEquation(normalizedTerms, symTokens) is True and input != "": if symTokens[-1] is not False: tokens = getToken(normalizedTerms, symTokens) tokens = tokens.tokens lhs, rhs = getLHSandRHS(tokens) _, solutionType = checkTypes(lhs, rhs) if solutionType == 'expression': _, _, _, equationTokens, _ = simplify(tokens) qSolution = r'$ ' + '= \ ' else: _, _, _, _, equationTokens, _ = simplifyEquation(lhs, rhs) qSolution = r'$ ' + '\Rightarrow \ ' qSolution += tokensToLatex(equationTokens[-1]) + ' $' # workspace.eqToks = equationTokens # plot(workspace) return qSolution else: log = "Invalid Expression" return log else: log = "" if input != "": _, log = checkEquation(normalizedTerms, symTokens) return log
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 commandExec(command): operation = command.split('(', 1)[0] inputEquation = command.split('(', 1)[1][:-1] matrix = False # True when matrices operations are present in the code. if operation[0:4] == 'mat_': matrix = True if not matrix: """ This part handles the cases when VisMa is NOT dealing with matrices. Boolean flags used in code below: simul -- {True} when VisMa is dealing with simultaneous equations & {False} in all other cases """ varName = None if ',' in inputEquation: varName = inputEquation.split(',')[1] varName = "".join(varName.split()) inputEquation = inputEquation.split(',')[0] simul = False # True when simultaneous equation is present if (inputEquation.count(';') == 2) and (operation == 'solve'): simul = True afterSplit = inputEquation.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] eqStr3 = afterSplit[2] lhs = [] rhs = [] solutionType = '' lTokens = [] rTokens = [] equationTokens = [] comments = [] if simul: tokens = [tokenizer(eqStr1), tokenizer(eqStr2), tokenizer(eqStr3)] else: tokens = tokenizer(inputEquation) if '=' in inputEquation: lhs, rhs = getLHSandRHS(tokens) lTokens = lhs rTokens = rhs _, solutionType = checkTypes(lhs, rhs) else: solutionType = 'expression' lhs, rhs = getLHSandRHS(tokens) lTokens = lhs rTokens = rhs if operation == 'plot': app = QApplication(sys.argv) App(tokens) sys.exit(app.exec_()) elif operation == 'simplify': if solutionType == 'expression': tokens, _, _, equationTokens, comments = simplify(tokens) else: lTokens, rTokens, _, _, equationTokens, comments = simplifyEquation( lTokens, rTokens) elif operation == 'addition': if solutionType == 'expression': tokens, _, _, equationTokens, comments = addition(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = additionEquation( lTokens, rTokens, True) elif operation == 'subtraction': if solutionType == 'expression': tokens, _, _, equationTokens, comments = subtraction( tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = subtractionEquation( lTokens, rTokens, True) elif operation == 'multiplication': if solutionType == 'expression': tokens, _, _, equationTokens, comments = multiplication( tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = multiplicationEquation( lTokens, rTokens, True) elif operation == 'division': if solutionType == 'expression': tokens, _, _, equationTokens, comments = division(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = divisionEquation( lTokens, rTokens, True) elif operation == 'factorize': tokens, _, _, equationTokens, comments = factorize(tokens) elif operation == 'find-roots': lTokens, rTokens, _, _, equationTokens, comments = rootFinder( lTokens, rTokens) elif operation == 'solve': if simul: if varName is not None: _, equationTokens, comments = simulSolver( tokens[0], tokens[1], tokens[2], varName) else: _, equationTokens, comments = simulSolver( tokens[0], tokens[1], tokens[2]) solutionType = equationTokens else: lhs, rhs = getLHSandRHS(tokens) lTokens, rTokens, _, _, equationTokens, comments = solveFor( lTokens, rTokens, varName) elif operation == 'factorial': tokens, _, _, equationTokens, comments = factorial(tokens) elif operation == 'combination': n = tokenizer(inputEquation) r = tokenizer(varName) tokens, _, _, equationTokens, comments = combination(n, r) elif operation == 'permutation': n = tokenizer(inputEquation) r = tokenizer(varName) tokens, _, _, equationTokens, comments = permutation(n, r) elif operation == 'integrate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = integrate( lTokens, varName) elif operation == 'differentiate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = differentiate( lTokens, varName) if operation != 'plot': # FIXME: when either plotting window or GUI window is opened from CLI and after it is closed entire CLI exits, it would be better if it is avoided final_string = resultStringCLI(equationTokens, operation, comments, solutionType, simul) print(final_string) else: """ This part handles the cases when VisMa is dealing with matrices. Boolean flags used in code below: dualOperand -- {True} when the matrix operations require two operands (used in operations like addition, subtraction etc) nonMatrixResult -- {True} when the result after performing operations on the Matrix is not a Matrix (in operations like Determinant, Trace etc.) scalarOperations -- {True} when one of the operand in a scalar (used in operations like Scalar Addition, Scalar Subtraction etc.) """ operation = operation[4:] dualOperand = False nonMatrixResult = False scalarOperations = False if ', ' in inputEquation: dualOperand = True [inputEquation1, inputEquation2] = inputEquation.split(', ') if '[' in inputEquation1: inputEquation1 = inputEquation1[1:][:-1] inputEquation1 = inputEquation1.split('; ') matrixOperand1 = [] for row in inputEquation1: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand1.append(row1) Matrix1 = Matrix() Matrix1.value = matrixOperand1 inputEquation2 = inputEquation2[1:][:-1] inputEquation2 = inputEquation2.split('; ') matrixOperand2 = [] for row in inputEquation2: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand2.append(row1) Matrix2 = Matrix() Matrix2.value = matrixOperand2 Matrix1_copy = copy.deepcopy(Matrix1) Matrix2_copy = copy.deepcopy(Matrix2) else: scalarOperations = True scalar = inputEquation1 scalarTokens = scalar # scalarTokens = tokenizer(scalar) inputEquation2 = inputEquation2[1:][:-1] inputEquation2 = inputEquation2.split('; ') matrixOperand2 = [] for row in inputEquation2: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand2.append(row1) Matrix2 = Matrix() Matrix2.value = matrixOperand2 scalarTokens_copy = copy.deepcopy(scalarTokens) Matrix2_copy = copy.deepcopy(Matrix2) else: inputEquation = inputEquation[1:][:-1] inputEquation = inputEquation.split('; ') matrixOperand = [] for row in inputEquation: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand.append(row1) Matrix0 = Matrix() Matrix0.value = matrixOperand Matrix0_copy = copy.deepcopy(Matrix0) if operation == 'simplify': MatrixResult = simplifyMatrix(Matrix0) elif operation == 'add': MatrixResult = addMatrix(Matrix1, Matrix2) elif operation == 'sub': MatrixResult = subMatrix(Matrix1, Matrix2) elif operation == 'mult': MatrixResult = multiplyMatrix(Matrix1, Matrix2) elif operation == 'determinant': nonMatrixResult = True sqMatrix = SquareMat() sqMatrix.value = Matrix0.value result = sqMatrix.determinant() elif operation == 'trace': nonMatrixResult = True sqMatrix = SquareMat() sqMatrix.value = Matrix0.value result = sqMatrix.traceMat() elif operation == 'inverse': sqMatrix = SquareMat() sqMatrix.value = Matrix0.value MatrixResult = SquareMat() MatrixResult = sqMatrix.inverse() finalCLIstring = '' if dualOperand: if not scalarOperations: finalCLIstring = resultMatrixString(operation=operation, operand1=Matrix1_copy, operand2=Matrix2_copy, result=MatrixResult) else: finalCLIstring = resultMatrixString(operation=operation, operand1=scalarTokens_copy, operand2=Matrix2_copy, result=MatrixResult) else: if nonMatrixResult: finalCLIstring = resultMatrixString(operation=operation, operand1=Matrix0_copy, nonMatrixResult=True, result=result) else: finalCLIstring = resultMatrixString(operation=operation, operand1=Matrix0_copy, result=MatrixResult) print(finalCLIstring)
def calluser(): availableOperations = [] tokenString = '' equationTokens = [] self.resultOut = True if name == 'addition': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = addition( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = additionEquation( self.lTokens, self.rTokens, True) elif name == 'subtraction': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = subtraction( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = subtractionEquation( self.lTokens, self.rTokens, True) elif name == 'multiplication': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = multiplication( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = multiplicationEquation( self.lTokens, self.rTokens, True) elif name == 'division': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = division( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = divisionEquation( self.lTokens, self.rTokens, True) elif name == 'simplify': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = simplify( self.tokens) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = simplifyEquation( self.lTokens, self.rTokens) elif name == 'factorize': self.tokens, availableOperations, tokenString, equationTokens, comments = factorize( self.tokens) elif name == 'find roots': self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = quadraticRoots( self.lTokens, self.rTokens) elif name == 'solve': lhs, rhs = getLHSandRHS(self.tokens) variables = getVariables(lhs, rhs) self.wrtVariableButtons(variables, name) self.resultOut = False elif name == 'integrate': lhs, rhs = getLHSandRHS(self.tokens) variables = getVariables(lhs, rhs) self.wrtVariableButtons(variables, name) self.resultOut = False elif name == 'differentiate': lhs, rhs = getLHSandRHS(self.tokens) variables = getVariables(lhs, rhs) self.wrtVariableButtons(variables, name) self.resultOut = False if self.resultOut: self.eqToks = equationTokens self.output = resultLatex(name, equationTokens, comments) if len(availableOperations) == 0: self.clearButtons() else: self.refreshButtons(availableOperations) if self.mode == 'normal': self.textedit.setText(tokenString) elif self.mode == 'interaction': cursor = self.textedit.textCursor() cursor.insertText(tokenString) if self.showStepByStep is True: showSteps(self) if self.showPlotter is True: plot(self)
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 commandExec(command): operation = command.split('(', 1)[0] inputEquation = command.split('(', 1)[1][:-1] if ',' in inputEquation: varName = inputEquation.split(',')[1] inputEquation = inputEquation.split(',')[0] lhs = [] rhs = [] solutionType = '' lTokens = [] rTokens = [] equationTokens = [] comments = [] tokens = tokenizer(inputEquation) lhs, rhs = getLHSandRHS(tokens) lTokens = lhs rTokens = rhs _, solutionType = checkTypes(lhs, rhs) if operation == 'simplify': if solutionType == 'expression': tokens, _, _, equationTokens, comments = simplify(tokens) else: lTokens, rTokens, _, _, equationTokens, comments = simplifyEquation( lTokens, rTokens) elif operation == 'addition': if solutionType == 'expression': tokens, _, _, equationTokens, comments = addition(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = additionEquation( lTokens, rTokens, True) elif operation == 'subtraction': if solutionType == 'expression': tokens, _, _, equationTokens, comments = subtraction(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = subtractionEquation( lTokens, rTokens, True) elif operation == 'multiplication': if solutionType == 'expression': tokens, _, _, equationTokens, comments = multiplication( tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = multiplicationEquation( lTokens, rTokens, True) elif operation == 'division': if solutionType == 'expression': tokens, _, _, equationTokens, comments = division(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = divisionEquation( lTokens, rTokens, True) elif operation == 'simplify': if solutionType == 'expression': tokens, _, _, equationTokens, comments = simplify(tokens) else: lTokens, rTokens, _, _, equationTokens, comments = simplifyEquation( lTokens, rTokens) elif operation == 'factorize': tokens, _, _, equationTokens, comments = factorize(tokens) elif operation == 'find-roots': lTokens, rTokens, _, _, equationTokens, comments = quadraticRoots( lTokens, rTokens) elif operation == 'solve': lhs, rhs = getLHSandRHS(tokens) lTokens, rTokens, _, _, equationTokens, comments = solveFor( lTokens, rTokens, varName) elif operation == 'integrate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = integrate(lTokens, varName) elif operation == 'differentiate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = differentiate( lTokens, varName) printOnCLI(equationTokens, operation, comments)
def calluser(): availableOperations = [] tokenString = '' equationTokens = [] self.resultOut = True if not self.matrix: """ This part handles the cases when VisMa is NOT dealing with matrices. Boolean flags used in code below: simul -- {True} when VisMa is dealing with simultaneous equations & {False} in all other cases """ if name == 'addition': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = addition( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = additionEquation( self.lTokens, self.rTokens, True) elif name == 'subtraction': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = subtraction( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = subtractionEquation( self.lTokens, self.rTokens, True) elif name == 'multiplication': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = multiplication( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = multiplicationEquation( self.lTokens, self.rTokens, True) elif name == 'division': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = division( self.tokens, True) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = divisionEquation( self.lTokens, self.rTokens, True) elif name == 'simplify': if self.solutionType == 'expression': self.tokens, availableOperations, tokenString, equationTokens, comments = simplify(self.tokens) else: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = simplifyEquation(self.lTokens, self.rTokens) elif name == 'factorize': self.tokens, availableOperations, tokenString, equationTokens, comments = factorize(self.tokens) elif name == 'find roots': self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = rootFinder(self.lTokens, self.rTokens) elif name == 'solve': if not self.simul: lhs, rhs = getLHSandRHS(self.tokens) variables = getVariables(lhs, rhs) else: variables = getVariableSim(self.tokens) self.wrtVariableButtons(variables, name) self.resultOut = False elif name == 'factorial': self.tokens, availableOperations, tokenString, equationTokens, comments = factorial(self.tokens) elif name == 'combination': nTokens = self.tokens[0] rTokens = self.tokens[1] self.tokens, _, _, equationTokens, comments = combination(nTokens, rTokens) elif name == 'permutation': nTokens = self.tokens[0] rTokens = self.tokens[1] self.tokens, _, _, equationTokens, comments = permutation(nTokens, rTokens) elif name == 'integrate': lhs, rhs = getLHSandRHS(self.tokens) variables = getVariables(lhs, rhs) self.wrtVariableButtons(variables, name) self.resultOut = False elif name == 'differentiate': lhs, rhs = getLHSandRHS(self.tokens) variables = getVariables(lhs, rhs) self.wrtVariableButtons(variables, name) self.resultOut = False else: """ This part handles the cases when VisMa is dealing with matrices. Boolean flags used in code below: dualOperand -- {True} when the matrix operations require two operands (used in operations like addition, subtraction etc) nonMatrixResult -- {True} when the result after performing operations on the Matrix is not a Matrix (in operations like Determinant, Trace etc.) scalarOperations -- {True} when one of the operand in a scalar (used in operations like Scalar Addition, Scalar Subtraction etc.) """ # TODO: use latex tools like /amsmath for displaying matrices if self.dualOperandMatrix: Matrix1_copy = copy.deepcopy(self.Matrix1) Matrix2_copy = copy.deepcopy(self.Matrix2) else: Matrix0_copy = copy.deepcopy(self.Matrix0) if name == 'Addition': MatrixResult = addMatrix(self.Matrix1, self.Matrix2) elif name == 'Subtraction': MatrixResult = subMatrix(self.Matrix1, self.Matrix2) elif name == 'Multiply': MatrixResult = multiplyMatrix(self.Matrix1, self.Matrix2) elif name == 'Simplify': MatrixResult = simplifyMatrix(self.Matrix0) elif name == 'Trace': sqMatrix = SquareMat() sqMatrix.value = self.Matrix0.value result = sqMatrix.traceMat() elif name == 'Determinant': sqMatrix = SquareMat() sqMatrix.value = self.Matrix0.value result = sqMatrix.determinant() elif name == 'Inverse': sqMatrix = SquareMat() sqMatrix.value = self.Matrix0.value MatrixResult = SquareMat() MatrixResult = sqMatrix.inverse() if name in ['Addition', 'Subtraction', 'Multiply']: self.dualOperandMatrix = True else: self.dualOperandMatrix = False if name in ['Determinant', 'Trace']: self.nonMatrixResult = True else: self.nonMatrixResult = False if self.resultOut: if not self.matrix: self.eqToks = equationTokens self.output = resultLatex(equationTokens, name, comments, self.solutionType) if (mathError(self.eqToks[-1])): self.output += 'Math Error: LHS not equal to RHS' + '\n' if len(availableOperations) == 0: self.clearButtons() else: self.refreshButtons(availableOperations) if self.mode == 'normal': self.textedit.setText(tokenString) elif self.mode == 'interaction': cursor = self.textedit.textCursor() cursor.insertText(tokenString) if self.showStepByStep is True: showSteps(self) if self.showPlotter is True: plot(self) else: if self.dualOperandMatrix: if not self.scalarOperationsMatrix: self.output = resultMatrixStringLatex(operation=name, operand1=Matrix1_copy, operand2=Matrix2_copy, result=MatrixResult) else: # TODO: Implement Scalar Matrices operations. pass # finalCLIstring = resultMatrix_Latex(operation=name, operand1=scalarTokens_copy, operand2=Matrix2_copy, result=MatrixResult) else: if self.nonMatrixResult: self.output = resultMatrixStringLatex(operation=name, operand1=Matrix0_copy, nonMatrixResult=True, result=result) else: self.output = resultMatrixStringLatex(operation=name, operand1=Matrix0_copy, result=MatrixResult) if self.mode == 'normal': self.textedit.setText(tokenString) elif self.mode == 'interaction': cursor = self.textedit.textCursor() cursor.insertText(tokenString) if self.showStepByStep is True: showSteps(self)