def __sub__(self, other): if isinstance(other, Constant): self = self + Constant(-1, 1, 1) * other return self elif isinstance(other, Variable): if self.value == 0: other.coefficient *= -1 return other expression = Expression() expression.tokens = [self] expression.tokens.extend([Minus(), other]) elif isinstance(other, Expression): expression = Expression() expression.tokens = [self] if other.power == 1: coeff = other.coefficient for i, token in enumerate(other.tokens): print(expression, " ", type(token), other.tokens[i-1]) if isinstance(token, Constant): if other.tokens[i-1].value == '+' or i == 0: expression.tokens[0] = Constant(self.calculate() - token.calculate()*coeff) elif other.tokens[i-1].value == '-': expression.tokens[0] = Constant(self.calculate() + token.calculate()*coeff) elif isinstance(token, Variable): if other.tokens[i-1].value == '+' or i == 0: expression.tokens.extend([Minus(), Variable(token)]) elif other.tokens[i-1].value == '-': expression.tokens.extend([Plus(), Variable(token)]) else: expression.tokens.extend([Minus(), other]) self = expression return expression
def __sub__(self, other): from visma.functions.constant import Constant if isinstance(other, Variable): otherValueSorted = sorted(other.value) selfValueSorted = sorted(self.value) if (other.power == self.power) & (selfValueSorted == otherValueSorted): self = self + Constant(-1, 1, 1) * other return self else: expression = Expression() expression.tokens = [self] expression.tokens.extend([Minus(), other]) self = expression return expression elif isinstance(other, Constant): if other.isZero(): return self expression = Expression() expression.tokens = [self] expression.tokens.extend([Minus(), other]) self = expression return expression elif isinstance(other, Expression): expression = Expression() expression.tokens = [self] for i, token in enumerate(other.tokens): if isinstance(token, Variable): tokenValueSorted = sorted(token.value) selfValueSorted = sorted(self.value) if (token.power == self.power) & (tokenValueSorted == selfValueSorted): if other.tokens[i - 1].value == '+' or (i == 0): self.coefficient -= other.tokens[i].coefficient elif other.tokens[i - 1].value == '-': self.coefficient += other.tokens[i].coefficient else: if other.tokens[i - 1].value == '+' or i == 0: expression.tokens.extend([Plus(), Variable(token)]) elif other.tokens[i - 1].value == '-': expression.tokens.extend( [Minus(), Variable(token)]) elif not isinstance(token, Binary): if other.tokens[i - 1].value == '+' or (i == 0): expression.tokens.extend([Minus(), token]) elif other.tokens[i - 1].value == '-': expression.tokens.extend([Plus(), token]) expression.tokens[0] = self self = expression return expression
def factorizeTokens(tokens): coeffs, var = getPolyCoeffs(tokens) gcf, roots, polynomial = factor(coeffs) if roots != []: tokens = [] comment = "The real roots of the above polynomial are " for root in roots: comment += r"$" + str(root) + "\ ,\ " + r"$" if gcf != 1: tokens.append(Constant(float(gcf))) tokens.append(Multiply()) for root in roots: expression = Expression() expression.tokens.append(Variable(1, var, 1)) if root > 0: expression.tokens.append(Minus()) expression.tokens.append(Constant(float(root))) elif root < 0: expression.tokens.append(Plus()) expression.tokens.append(Constant(float(-root))) tokens.append(expression) tokens.append(Multiply()) if polynomial != [1]: expression = Expression() degree = len(polynomial) - 1 for i, coeff in enumerate(polynomial): if i == degree: if coeff > 0: expression.tokens.append(Plus()) expression.tokens.append(Constant(float(coeff))) elif coeff < 0: expression.tokens.append(Minus()) expression.tokens.append(Constant(float(-coeff))) elif coeff > 0: expression.tokens.append(Plus()) expression.tokens.append(Variable(coeff, var, degree - i)) elif coeff < 0: expression.tokens.append(Minus()) expression.tokens.append(Variable(-coeff, var, degree - i)) if isinstance(expression.tokens[0], Plus): expression.tokens.pop(0) tokens.append(expression) else: tokens.pop() else: comment = None animation = [tokens] comments = [comment] return tokens, animation, comments
def __sub__(self, other): from visma.functions.constant import Constant from visma.functions.variable import Variable from visma.functions.operator import Plus, Minus if isinstance(other, Expression): result = Expression() for tok1 in self.tokens: result.tokens.append(tok1) for _, x in enumerate(other.tokens): if x.value == '+': x.value = '-' elif x.value == '-': x.value = '+' result.tokens.append(Minus()) if (isinstance(other.tokens[0], Constant)): if (other.tokens[0].value < 0): result.tokens[-1] = Plus() other.tokens[0].value = abs(other.tokens[0].value) elif (isinstance(other.tokens[0], Variable)): if (other.tokens[0].coefficient < 0): result.tokens[-1] = Plus() other.tokens[0].coefficient = abs(other.tokens[0].coefficient) return result elif isinstance(other, Constant): result = self result += (Constant(0) - other) return result elif isinstance(other, Variable): result = self a = Constant(0) - other result = a + result return result
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 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 test_Constant(): # Tests for Calculus operations for Constant Class. constant1 = Constant(10) assert constant1.__str__() == "{10}" constant1.differentiate() assert constant1.value == 0 constant2 = Constant(5, 2) constant2.integrate('x') assert isinstance(constant2, Variable) assert constant2.__str__() == "25{x}" # Tests for Add/Sub operations (using Overloading) for Constant Class. constant4 = Constant(2, 2) constant5 = Constant(7) constant3 = constant4 - constant5 assert constant3.__str__() == "{-3}" constant4 = Constant(7, 2) constant0 = Constant(5) constant6 = constant4 - constant3 - constant5 + constant0 assert constant6.__str__() == "{50}" constant0 = Constant(5, 2, 2) constant2 = constant0 variable0 = Variable(5, 'X', 3) summation0 = constant0 - variable0 + constant2 assert summation0.__str__() == "{({100}-5{X}^{3})}" constant0 = Constant(5, 2, 2) constant2 = constant0 variable0 = Variable(5, 'X', 3) summation0 = constant0 + variable0 + constant2 assert summation0.__str__() == "{({100}+5{X}^{3})}" var1 = Variable(3, 'x', 3) const1 = Constant(5) expr1 = Expression([var1, Minus(), const1]) constant2 = Constant(2, 2) sub1 = constant2 - expr1 assert sub1.__str__() == "{({9}-3{x}^{3})}" constant1 = Constant(2) constant2 = Constant(7) constant3 = constant1 + constant2 assert constant3.__str__() == "{9}" constant1 = Constant(2) constant2 = Constant(7) constant3 = constant1 - constant2 assert constant3.__str__() == "{-5}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) summation = constant1 + variable1 assert summation.__str__() == "{({5}+5{x}^{3})}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) summation = constant1 - variable1 assert summation.__str__() == "{({5}-5{x}^{3})}" # Tests for Add/Sub operations (using Overloading) for Constant Class. constant0 = Constant(0, 2) constant1 = Constant(5) mul1 = constant0 * constant1 assert mul1.calculate() == 0 mul1 = constant1 * constant0 assert mul1.calculate() == 0 mul1 = constant1 * constant1 + constant0 * constant1 + constant0 * constant1 assert mul1.calculate() == 25 constant1 = Constant(5, 2) constant2 = Constant(4, 2) variable0 = Variable(3, 'X', 3) mul3 = constant1 * (constant2 + variable0) assert mul3.__str__() == "{({400}+75{X}^{3})}" constant1 = Constant(5, 2) constant2 = Constant(4, 2) variable0 = Variable(3, 'X', 3) mul3 = constant1 / (constant2 + variable0) assert mul3.__str__() == "{25}*{({16}+3{X}^{3})}^{-1}" constant1 = Constant(5) constant2 = Constant(4) div1 = constant1 / constant2 assert div1.__str__() == "{1.25}" constant1 = Constant(3, 2) constant2 = Constant(4, 2) variable0 = Variable(3, 'X', 3) mul3 = constant1 - constant1 / (constant2 / variable0 + constant1) assert mul3.__str__( ) == "{({9}-{9}*{(5.333333333333333{X}^{-3}+{9})}^{-1})}" constant1 = Constant(2, 2) constant2 = Constant(2, 2) mul3 = constant1**constant2 assert mul3.__str__() == "{256}" constant1 = Constant(5) constant2 = Constant(5) summation = constant1 * constant2 assert summation.__str__() == "{25}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) exp1 = Expression([constant1, Plus(), variable1]) constant2 = Constant(10) summation = constant2 + exp1 assert summation.__str__() == "{({15}+5{x}^{3})}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) exp1 = Expression([constant1, Plus(), variable1]) constant2 = Constant(10) summation = constant2 - exp1 assert summation.__str__() == "{({5}-5{x}^{3})}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) exp1 = Expression([constant1, Plus(), variable1]) constant2 = Constant(10) summation = exp1 - constant2 assert summation.__str__() == "{({-5}+5{x}^{3})}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) summation = constant1 * variable1 assert summation.__str__() == "25{x}^{3}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) exp1 = Expression([constant1, Plus(), variable1]) constant2 = Constant(10) summation = constant2 * exp1 assert summation.__str__() == "{({50}+50{x}^{3})}" constant1 = Constant(5) constant2 = Constant(5) summation = constant1 / constant2 assert summation.__str__() == "{1.0}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) summation = constant1 / variable1 assert summation.__str__() == "{x}^{-3}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) exp1 = Expression([constant1, Plus(), variable1]) constant2 = Constant(10) summation = constant2 / exp1 assert summation.__str__() == "{10}*{({5}+5{x}^{3})}^{-1}" constant1 = Constant(5) variable1 = Variable(5, 'x', 3) exp1 = Expression([constant1, Plus(), variable1]) constant2 = Constant(10) summation = exp1 / constant2 assert summation.__str__() == "{({0.5}+0.5{x}^{3})}"
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