Exemple #1
0
 def setUp(self):
     self.t = tensor.Tensor('t')
     self.tf = tensor.TensorFunction('tf')
     self.a = sympy.Dummy('a')
     self.b = sympy.Dummy('b')
     self.x, self.y, self.z = sympy.symbols('x,y,z')
     self.f = sympy.Function('f')
Exemple #2
0
    def symbol(self, name):
        if name in self.symbols:
            return self.symbols[name]

        prefix = (
            not self.prefix_exclude and name in self.prefix_include or
            not self.prefix_include and name not in self.prefix_exclude
        ) and self.prefix or ''
        suffix = (
            not self.suffix_exclude and name in self.suffix_include or
            not self.suffix_include and name not in self.suffix_exclude
        ) and self.suffix or ''

        if isinstance(name, integer_types):
            # all integers are currently treated as dummy variables
            fullname = prefix + str(name) + suffix
            symbol = sympy.Dummy(fullname)
        else:
            fullname = prefix + name + suffix
            if self.dummies is True or name in self.dummies:
                symbol = sympy.Dummy(fullname)
            else:
                symbol = sympy.Symbol(fullname)

        self.symbols[name] = symbol
        self.symbolnames[symbol] = name  # XXX needed?
        return symbol
Exemple #3
0
def power_rule(derivative):
    expr, symbol = derivative.expr, derivative.symbol
    base, exp = expr.as_base_exp()

    if not base.has(symbol):
        if isinstance(exp, sympy.Symbol):
            return ExpRule(expr, base, expr, symbol)
        else:
            u = sympy.Dummy()
            f = base ** u
            return ChainRule(
                ExpRule(f, base, f, u),
                exp, u,
                diff_steps(exp, symbol),
                expr, symbol
            )
    elif not exp.has(symbol):
        if isinstance(base, sympy.Symbol):
            return PowerRule(base, exp, expr, symbol)
        else:
            u = sympy.Dummy()
            f = u ** exp
            return ChainRule(
                PowerRule(u, exp, f, u),
                base, u,
                diff_steps(base, symbol),
                expr, symbol
            )
    else:
        return DontKnowRule(expr, symbol)
Exemple #4
0
def functional_derivative(functional, v):
    r"""Computes functional derivative of functional with respect to v using Euler-Lagrange equation

    .. math ::

        \frac{\delta F}{\delta v} =
                \frac{\partial F}{\partial v} - \nabla \cdot \frac{\partial F}{\partial \nabla v}

    - assumes that gradients are represented by Diff() node
    - Diff(Diff(r)) represents the divergence of r
    - the constants parameter is a list with symbols not affected by the derivative. This is used for simplification
      of the derivative terms.
    """
    diffs = functional.atoms(Diff)
    bulk_substitutions = {d: sp.Dummy() for d in diffs}
    bulk_substitutions_inverse = {v: k for k, v in bulk_substitutions.items()}
    non_diff_part = functional.subs(bulk_substitutions)
    partial_f_partial_v = sp.diff(non_diff_part,
                                  v).subs(bulk_substitutions_inverse)

    gradient_part = 0
    for diff_obj in diffs:
        if diff_obj.args[0] != v:
            continue
        dummy = sp.Dummy()
        partial_f_partial_grad_v = functional.subs(diff_obj,
                                                   dummy).diff(dummy).subs(
                                                       dummy, diff_obj)
        gradient_part += Diff(partial_f_partial_grad_v,
                              target=diff_obj.target,
                              superscript=diff_obj.superscript)

    result = partial_f_partial_v - gradient_part
    return result
Exemple #5
0
def test_imports():
    from eqpy.dummies import x1, y1 as why1
    assert x1 is not sympy.Dummy('x1')
    assert why1 is not sympy.Dummy('y1')
    assert eqpy.dummies.x1 is not x1
    assert isinstance(x1, sympy.Dummy)
    assert isinstance(why1, sympy.Dummy)
    from eqpy.dummies import y1
    assert y1 is not why1
