Ejemplo n.º 1
0
Archivo: power.py Proyecto: ENuge/sympy
    def as_real_imag(self, deep=True, **hints):
        from sympy.core.symbol import symbols
        from sympy.polys.polytools import poly
        from sympy.core.function import expand_multinomial
        if self.exp.is_Integer:
            exp = self.exp
            re, im = self.base.as_real_imag(deep=deep)
            if re.func == C.re or im.func == C.im:
                return self, S.Zero
            a, b = symbols('a b', cls=Dummy)
            if exp >= 0:
                if re.is_Number and im.is_Number:
                    # We can be more efficient in this case
                    expr = expand_multinomial(self.base**exp)
                    return expr.as_real_imag()

                expr = poly((a + b)**exp) # a = re, b = im; expr = (a + b*I)**exp
            else:
                mag = re**2 + im**2
                re, im = re/mag, -im/mag
                if re.is_Number and im.is_Number:
                    # We can be more efficient in this case
                    expr = expand_multinomial((re + im*S.ImaginaryUnit)**-exp)
                    return expr.as_real_imag()

                expr = poly((a + b)**-exp)

            # Terms with even b powers will be real
            r = [i for i in expr.terms() if not i[0][1] % 2]
            re_part = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])
            # Terms with odd b powers will be imaginary
            r = [i for i in expr.terms() if i[0][1] % 4 == 1]
            im_part1 = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])
            r = [i for i in expr.terms() if i[0][1] % 4 == 3]
            im_part3 = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])

            return (re_part.subs({a: re, b: S.ImaginaryUnit*im}),
            im_part1.subs({a: re, b: im}) + im_part3.subs({a: re, b: -im}))

        elif self.exp.is_Rational:
            # NOTE: This is not totally correct since for x**(p/q) with
            #       x being imaginary there are actually q roots, but
            #       only a single one is returned from here.
            re, im = self.base.as_real_imag(deep=deep)
            if re.func == C.re or im.func == C.im:
                return self, S.Zero
            r = Pow(Pow(re, 2) + Pow(im, 2), S.Half)
            t = C.atan2(im, re)

            rp, tp = Pow(r, self.exp), t*self.exp

            return (rp*C.cos(tp), rp*C.sin(tp))
        else:

            if deep:
                hints['complex'] = False
                return (C.re(self.expand(deep, **hints)),
                        C.im(self.expand(deep, **hints)))
            else:
                return (C.re(self), C.im(self))
Ejemplo n.º 2
0
    def expectation(self, expr, var, evaluate=True, **kwargs):
        """ Expectation of expression over distribution """
        # TODO: support discrete sets with non integer stepsizes

        if evaluate:
            try:
                p = poly(expr, var)

                t = Dummy('t', real=True)

                mgf = self.moment_generating_function(t)
                deg = p.degree()
                taylor = poly(series(mgf, t, 0, deg + 1).removeO(), t)
                result = 0
                for k in range(deg + 1):
                    result += p.coeff_monomial(var**k) * taylor.coeff_monomial(
                        t**k) * factorial(k)

                return result

            except PolynomialError:
                return summation(expr * self.pdf(var),
                                 (var, self.set.inf, self.set.sup), **kwargs)

        else:
            return Sum(expr * self.pdf(var), (var, self.set.inf, self.set.sup),
                       **kwargs)
Ejemplo n.º 3
0
    def as_real_imag(self, deep=True, **hints):
        from sympy.core.symbol import symbols
        from sympy.polys.polytools import poly
        from sympy.core.function import expand_multinomial
        if self.exp.is_Integer:
            exp = self.exp
            re, im = self.base.as_real_imag(deep=deep)
            a, b = symbols('a b', cls=Dummy)
            if exp >= 0:
                if re.is_Number and im.is_Number:
                    # We can be more efficient in this case
                    expr = expand_multinomial(self.base**exp)
                    return expr.as_real_imag()

                expr = poly((a + b)**exp) # a = re, b = im; expr = (a + b*I)**exp
            else:
                mag = re**2 + im**2
                re, im = re/mag, -im/mag
                if re.is_Number and im.is_Number:
                    # We can be more efficient in this case
                    expr = expand_multinomial((re + im*S.ImaginaryUnit)**-exp)
                    return expr.as_real_imag()

                expr = poly((a + b)**-exp)

            # Terms with even b powers will be real
            r = [i for i in expr.terms() if not i[0][1] % 2]
            re_part = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])
            # Terms with odd b powers will be imaginary
            r = [i for i in expr.terms() if i[0][1] % 4 == 1]
            im_part1 = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])
            r = [i for i in expr.terms() if i[0][1] % 4 == 3]
            im_part3 = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])

            return (re_part.subs({a: re, b: S.ImaginaryUnit*im}),
            im_part1.subs({a: re, b: im}) + im_part3.subs({a: re, b: -im}))

        elif self.exp.is_Rational:
            # NOTE: This is not totally correct since for x**(p/q) with
            #       x being imaginary there are actually q roots, but
            #       only a single one is returned from here.
            re, im = self.base.as_real_imag(deep=deep)

            r = Pow(Pow(re, 2) + Pow(im, 2), S.Half)
            t = C.atan2(im, re)

            rp, tp = Pow(r, self.exp), t*self.exp

            return (rp*C.cos(tp), rp*C.sin(tp))
        else:

            if deep:
                hints['complex'] = False
                return (C.re(self.expand(deep, complex=False)),
                C.im(self. expand(deep, **hints)))
            else:
                return (C.re(self), C.im(self))
