def __mul__(self, other): from main.multiplyterm import MultiplyTerm from main.simpleterm import SimpleTerm, TermTypes if isinstance(other, numbers.Number): return MultiplyTerm( [self, SimpleTerm(TermTypes.POLYNOMIAL, other, 0)]) elif isinstance(other, AbstractTerm): return MultiplyTerm([self, other]) else: raise TypeError( "Multiplying SimpleTerm with thing that is not a number or term" )
class MyTestCase(unittest.TestCase): def setUp(self): # a = VariedCoefficient(A=1) # b = VariedCoefficient(B=1) self.term1 = SimpleTerm(TermTypes.POLYNOMIAL, -5, 1) self.term2 = SimpleTerm(TermTypes.EXPONENTIAL, 3, 3) self.term3 = SimpleTerm(TermTypes.POLYNOMIAL, 4, 3) self.term4 = SimpleTerm(TermTypes.SINE, 2, 8) def test_simplify_nested(self): self.mult_term = MultiplyTerm([self.term1, self.term2]) self.assertEqual(str(self.mult_term.simplify()), "(-15) * (x) * (e^(3x))") def test_add_mult(self): # term5 = MultiplyTerm([AddTerm([self.term1, self.term2]), # AddTerm([self.term3, self.term4])]) # self.assertEqual(str(term5.simplify()), "((-20) * (x^(4))) + ((-10) * (sin(8x)) * (x)) + " # "((12) * (x^(3)) * (e^(3x))) + ((6) * (sin(8x)) * (e^(3x)))") # term6 = MultiplyTerm([AddTerm([self.term1, self.term2]), # AddTerm([self.term1, -1 * self.term2])]).simplify() # term_compare = AddTerm([SimpleTerm(TermTypes.POLYNOMIAL, # self.term1.multiple ** 2, # self.term1.power * 2), # SimpleTerm(TermTypes.EXPONENTIAL, # -self.term2.multiple ** 2, # self.term2.power * 2)]).simplify() # print(AddTerm([self.term1, self.term2])) # print(AddTerm([self.term1, -1 * self.term2])) # print(term6) # print(term_compare) pass
def setUp(self): a = VariedCoefficient(A=1) b = VariedCoefficient(B=1) self.term1 = AddTerm([MultiplyTerm([SimpleTerm(TermTypes.POLYNOMIAL, b, 0), SimpleTerm(TermTypes.POLYNOMIAL, 1, 0)]), SimpleTerm(TermTypes.POLYNOMIAL, a, 0), SimpleTerm(TermTypes.POLYNOMIAL, 6, 0), SimpleTerm(TermTypes.POLYNOMIAL, b + 5, 1)])
def solve_homogenous(self): self.homogenous_solutions = [None, None] a = self.coefs.variables[Equation.Y_PP] b = self.coefs.variables[Equation.Y_P] c = self.coefs.variables[Equation.Y] bsq_4ac = b**2 - 4 * c * a if bsq_4ac > 0: # Standard two exponential solutions root1 = (-b + math.sqrt(bsq_4ac)) / (2 * a) root2 = (-b - math.sqrt(bsq_4ac)) / (2 * a) self.homogenous_solutions[0] = SimpleTerm( TermTypes.EXPONENTIAL, VariedCoefficient(**{Equation.C1: 1}), root1) self.homogenous_solutions[1] = SimpleTerm( TermTypes.EXPONENTIAL, VariedCoefficient(**{Equation.C2: 1}), root2) elif bsq_4ac < 0: # Periodic solution b_2a = -b / (2 * a) freq_term = math.sqrt(-bsq_4ac) / (2 * a) self.homogenous_solutions[0] = MultiplyTerm([ SimpleTerm(TermTypes.EXPONENTIAL, VariedCoefficient(**{Equation.C1: 1}), b_2a), SimpleTerm(TermTypes.SINE, 1, freq_term) ]) self.homogenous_solutions[1] = MultiplyTerm([ SimpleTerm(TermTypes.EXPONENTIAL, VariedCoefficient(**{Equation.C2: 1}), b_2a), SimpleTerm(TermTypes.COSINE, 1, freq_term) ]) else: # Repeated roots b_2a = -b / (2 * a) self.homogenous_solutions[0] = SimpleTerm( TermTypes.EXPONENTIAL, VariedCoefficient(**{Equation.C1: 1}), b_2a) self.homogenous_solutions[1] = MultiplyTerm([ SimpleTerm(TermTypes.POLYNOMIAL, VariedCoefficient(**{Equation.C2: 1}), 1), SimpleTerm(TermTypes.EXPONENTIAL, 1, b_2a) ]) self.homogenous_solutions = list( [soln.simplify() for soln in self.homogenous_solutions])
def simplify(self): from main.multiplyterm import MultiplyTerm # "Flatten" any weird nested AddTerms. tmp_terms = [term.simplify() for term in self.terms] # Possibly redundant terms = [] for term in tmp_terms: if isinstance(term, AddTerm): terms = terms + term.terms else: terms.append(term) # REAL simplest case: Only one term. if len(terms) == 1: return terms[0] term_signatures = {} # Signature, coef for term in terms: term = term.simplify() # Simplify again after breaking up nested add terms signature = {} # KEY: term, VALUE: count coef = 0 if isinstance(term, MultiplyTerm): coef = term.get_coefficient_term().multiple signature = term.get_signature() elif isinstance(term, SimpleTerm): coef = term.multiple signature[SimpleTerm(term.term_type, 1, term.power)] = 1 else: raise ValueError("Term Type not recognized!") frozen_key = frozenset(signature.items()) AbstractTerm.increment_map(term_signatures, frozen_key, coef) retvals = [] for signature in term_signatures: const_val = term_signatures[signature] if not (const_val == 0): # print(const_val) const_term = SimpleTerm(TermTypes.POLYNOMIAL, const_val, 0) retvals.append(MultiplyTerm([const_term] + list(dict(signature)))) return AddTerm(retvals)
def init_solutions(self): self.solve_homogenous() homogenous_signatures = [ solution.get_signature() for solution in self.homogenous_solutions ] # for term in homogenous_signatures: # for blah in term: # print(blah, term[blah]) # print() # # print(term) self.var_num = ord('A') self.specific_solutions = [] for term in self.terms.terms: solution_terms = [] subterms = term.terms for subterm in subterms: if not isinstance(subterm, SimpleTerm): raise ValueError( "Solution init error: Terms not simplified correctly!") term_type = subterm.term_type if term_type == TermTypes.POLYNOMIAL: polynom_terms = [] for i in range(subterm.power + 1): polynom_terms.append( SimpleTerm(TermTypes.POLYNOMIAL, 1, i)) solution_terms.append(AddTerm(polynom_terms)) elif term_type == TermTypes.EXPONENTIAL: solution_terms.append( SimpleTerm(TermTypes.EXPONENTIAL, 1, subterm.power)) elif (term_type == TermTypes.SINE) or term_type == TermTypes.COSINE: solution_terms.append( AddTerm([ SimpleTerm(TermTypes.SINE, 1, subterm.power), SimpleTerm(TermTypes.COSINE, 1, subterm.power) ])) solution_form = MultiplyTerm(solution_terms) solution_form = solution_form.simplify() names = [] repeats = 0 for polyterm in solution_form.terms: # Check for solutions that are already part of the general solution for signature in homogenous_signatures: if polyterm.get_signature() == signature: repeats += 1 name = self.__get_next_available_name() names.append(name) coef = VariedCoefficient(**{name: 1}) if isinstance(polyterm, SimpleTerm): polyterm.multiple = coef continue if not isinstance(polyterm, MultiplyTerm): raise ValueError( "Solving error: Failed to simplify properly") polyterm.get_coefficient_term().multiple = coef # Multiply by t^s if not (repeats == 0): solution_form = ( solution_form * SimpleTerm(TermTypes.POLYNOMIAL, 1, repeats)).simplify() self.specific_solutions.append((solution_form, term, names))
# from main.variedcoefficient import VariedCoefficient from main.simpleterm import SimpleTerm, TermTypes # from main.addterm import AddTerm from main.multiplyterm import MultiplyTerm from main.equation import Equation # x = VariedCoefficient("A") # x = x * 2 * 7 # print(x) # term1 = SimpleTerm(TermTypes.EXPONENTIAL, 3, 2) term2 = SimpleTerm(TermTypes.POLYNOMIAL, -5, 2) term4 = MultiplyTerm([ SimpleTerm(TermTypes.COSINE, 1, 2), SimpleTerm(TermTypes.POLYNOMIAL, 1, 1) ]).simplify() term5 = SimpleTerm(TermTypes.SINE, 3, 2) # print(term1) # print(term2) # print(term5) # print(term5.derivative()) # print(term5.simplify()) eqn1 = Equation(coef_list=[1, 0, 1], term_list=[term4, term5]) # eqn1 = Equation(coef_list=[1, 1, 1], term_list=[term2]) eqn1.init_solutions() print(eqn1) eqn1.solve_all_specific() print(eqn1.specific_solutions[0])
def test_simplify_nested(self): self.mult_term = MultiplyTerm([self.term1, self.term2]) self.assertEqual(str(self.mult_term.simplify()), "(-15) * (x) * (e^(3x))")