Exemple #6
0
def maxwell_construction(eos, tolerance=1e-4):
    """Numerical Maxwell construction to find ρ_gas and ρ_liquid for a given equation of state.

    Args:
        eos: equation of state, that has only one symbol (the density) in it
        tolerance: internally a bisection algorithm is used to find pressure such that areas below and
                   above are equal. The tolerance parameter refers to the pressure. If the integral is smaller than
                   the tolerance the bisection algorithm is stopped.

    Returns:
        (gas density, liquid density)
    """
    dofs = eos.atoms(sp.Symbol)
    assert len(dofs) == 1
    density = dofs.pop()
    v = sp.Dummy()
    eos = eos.subs(density, 1 / v)

    # pre-compute integral once - then it is evaluated in every bisection iteration
    symbolic_offset = sp.Dummy(real=True)
    integral = sp.integrate(sp.nsimplify(eos + symbolic_offset), v)
    upper_bound, lower_bound = sp.Dummy(real=True), sp.Dummy(real=True)
    symbolic_deviation = integral.subs(v, upper_bound) - integral.subs(v, lower_bound)
    get_deviation = sp.lambdify((lower_bound, upper_bound, symbolic_offset), symbolic_deviation)

    critical_points = sp.solve(sp.diff(eos, v))
    critical_points = [remove_small_floats(e, 1e-14) for e in critical_points]
    critical_points = [e for e in critical_points if e.is_real]
    *_, v_min, v_max = critical_points

    assert sp.diff(eos, v, v).subs(v, v_min) > 0
    assert sp.diff(eos, v, v).subs(v, v_max) < 0

    assert sp.limit(eos, v, sp.oo) == 0
    # shift has to be negative, since equation of state approaches zero for v -> oo
    shift_min, shift_max = -eos.subs(v, v_max), 0
    c = (shift_max + shift_min) / 2
    deviation = tolerance * 2

    while abs(deviation) > tolerance:
        solve_res = sp.solve(eos + c)
        solve_res = [remove_small_floats(e, 1e-14) for e in solve_res]
        zeros = sorted([e for e in solve_res if e.is_real])
        integral_bounds = (zeros[-3], zeros[-1])
        deviation = get_deviation(float(integral_bounds[0]), float(integral_bounds[1]), float(c))
        if deviation > 0:
            shift_max = c
        else:
            shift_min = c
        c = (shift_max + shift_min) / 2

    return 1 / integral_bounds[1], 1 / integral_bounds[0]
Exemple #7
0
def substitution_rule(integral):
    integrand, symbol = integral

    u_var = sympy.Dummy("u")
    substitutions = find_substitutions(integrand, symbol, u_var)
    if substitutions:
        ways = []
        for u_func, c, substituted in substitutions:
            subrule = integral_steps(substituted / c, u_var)
            if contains_dont_know(subrule):
                continue

            if sympy.simplify(c - 1) != 0:
                subrule = ConstantTimesRule(c, substituted / c, subrule,
                                            substituted, symbol)

            ways.append(URule(u_var, u_func, c, subrule, integrand, symbol))

        if len(ways) > 1:
            return AlternativeRule(ways, integrand, symbol)
        elif ways:
            return ways[0]

    elif integrand.has(sympy.exp):
        u_func = sympy.exp(symbol)
        c = 1
        substituted = integrand / u_func.diff(symbol)
        substituted = substituted.subs(u_func, u_var)

        if symbol not in substituted.free_symbols:
            return URule(u_var, u_func, c, integral_steps(substituted, u_var),
                         integrand, symbol)