Ejemplo n.º 4
0
 def expectation(self, expr, var, evaluate=True, **kwargs):
     """ Expectation of expression over distribution """
     if evaluate:
         try:
             p = poly(expr, var)
             if p.is_zero:
                 return S.Zero
             t = Dummy('t', real=True)
             mgf = self._moment_generating_function(t)
             if mgf is None:
                 return integrate(expr * self.pdf(var), (var, self.set), **kwargs)
             deg = p.degree()
             taylor = poly(series(mgf, t, 0, deg + 1).removeO(), t)
             result = 0
             for k in range(deg+1):
                 result += p.coeff_monomial(var ** k) * taylor.coeff_monomial(t ** k) * factorial(k)
             return result
         except PolynomialError:
             return integrate(expr * self.pdf(var), (var, self.set), **kwargs)
     else:
         return Integral(expr * self.pdf(var), (var, self.set), **kwargs)
Ejemplo n.º 5
0
 c=symbols('c0:%d'%(Lamda.rows*Lamda.cols))
 C=Matrix(Lamda.rows,Lamda.cols,c)
 #-----------------------------------------
 
 RHS_matrix=Lamda*sI_A +C                            #right hand side of the equation (1)
  
 '''
 -----------Converting equation (1) to a system of linear -----------
 -----------equations, comparing the coefficients of the  -----------
 -----------polynomials in both sides of the equation (1) -----------
 '''
  EQ=[Eq(LHS_matrix[i,j],expand(RHS_matrix[i,j])) for i,j in product(range(LHS_matrix.rows),range(LHS_matrix.cols)) ]
 eq=[]
 
 for equation in EQ:
     RHS=poly((equation).rhs,s).all_coeffs() #simplify necessary ?
     LHS=poly((equation).lhs,s).all_coeffs()
     if len(RHS)>len(LHS):                      # we add zero for each missing coefficient (greater than  the degree of LHS)
         LHS=(len(RHS)-len(LHS))*[0] + LHS
     eq=eq+[Eq(LHS[i],RHS[i]) for i in range(len(RHS))]
 
 SOL=solve(eq,a+c)   # the coefficients of Λ and C
 
 
 #----------substitute the solution in the matrices----------------
 C=C.subs(SOL)     #substitute(SOL)
 Lamda=Lamda.subs(SOL)    #substitute(SOL)
 Js=(Ds+Cs*Ys+Lamda*(B0));
 # for output compatibility
 E=eye(A0.cols)
 if do_test==True:
Ejemplo n.º 6
0
    def _eval_simplify(self, **kwargs):
        from .add import Add
        from .expr import Expr
        r = self
        r = r.func(*[i.simplify(**kwargs) for i in r.args])
        if r.is_Relational:
            if not isinstance(r.lhs, Expr) or not isinstance(r.rhs, Expr):
                return r
            dif = r.lhs - r.rhs
            # replace dif with a valid Number that will
            # allow a definitive comparison with 0
            v = None
            if dif.is_comparable:
                v = dif.n(2)
            elif dif.equals(0):  # XXX this is expensive
                v = S.Zero
            if v is not None:
                r = r.func._eval_relation(v, S.Zero)
            r = r.canonical
            # If there is only one symbol in the expression,
            # try to write it on a simplified form
            free = list(
                filter(lambda x: x.is_real is not False, r.free_symbols))
            if len(free) == 1:
                try:
                    from sympy.solvers.solveset import linear_coeffs
                    x = free.pop()
                    dif = r.lhs - r.rhs
                    m, b = linear_coeffs(dif, x)
                    if m.is_zero is False:
                        if m.is_negative:
                            # Dividing with a negative number, so change order of arguments
                            # canonical will put the symbol back on the lhs later
                            r = r.func(-b / m, x)
                        else:
                            r = r.func(x, -b / m)
                    else:
                        r = r.func(b, S.Zero)
                except ValueError:
                    # maybe not a linear function, try polynomial
                    from sympy.polys.polyerrors import PolynomialError
                    from sympy.polys.polytools import gcd, Poly, poly
                    try:
                        p = poly(dif, x)
                        c = p.all_coeffs()
                        constant = c[-1]
                        c[-1] = 0
                        scale = gcd(c)
                        c = [ctmp / scale for ctmp in c]
                        r = r.func(
                            Poly.from_list(c, x).as_expr(), -constant / scale)
                    except PolynomialError:
                        pass
            elif len(free) >= 2:
                try:
                    from sympy.solvers.solveset import linear_coeffs
                    from sympy.polys.polytools import gcd
                    free = list(ordered(free))
                    dif = r.lhs - r.rhs
                    m = linear_coeffs(dif, *free)
                    constant = m[-1]
                    del m[-1]
                    scale = gcd(m)
                    m = [mtmp / scale for mtmp in m]
                    nzm = list(filter(lambda f: f[0] != 0, list(zip(m, free))))
                    if scale.is_zero is False:
                        if constant != 0:
                            # lhs: expression, rhs: constant
                            newexpr = Add(*[i * j for i, j in nzm])
                            r = r.func(newexpr, -constant / scale)
                        else:
                            # keep first term on lhs
                            lhsterm = nzm[0][0] * nzm[0][1]
                            del nzm[0]
                            newexpr = Add(*[i * j for i, j in nzm])
                            r = r.func(lhsterm, -newexpr)

                    else:
                        r = r.func(constant, S.Zero)
                except ValueError:
                    pass
        # Did we get a simplified result?
        r = r.canonical
        measure = kwargs['measure']
        if measure(r) < kwargs['ratio'] * measure(self):
            return r
        else:
            return self