Example #1
0
 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 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 get_signature(self):
     signature = {}  # KEY: term, VALUE: count
     for subterm in self.terms:
         if not ((subterm.term_type == TermTypes.POLYNOMIAL) and
                 (subterm.power == 0)):
             subterm_sig = SimpleTerm(subterm.term_type, 1, subterm.power)
             AbstractTerm.increment_map(signature, subterm_sig, 1)
     return signature
Example #4
0
    def __rmul__(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)])
        else:
            raise TypeError(
                "Multiplying SimpleTerm with thing that is not a number or term"
            )
    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)
Example #6
0
 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 __split_expression(terms):
     coefficient = functools.reduce(lambda x, y: x * y.multiple, terms, 1)
     exp_accum = 0
     polynom_accum = 0
     sin_cos_terms = []
     for term in terms:
         if (term.term_type == TermTypes.SINE) or (term.term_type
                                                   == TermTypes.COSINE):
             sin_cos_terms.append(SimpleTerm(term.term_type, 1, term.power))
         elif term.term_type == TermTypes.POLYNOMIAL:
             polynom_accum += term.power
         elif term.term_type == TermTypes.EXPONENTIAL:
             exp_accum += term.power
         else:
             raise ValueError("Illegal Term Type!")
     return coefficient, polynom_accum, exp_accum, sin_cos_terms
    def simplify(self):
        # Simplify, and "Flatten" any weird nested MultiplyTerms.
        tmp_terms = [term.simplify() for term in self.terms]
        terms = []
        # coef = self.coefficient
        # print(coef)
        for term in tmp_terms:
            if isinstance(term, MultiplyTerm):
                terms = terms + term.terms
                # coef *= term.coefficient
            else:
                terms.append(term)

        # REAL simplest case: Only one term.
        if len(terms) == 1:
            return terms[0]  # * coef

        # Stupid add terms screwing everything up
        add_terms = [term.terms for term in terms if isinstance(term, AddTerm)]
        other_terms = [term for term in terms if not isinstance(term, AddTerm)]

        # Split up the "other terms" into core components
        coefficient, polynom_accum, exp_accum, sin_cos_terms = MultiplyTerm.__split_expression(
            other_terms)

        # coefficient *= coef

        if len(add_terms) == 0:
            accumulated_terms = [
                SimpleTerm(TermTypes.POLYNOMIAL, coefficient, 0)
            ]
            if not (polynom_accum == 0):
                accumulated_terms.append(
                    SimpleTerm(TermTypes.POLYNOMIAL, 1, polynom_accum))
            if not (exp_accum == 0):
                accumulated_terms.append(
                    SimpleTerm(TermTypes.EXPONENTIAL, 1, exp_accum))
            if (len(accumulated_terms) == 1) and (len(sin_cos_terms) == 0):
                return accumulated_terms[0]
            return MultiplyTerm(accumulated_terms + sin_cos_terms)

        retvals = []
        for combo in itertools.product(*add_terms):
            mult_tmp = MultiplyTerm(list(combo)).simplify()
            tmp_coef, tmp_polynom_accum, tmp_exp_accum, tmp_sin_cos_terms = \
                MultiplyTerm.__split_expression(mult_tmp.terms)
            total_coefficient = coefficient * tmp_coef
            if total_coefficient == 0:
                continue
            total_polynom_accum = polynom_accum + tmp_polynom_accum
            total_exp_accum = exp_accum + tmp_exp_accum
            total_sin_cos_terms = sin_cos_terms + tmp_sin_cos_terms
            accumulated_terms = [
                SimpleTerm(TermTypes.POLYNOMIAL, total_coefficient, 0)
            ]
            if not (total_polynom_accum == 0):
                accumulated_terms.append(
                    SimpleTerm(TermTypes.POLYNOMIAL, 1, total_polynom_accum))
            if not (total_exp_accum == 0):
                accumulated_terms.append(
                    SimpleTerm(TermTypes.EXPONENTIAL, 1, total_exp_accum))

            if (len(accumulated_terms) == 1) and (len(total_sin_cos_terms)
                                                  == 0):
                retvals.append(accumulated_terms[0])
            else:
                retvals.append(
                    MultiplyTerm(accumulated_terms + total_sin_cos_terms))
        if len(retvals) == 0:
            return SimpleTerm(TermTypes.POLYNOMIAL, 0, 0)
        return AddTerm(retvals).simplify()
Example #9
0
    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])