Exemple #8
0
    def __init__(self, dims):
        """Constructs a shape whose i-th dim is dims[i].

    Each dim can be one of the following types:
      integer: represents the dimension is a known and fixed.
      string: represents the dimension is an unknown and a sympy dummy symbol is
        used to represent it. Also note that contents of strings only matter for
        logging/printing. Even if the same string is given on multiple
        dimensions, it doesn't mean that they are the same.
      sympy expression: represents a dimension which possibly
        depends on dimensions of other shapes.

    Args:
      dims: A list of either integer, string or sympy.Symbol.
    """
        self._shape = []
        for x in dims:
            assert x is not None, str(dims)
            if isinstance(x, six.string_types):
                # NOTE: Dummy(x) creates a unique symbol. I.e., the value of x has no
                # meaning except for printing, etc.
                self._shape.append(sympy.Dummy(x, integer=True))
            else:
                # Converts x to a sympy type. E.g., int to sympy.Integer.
                self._shape.append(sympy.sympify(x))
        self._size = sympy.prod(self._shape)
Exemple #9
0
def complete_the_squares_in_exp(expr: sp.Expr,
                                symbols_to_complete: Sequence[sp.Symbol]):
    """Completes squares in arguments of exponential which makes them simpler to integrate.

    Very useful for integrating Maxwell-Boltzmann equilibria and its moment generating function
    """
    dummies = [sp.Dummy() for _ in symbols_to_complete]

    def visit(term):
        if term.func == sp.exp:
            exp_arg = term.args[0]
            for symbol_to_complete, dummy in zip(symbols_to_complete, dummies):
                exp_arg, substitution = complete_the_square(
                    exp_arg, symbol_to_complete, dummy)
            return sp.exp(sp.expand(exp_arg))
        else:
            param_list = [visit(a) for a in term.args]
            if not param_list:
                return term
            else:
                return term.func(*param_list)

    result = visit(expr)
    for s, d in zip(symbols_to_complete, dummies):
        result = result.subs(d, s)
    return result
Exemple #10
0
    def check_analytic(self, w=None, silent=False):
        if w is None:
            f = self.w_sympy
        elif type(w) == str:
            f = self.w_sympy = self.evaluate(w)
        else:
            f = self.w_sympy

        reps = defaultdict(lambda: sym.Dummy(real=True))

        f = f.replace(lambda x: x.is_Float, lambda x: reps[x])

        u = sym.re(f)
        v = sym.im(f)

        cond1 = sym.diff(u, x) - sym.diff(v, y)
        cond2 = sym.diff(u, y) + sym.diff(v, x)

        if sym.simplify(cond1) == 0 and sym.simplify(cond2) == 0:
            if silent is False:
                print('The function is conformal, angles are preserved :)')
            out = True
        else:
            if silent is False:
                print(
                    'The function is not conformal, angles are not preserved ...'
                )
            out = False

        return out
Exemple #11
0
def generate_position_vector_func(In_frame, origin, point, dynamic_variables):
    ''' retuns the position of the point on reference_frame
     in inertial reference frame (In_frame) as a fucntion
     of dynamic_variables 
     '''
    # finding the vector of point  in respect to In_frame
    point_vector = point.pos_from(origin)
    point_vector_x = point_vector.dot(In_frame.x)
    point_vector_y = point_vector.dot(In_frame.y)

    # substituting dummy variables instead of dynamic_variables
    # couse there are funcitons of times and they couldn't be unpacked
    # like a normal sm.symbols as args for the funtions
    dummy_symbols = [sm.Dummy() for i in dynamic_variables]
    dummy_dict = dict(zip(dynamic_variables, dummy_symbols))

    point_vector_dummy = [
        point_vector_x.subs(dummy_dict),
        point_vector_y.subs(dummy_dict)
    ]

    # lamdify the point vector
    point_vector_func = [
        sm.lambdify(dummy_symbols, point_vector_component, modules='numpy')
        for point_vector_component in point_vector_dummy
    ]
    return point_vector_func
Exemple #12
0
def trig_substitution_rule(integral):
    integrand, symbol = integral
    A = sympy.Wild('a', exclude=[0, symbol])
    B = sympy.Wild('b', exclude=[0, symbol])
    theta = sympy.Dummy("theta")
    target_pattern = A + B*symbol**2

    matches = integrand.find(target_pattern)
    for expr in matches:
        match = expr.match(target_pattern)
        a = match.get(A, ZERO)
        b = match.get(B, ZERO)

        a_positive = ((a.is_number and a > 0) or a.is_positive)
        b_positive = ((b.is_number and b > 0) or b.is_positive)
        a_negative = ((a.is_number and a < 0) or a.is_negative)
        b_negative = ((b.is_number and b < 0) or b.is_negative)
        x_func = None
        if a_positive and b_positive:
            # a**2 + b*x**2. Assume sec(theta) > 0, -pi/2 < theta < pi/2
            x_func = (sympy.sqrt(a)/sympy.sqrt(b)) * sympy.tan(theta)
            # Do not restrict the domain: tan(theta) takes on any real
            # value on the interval -pi/2 < theta < pi/2 so x takes on
            # any value
            restriction = True
        elif a_positive and b_negative:
            # a**2 - b*x**2. Assume cos(theta) > 0, -pi/2 < theta < pi/2
            constant = sympy.sqrt(a)/sympy.sqrt(-b)
            x_func = constant * sympy.sin(theta)
            restriction = sympy.And(symbol > -constant, symbol < constant)
        elif a_negative and b_positive:
            # b*x**2 - a**2. Assume sin(theta) > 0, 0 < theta < pi
            constant = sympy.sqrt(-a)/sympy.sqrt(b)
            x_func = constant * sympy.sec(theta)
            restriction = sympy.And(symbol > -constant, symbol < constant)
        if x_func:
            # Manually simplify sqrt(trig(theta)**2) to trig(theta)
            # Valid due to assumed domain restriction
            substitutions = {}
            for f in [sympy.sin, sympy.cos, sympy.tan,
                      sympy.sec, sympy.csc, sympy.cot]:
                substitutions[sympy.sqrt(f(theta)**2)] = f(theta)
                substitutions[sympy.sqrt(f(theta)**(-2))] = 1/f(theta)

            replaced = integrand.subs(symbol, x_func).trigsimp()
            replaced = replaced.subs(substitutions)
            if not replaced.has(symbol):
                replaced *= manual_diff(x_func, theta)
                replaced = replaced.trigsimp()
                secants = replaced.find(1/sympy.cos(theta))
                if secants:
                    replaced = replaced.xreplace({
                        1/sympy.cos(theta): sympy.sec(theta)
                    })

                substep = integral_steps(replaced, theta)
                if not contains_dont_know(substep):
                    return TrigSubstitutionRule(
                        theta, x_func, replaced, substep, restriction,
                        integrand, symbol)
Exemple #13
0
 def test_renameDummyIndex(self):
     A=tensor.Tensor('A')
     B=tensor.Tensor('B')
     a=sympy.Dummy('a')
     b,c,d=sympy.symbols('b,c,d')
     exp = A(a,b,c)*B(b,c) - A(a,c,d)*B(c,d)
     self.assertEqual(renameDummyIndex(exp),0)
Exemple #14
0
 def __init__(self,
              dim,
              time_step=TypedSymbol("time_step", np.uint32),
              offsets=(0, 0, 0),
              keys=None):
     if keys is None:
         keys = (0, ) * self._num_keys
     if len(keys) != self._num_keys:
         raise ValueError("Provided {} keys but need {}".format(
             len(keys), self._num_keys))
     if len(offsets) != 3:
         raise ValueError("Provided {} offsets but need {}".format(
             len(offsets), 3))
     self.result_symbols = tuple(
         TypedSymbol(sp.Dummy().name, self._data_type)
         for _ in range(self._num_vars))
     symbols_read = [s for s in keys if isinstance(s, sp.Symbol)]
     super().__init__("",
                      symbols_read=symbols_read,
                      symbols_defined=self.result_symbols)
     self._time_step = time_step
     self._offsets = offsets
     self.headers = ['"{}_rand.h"'.format(self._name)]
     self.keys = tuple(keys)
     self._args = sp.sympify((dim, time_step, keys))
     self._dim = dim
Exemple #15
0
def callable_matrices(dynamic, eom, consts):
    """Take the equations of motion and make the mass matrix
    and forcing vector callable so we can simulate the system.

    Parameters
    ----------

    Returns
    -------


    """

    # dummy symbols used for dynamamic variables
    dyn_symbols = dynamic['q'] + dynamic['u']
    dummy_symbols = [sym.Dummy() for i in dyn_symbols]
    dummy_dict = dict(zip(dyn_symbols, dummy_symbols))

    # substitute dummy symbols into mass matrix and forcing vector
    kd_dict = eom['kane'].kindiffdict()                              # solved kinematical differential equations
    F = eom['forcing'].subs(kd_dict).subs(dummy_dict)      # substitute into the forcing vector
    M = eom['mass'].subs(kd_dict).subs(dummy_dict)  # substitute into the mass matrix

    # callable matrices
    F_func = sym.lambdify(consts['names'] + dummy_symbols, F)
    M_func = sym.lambdify(consts['names'] + dummy_symbols, M)

    # partially evaluate matrices to run faster (maybe 15% or so)
    ffunc = functools.partial(F_func, *consts['vals'])
    mfunc = functools.partial(M_func, *consts['vals'])

    return F_func, M_func, ffunc, mfunc, dummy_dict
Exemple #16
0
def test_attributes():
    x2 = eqpy.dummies.x2
    assert x2 is not sympy.Dummy('x2')
    assert raises(AttributeError, lambda: eqpy.dummies.__dunder_should_fail__)
    assert isinstance(x2, sympy.Dummy)
    ex2 = eqpy.dummies.x2
    assert x2 is not ex2
Exemple #17
0
    def make_inverse_trig(RuleClass, base_exp, a, sign_a, b, sign_b):
        u_var = sympy.Dummy("u")
        current_base = base
        current_symbol = symbol
        constant = u_func = u_constant = substep = None
        factored = integrand
        if a != 1:
            constant = a**base_exp
            current_base = sign_a + sign_b * (b / a) * current_symbol**2
            factored = current_base**base_exp
        if (b / a) != 1:
            u_func = sympy.sqrt(b / a) * symbol
            u_constant = sympy.sqrt(a / b)
            current_symbol = u_var
            current_base = sign_a + sign_b * current_symbol**2

        substep = RuleClass(current_base**base_exp, current_symbol)
        if u_func is not None:
            if u_constant != 1 and substep is not None:
                substep = ConstantTimesRule(
                    u_constant, current_base**base_exp, substep,
                    u_constant * current_base**base_exp, symbol)
            substep = URule(u_var, u_func, u_constant, substep, factored,
                            symbol)
        if constant is not None and substep is not None:
            substep = ConstantTimesRule(constant, factored, substep, integrand,
                                        symbol)
        return substep
Exemple #18
0
    def apply(self, m, b, evaluation):
        'LinearSolve[m_, b_]'

        matrix = matrix_data(m)
        if matrix is None:
            return
        if not b.has_form('List', None):
            return
        if len(b.leaves) != len(matrix):
            return evaluation.message('LinearSolve', 'lslc')
        system = [mm + [v] for mm, v in zip(matrix, b.leaves)]
        system = to_sympy_matrix(system)
        if system is None:
            return
        syms = [
            sympy.Dummy('LinearSolve_var%d' % k)
            for k in range(system.cols - 1)
        ]
        sol = sympy.solve_linear_system(system, *syms)
        if sol:
            # substitute 0 for variables that are not in result dictionary
            free_vars = dict(
                (sym, sympy.Integer(0)) for sym in syms if sym not in sol)
            sol.update(free_vars)
            sol = [(sol[sym] if sym in free_vars else sol[sym].subs(free_vars))
                   for sym in syms]
            return from_sympy(sol)
        else:
            return evaluation.message('LinearSolve', 'nosol')
Exemple #19
0
def root_mul_rule(integral):
    integrand, symbol = integral
    a = sympy.Wild('a', exclude=[symbol])
    b = sympy.Wild('b', exclude=[symbol])
    c = sympy.Wild('c')
    match = integrand.match(sympy.sqrt(a * symbol + b) * c)

    if not match:
        return

    a, b, c = match[a], match[b], match[c]
    d = sympy.Wild('d', exclude=[symbol])
    e = sympy.Wild('e', exclude=[symbol])
    f = sympy.Wild('f')
    recursion_test = c.match(sympy.sqrt(d * symbol + e) * f)
    if recursion_test:
        return

    u = sympy.Dummy('u')
    u_func = sympy.sqrt(a * symbol + b)
    integrand = integrand.subs(u_func, u)
    integrand = integrand.subs(symbol, (u**2 - b) / a)
    integrand = integrand * 2 * u / a
    next_step = integral_steps(integrand, u)
    if next_step:
        return URule(u, u_func, None, next_step, integrand, symbol)
Exemple #20
0
def makeExponentialFuncArgumentSquares(expr, variablesToCompleteSquares):
    """Completes squares in arguments of exponential which makes them simpler to integrate
    Very useful for integrating Maxwell-Boltzmann and its moment generating function"""
    expr = sp.simplify(expr)
    dim = len(variablesToCompleteSquares)
    dummies = [sp.Dummy() for i in range(dim)]

    def visit(term):
        if term.func == sp.exp:
            expArg = term.args[0]
            for i in range(dim):
                expArg, substitution = completeTheSquare(
                    expArg, variablesToCompleteSquares[i], dummies[i])
            return sp.exp(sp.expand(expArg))
        else:
            paramList = [visit(a) for a in term.args]
            if not paramList:
                return term
            else:
                return term.func(*paramList)

    result = visit(expr)
    for i in range(dim):
        result = result.subs(dummies[i], variablesToCompleteSquares[i])
    return result
Exemple #21
0
    def _baseobjective_from_callable(self, func, objective_type=MinimizeModel):
        """
        symfit works with BaseObjective subclasses internally. If a custom
        objective is provided, we wrap it into a BaseObjective, MinimizeModel by
        default.

        :param func: Callable. If already an instance of BaseObjective, it is
            returned immediately. If not, it is turned into a BaseObjective of
            type ``objective_type``.
        :param objective_type:
        :return:
        """
        if isinstance(func, BaseObjective) or (
                hasattr(func, '__self__')
                and isinstance(func.__self__, BaseObjective)):
            # The latter condition is added to make sure .eval_jacobian methods
            # are still considered correct, and not doubly wrapped.
            return func
        else:
            if isinstance(func, BaseModel):
                model = func
            else:
                # Minimize the provided custom objective instead. We therefore
                # wrap it into a CallableNumericalModel, thats what they are for
                y = sympy.Dummy()
                model = CallableNumericalModel(
                    {y: func}, connectivity_mapping={y: set(self.parameters)})
            return objective_type(model, data={})
Exemple #22
0
def compute_ab(f):
    c = sp.Dummy(positive=True)
    sqrt_f = sp.sqrt(f(c))
    max_sqrt_f = max(sqrt_f.subs(c, 0), sqrt_f.subs(c, sp.Rational(1, 2)),
                     sqrt_f.subs(c, 1))
    sqrt_int = sp.integrate(sqrt_f, (c, 0, 1))
    return max_sqrt_f / sqrt_int, 1 / (2 * max_sqrt_f * sqrt_int)
def _parts_rule(integrand, symbol):
    # LIATE rule:
    # log, inverse trig, algebraic (polynomial), trigonometric, exponential
    def pull_out_polys(integrand):
        integrand = integrand.together()
        polys = [arg for arg in integrand.args if arg.is_polynomial(symbol)]
        if polys:
            u = sympy.Mul(*polys)
            dv = integrand / u
            return u, dv

    def pull_out_u(*functions):
        def pull_out_u_rl(integrand):
            if any([integrand.has(f) for f in functions]):
                args = [
                    arg for arg in integrand.args if any(
                        isinstance(arg, cls) for cls in functions)
                ]
                if args:
                    u = reduce(lambda a, b: a * b, args)
                    dv = integrand / u
                    return u, dv

        return pull_out_u_rl

    liate_rules = [
        pull_out_u(sympy.log),
        pull_out_u(sympy.atan), pull_out_polys,
        pull_out_u(sympy.sin, sympy.cos),
        pull_out_u(sympy.exp)
    ]

    dummy = sympy.Dummy("temporary")
    # we can integrate log(x) and atan(x) by setting dv = 1
    if isinstance(integrand, sympy.log) or isinstance(integrand, sympy.atan):
        integrand = dummy * integrand

    for index, rule in enumerate(liate_rules):
        result = rule(integrand)

        if result:
            u, dv = result

            # Don't pick u to be a constant if possible
            if symbol not in u.free_symbols and not u.has(dummy):
                return

            u = u.subs(dummy, 1)
            dv = dv.subs(dummy, 1)

            for rule in liate_rules[index + 1:]:
                r = rule(integrand)
                # make sure dv is amenable to integration
                if r and r[0].subs(dummy, 1) == dv:
                    du = u.diff(symbol)
                    v_step = integral_steps(dv, symbol)
                    v = _manualintegrate(v_step)

                    return u, dv, v, du, v_step
Exemple #24
0
def substitution_rule(integral):
    integrand, symbol = integral

    u_var = sympy.Dummy("u")
    substitutions = find_substitutions(integrand, symbol, u_var)
    if substitutions:
        ways = []
        for u_func, c, substituted in substitutions:
            subrule = integral_steps(substituted, u_var)
            if contains_dont_know(subrule):
                continue

            if sympy.simplify(c - 1) != 0:
                _, denom = c.as_numer_denom()
                if subrule:
                    subrule = ConstantTimesRule(c, substituted, subrule, substituted, u_var)

                if denom.free_symbols:
                    piecewise = []
                    could_be_zero = []

                    if isinstance(denom, sympy.Mul):
                        could_be_zero = denom.args
                    else:
                        could_be_zero.append(denom)

                    for expr in could_be_zero:
                        if not fuzzy_not(expr.is_zero):
                            substep = integral_steps(integrand.subs(expr, 0), symbol)

                            if substep:
                                piecewise.append((
                                    substep,
                                    sympy.Eq(expr, 0)
                                ))
                    piecewise.append((subrule, True))
                    subrule = PiecewiseRule(piecewise, substituted, symbol)

            ways.append(URule(u_var, u_func, c,
                              subrule,
                              integrand, symbol))

        if len(ways) > 1:
            return AlternativeRule(ways, integrand, symbol)
        elif ways:
            return ways[0]

    elif integrand.has(sympy.exp):
        u_func = sympy.exp(symbol)
        c = 1
        substituted = integrand / u_func.diff(symbol)
        substituted = substituted.subs(u_func, u_var)

        if symbol not in substituted.free_symbols:
            return URule(u_var, u_func, c,
                         integral_steps(substituted, u_var),
                         integrand, symbol)
Exemple #25
0
def nc_coeffs(poly, var, max_deg=10, order='increasing'):
    """Returns a list of the coeffs w.r.t. var (expecting a monovariate polynomial)

    sympy.Poly can not handle non-commutative variables.
    This function mitigates that problem.

    :param poly:
    :param var:
    :param max_deg:     maximum degree to look for
    :param order:       increasing / decreasing

    :return: list of coeffs

    Caveat: This function expects all factors of `var` to be in one place.
    Terms like a*x*b*x**2 will not be handled correctly.
    """

    # TODO: elegant way to find out the degree
    # TODO: use nc_degree (after performance-testing)
    # workarround: pass the maximum expected degree as kwarg

    if poly == 0:
        return [sp.sympify(0)] * (max_deg + 1)

    D0 = sp.Dummy('D0')
    poly = sp.sympify(poly).expand() + D0  # ensure class add

    if not isinstance(poly, sp.Add):
        msg = "Expected sp.Add. Got %s" % type(poly)
        raise TypeError(msg)

    res = []
    # special case: 0-th power of var
    coeff = 0
    for a in poly.args:
        if not a.has(var):
            coeff += a
    res.append(coeff.subs(D0, 0))

    # special case: 1st power of var
    if max_deg >= 1:
        coeff = poly.diff(var).subs(var, 0)
        res.append(coeff)

    # powers > 1:
    for i in range(2, max_deg + 1):
        coeff = 0
        for a in poly.args:
            if a.has(var**(i)):
                term = a.subs(var, 1)
                coeff += term
        res.append(coeff)

    if order == "decreasing":
        res.reverse()

    return res
def exp_rule(derivative):
    expr, symbol = derivative
    exp = expr.args[0]
    if isinstance(exp, sympy.Symbol):
        return ExpRule(expr, sympy.E, expr, symbol)
    else:
        u = sympy.Dummy()
        f = sympy.exp(u)
        return ChainRule(ExpRule(f, sympy.E, f, u), exp, u,
                         diff_steps(exp, symbol), expr, symbol)
Exemple #27
0
    def __init__(self, value, error=0, symbol="x"):
        """

        :param value: Değer
        :param error: Belirsizlik (default=0)
        :param symbol: Sembol (default="x")
        """
        self.value = value
        self.error = abs(error)
        self.symbol = sp.Dummy(symbol)
        self.builder = Builder()
Exemple #28
0
 def cosine_law(lengths, angles, index):
     (c, a, b), gamma = lengths[index:] + lengths[:index], angles[index]
     x, find_angle = sympy.Dummy("x"), not bool(gamma)
     gamma, c = gamma or x, c or x
     equation = sympy.Eq(c ** 2, a ** 2 + b ** 2 - 2 * a * b * sympy.cos(gamma))
     domain = sympy.Interval.open(0, sympy.pi if find_angle else sympy.oo)
     sol = [x for x in sympy.solve(equation) if x in domain]
     if not sol:
         raise ValueError(
             "The lengths and angles must satisfy the law of cosines"
         )
     locals()["angles" if find_angle else "lengths"][index] = sol[0]
def log_rule(derivative):
    expr, symbol = derivative
    arg = expr.args[0]
    if len(expr.args) == 2:
        base = expr.args[1]
    else:
        base = sympy.E
        if isinstance(arg, sympy.Symbol):
            return LogRule(arg, base, expr, symbol)
        else:
            u = sympy.Dummy()
            return ChainRule(LogRule(u, base, sympy.log(u, base), u), arg, u,
                             diff_steps(arg, symbol), expr, symbol)
Exemple #30
0
def _construct_symbolic_lyapunov_solution_matrix(dim):
    numEquations = dim * (dim + 1) / 2
    X = np.zeros((dim, dim))

    counter = itertools.count()

    for k in xrange(dim):
        next_symbols = [
            sympy.Dummy('x%d' % counter.next()) for i in range(dim - k)
        ]
        X = X + np.diag(next_symbols, k)
        if k > 0: X = X + np.diag(next_symbols, -k)
    return X