def _eval_expand_complex(self, *args): if self.args[0].is_real: return self re, im = self.args[0].as_real_imag() denom = sinh(re)**2 + C.cos(im)**2 return (sinh(re)*cosh(re) + \ S.ImaginaryUnit*C.sin(im)*C.cos(im))/denom
def solve_ODE_second_order(eq, f): """ solves many kinds of second order odes, different methods are used depending on the form of the given equation. Now the constanst coefficients case and a special case are implemented. """ x = f.args[0] f = f.func #constant coefficients case: af''(x)+bf'(x)+cf(x)=0 a = Wild('a', exclude=[x]) b = Wild('b', exclude=[x]) c = Wild('c', exclude=[x]) r = eq.match(a * f(x).diff(x, x) + c * f(x)) if r: return Symbol("C1") * C.sin(sqrt( r[c] / r[a]) * x) + Symbol("C2") * C.cos(sqrt(r[c] / r[a]) * x) r = eq.match(a * f(x).diff(x, x) + b * diff(f(x), x) + c * f(x)) if r: r1 = solve(r[a] * x**2 + r[b] * x + r[c], x) if r1[0].is_real: if len(r1) == 1: return (Symbol("C1") + Symbol("C2") * x) * exp(r1[0] * x) else: return Symbol("C1") * exp(r1[0] * x) + Symbol("C2") * exp( r1[1] * x) else: r2 = abs((r1[0] - r1[1]) / (2 * S.ImaginaryUnit)) return (Symbol("C2") * C.cos(r2 * x) + Symbol("C1") * C.sin(r2 * x)) * exp( (r1[0] + r1[1]) * x / 2) #other cases of the second order odes will be implemented here #special equations, that we know how to solve t = x * C.exp(f(x)) tt = a * t.diff(x, x) / t r = eq.match(tt.expand()) if r: return -solve_ODE_1(f(x), x) t = x * C.exp(-f(x)) tt = a * t.diff(x, x) / t r = eq.match(tt.expand()) if r: #check, that we've rewritten the equation correctly: #assert ( r[a]*t.diff(x,2)/t ) == eq.subs(f, t) return solve_ODE_1(f(x), x) neq = eq * C.exp(f(x)) / C.exp(-f(x)) r = neq.match(tt.expand()) if r: #check, that we've rewritten the equation correctly: #assert ( t.diff(x,2)*r[a]/t ).expand() == eq return solve_ODE_1(f(x), x) raise NotImplementedError("solve_ODE_second_order: cannot solve " + str(eq))
def _eval_expand_complex(self, *args): if self.args[0].is_real: return self re, im = self.args[0].as_real_imag() denom = sinh(re)**2 + C.cos(im)**2 return (sinh(re)*cosh(re) + \ S.ImaginaryUnit*C.sin(im)*C.cos(im))/denom
def as_real_imag(self, deep=True, **hints): # TODO: Handle deep and hints n, m, theta, phi = self.args re = (sqrt((2*n + 1)/(4*pi) * C.factorial(n - m)/C.factorial(n + m)) * C.cos(m*phi) * assoc_legendre(n, m, C.cos(theta))) im = (sqrt((2*n + 1)/(4*pi) * C.factorial(n - m)/C.factorial(n + m)) * C.sin(m*phi) * assoc_legendre(n, m, C.cos(theta))) return (re, im)
def solve_ODE_second_order(eq, f): """ solves many kinds of second order odes, different methods are used depending on the form of the given equation. So far the constants coefficients case and a special case are implemented. """ x = f.args[0] f = f.func #constant coefficients case: af''(x)+bf'(x)+cf(x)=0 a = Wild('a', exclude=[x]) b = Wild('b', exclude=[x]) c = Wild('c', exclude=[x]) r = eq.match(a*f(x).diff(x,x) + c*f(x)) if r: return Symbol("C1")*C.sin(sqrt(r[c]/r[a])*x)+Symbol("C2")*C.cos(sqrt(r[c]/r[a])*x) r = eq.match(a*f(x).diff(x,x) + b*diff(f(x),x) + c*f(x)) if r: r1 = solve(r[a]*x**2 + r[b]*x + r[c], x) if r1[0].is_real: if len(r1) == 1: return (Symbol("C1") + Symbol("C2")*x)*exp(r1[0]*x) else: return Symbol("C1")*exp(r1[0]*x) + Symbol("C2")*exp(r1[1]*x) else: r2 = abs((r1[0] - r1[1])/(2*S.ImaginaryUnit)) return (Symbol("C2")*C.cos(r2*x) + Symbol("C1")*C.sin(r2*x))*exp((r1[0] + r1[1])*x/2) #other cases of the second order odes will be implemented here #special equations, that we know how to solve a = Wild('a') t = x*exp(f(x)) tt = a*t.diff(x, x)/t r = eq.match(tt.expand()) if r: return -solve_ODE_1(f(x), x) t = x*exp(-f(x)) tt = a*t.diff(x, x)/t r = eq.match(tt.expand()) if r: #check, that we've rewritten the equation correctly: #assert ( r[a]*t.diff(x,2)/t ) == eq.subs(f, t) return solve_ODE_1(f(x), x) neq = eq*exp(f(x))/exp(-f(x)) r = neq.match(tt.expand()) if r: #check, that we've rewritten the equation correctly: #assert ( t.diff(x,2)*r[a]/t ).expand() == eq return solve_ODE_1(f(x), x) raise NotImplementedError("solve_ODE_second_order: cannot solve " + str(eq))
def as_real_imag(self, deep=True, **hints): if self.args[0].is_real: if deep: hints["complex"] = False return (self.expand(deep, **hints), S.Zero) else: return (self, S.Zero) if deep: re, im = self.args[0].expand(deep, **hints).as_real_imag() else: re, im = self.args[0].as_real_imag() denom = sinh(re) ** 2 + C.cos(im) ** 2 return (sinh(re) * cosh(re) / denom, C.sin(im) * C.cos(im) / denom)
def _eval_expand_complex(self, deep=True, **hints): if self.args[0].is_real: if deep: hints['complex'] = False return self.expand(deep, **hints) else: return self if deep: re, im = self.args[0].expand(deep, **hints).as_real_imag() else: re, im = self.args[0].as_real_imag() denom = sinh(re)**2 + C.cos(im)**2 return (sinh(re)*cosh(re) + \ S.ImaginaryUnit*C.sin(im)*C.cos(im))/denom
def _eval_expand_complex(self, deep=True, **hints): if self.args[0].is_real: if deep: hints['complex'] = False return self.expand(deep, **hints) else: return self if deep: re, im = self.args[0].expand(deep, **hints).as_real_imag() else: re, im = self.args[0].as_real_imag() denom = sinh(re)**2 + C.cos(im)**2 return (sinh(re)*cosh(re) + \ S.ImaginaryUnit*C.sin(im)*C.cos(im))/denom
def _eval_expand_complex(self, deep=True, **hints): re, im = self.args[0].as_real_imag() if deep: re = re.expand(deep, **hints) im = im.expand(deep, **hints) cos, sin = C.cos(im), C.sin(im) return exp(re) * cos + S.ImaginaryUnit * exp(re) * sin
def eval(cls, arg): arg = sympify(arg) if arg.is_Number: if arg is S.NaN: return S.NaN elif arg is S.Infinity: return S.Infinity elif arg is S.NegativeInfinity: return S.Infinity elif arg is S.Zero: return S.One elif arg.is_negative: return cls(-arg) else: i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return C.cos(i_coeff) else: coeff, terms = arg.as_coeff_terms() if coeff.is_negative: return cls(-arg) if isinstance(arg, asinh): return sqrt(1 + arg.args[0]**2) if isinstance(arg, acosh): return arg.args[0] if isinstance(arg, atanh): return 1 / sqrt(1 - arg.args[0]**2)
def apothem(self): """ Returns the apothem/inradius of the regular polygon (i.e., the radius of the inscribed circle). """ n = self.__getitem__(2) return self.radius * C.cos(S.Pi/n)
def eval(cls, n, x): if not n.is_Number: # Symbolic result U_n(x) # U_n(-x) ---> (-1)**n * U_n(x) if x.could_extract_minus_sign(): return S.NegativeOne**n * chebyshevu(n, -x) # U_{-n}(x) ---> -U_{n-2}(x) if n.could_extract_minus_sign(): if n == S.NegativeOne: return S.Zero else: return -chebyshevu(-n - 2, x) # We can evaluate for some special values of x if x == S.Zero: return C.cos(S.Half * S.Pi * n) if x == S.One: return S.One + n elif x == S.Infinity: return S.Infinity else: # n is a given fixed integer, evaluate into polynomial if n.is_negative: # U_{-n}(x) ---> -U_{n-2}(x) if n == S.NegativeOne: return S.Zero else: return -cls._eval_at_order(-n - 2, x) else: return cls._eval_at_order(n, x)
def eval(cls, arg): arg = sympify(arg) if arg.is_Number: if arg is S.NaN: return S.NaN elif arg is S.Infinity: return S.Infinity elif arg is S.NegativeInfinity: return S.Infinity elif arg is S.Zero: return S.One elif arg.is_negative: return cls(-arg) else: i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return C.cos(i_coeff) else: coeff, terms = arg.as_coeff_terms() if coeff.is_negative: return cls(-arg) if arg.func == asinh: return sqrt(1 + arg.args[0] ** 2) if arg.func == acosh: return arg.args[0] if arg.func == atanh: return 1 / sqrt(1 - arg.args[0] ** 2)
def eval(cls, n, x): if not n.is_Number: # Symbolic result U_n(x) # U_n(-x) ---> (-1)**n * U_n(x) if x.could_extract_minus_sign(): return S.NegativeOne**n * chebyshevu(n, -x) # U_{-n}(x) ---> -U_{n-2}(x) if n.could_extract_minus_sign(): if n == S.NegativeOne: return S.Zero else: return -chebyshevu(-n - 2, x) # We can evaluate for some special values of x if x == S.Zero: return C.cos(S.Half * S.Pi * n) if x == S.One: return S.One + n elif x == S.Infinity: return S.Infinity else: # n is a given fixed integer, evaluate into polynomial if n.is_negative: # U_{-n}(x) ---> -U_{n-2}(x) if n == S.NegativeOne: return S.Zero else: return -cls._eval_at_order(-n - 2, x) else: return cls._eval_at_order(n, x)
def _eval_expand_complex(self, deep=True, **hints): re, im = self.args[0].as_real_imag() if deep: re = re.expand(deep, **hints) im = im.expand(deep, **hints) cos, sin = C.cos(im), C.sin(im) return exp(re) * cos + S.ImaginaryUnit * exp(re) * sin
def _eval_expand_func(self, **hints): n, m, theta, phi = self.args rv = (sqrt( (2 * n + 1) / (4 * pi) * C.factorial(n - m) / C.factorial(n + m)) * C.exp(I * m * phi) * assoc_legendre(n, m, C.cos(theta))) # We can do this because of the range of theta return rv.subs(sqrt(-cos(theta)**2 + 1), sin(theta))
def vertices(self): points = [] c, r, n = self v = 2*S.Pi/n for k in xrange(0, n): points.append( Point(c[0] + r*C.cos(k*v), c[1] + r*C.sin(k*v)) ) return points
def _eval_expand_func(self, **hints): n, m, theta, phi = self.args rv = ( sqrt((2 * n + 1) / (4 * pi) * C.factorial(n - m) / C.factorial(n + m)) * C.exp(I * m * phi) * assoc_legendre(n, m, C.cos(theta)) ) # We can do this because of the range of theta return rv.subs(sqrt(-cos(theta) ** 2 + 1), sin(theta))
def arbitrary_point(self, parameter_name='t'): """Returns a symbolic point that is on the ellipse.""" t = C.Symbol(parameter_name, real=True) return Point(self.center[0] + self.hradius * C.cos(t), self.center[1] + self.vradius * C.sin(t))
def eval(cls, n, k): if not 0 <= k < n: raise ValueError("must have 0 <= k < n") return C.cos(S.Pi*(k+1)/(n+1))
def eval(cls, n, k): if not 0 <= k < n: raise ValueError("must have 0 <= k < n") return C.cos(S.Pi * (k + 1) / (n + 1))
def canonize(cls, n, k): if not 0 <= k < n: raise ValueError("must have 0 <= k < n") return C.cos(S.Pi * (2 * k + 1) / (2 * n))
def _eval_expand_func(self, **hints): n, m, theta, phi = self.args return (sqrt((2*n + 1)/(4*pi) * C.factorial(n - m)/C.factorial(n + m)) * C.exp(I*m*phi) * assoc_legendre(n, m, C.cos(theta)))
def _eval_expand_complex(self, *args): if self.args[0].is_real: return self re, im = self.args[0].as_real_imag() return sinh(re)*C.cos(im) + cosh(re)*C.sin(im)*S.ImaginaryUnit
def _eval_expand_complex(self, *args): if self.args[0].is_real: return self re, im = self.args[0].as_real_imag() return sinh(re) * C.cos(im) + cosh(re) * C.sin(im) * S.ImaginaryUnit
def eval(cls, n, k): if not ((0 <= k) and (k < n)): raise ValueError("must have 0 <= k < n, " "got k = %s and n = %s" % (k, n)) return C.cos(S.Pi*(2*k + 1)/(2*n))
def eval(cls, n, k): if not ((0 <= k) and (k < n)): raise ValueError("must have 0 <= k < n, " "got k = %s and n = %s" % (k, n)) return C.cos(S.Pi * (2 * k + 1) / (2 * n))
def _eval_rewrite_as_cos(self, arg): I = S.ImaginaryUnit return C.cos(I*arg) + I*C.cos(I*arg+S.Pi/2)
def _eval_expand_complex(self, *args): re, im = self.args[0].as_real_imag() cos, sin = C.cos(im), C.sin(im) return exp(re) * cos + S.ImaginaryUnit * exp(re) * sin
def eval(cls, n, k): if not ((0 <= k) is (k < n) is True): raise ValueError("must have 0 <= k < n, " "got k = %s and n = %s" % (k, n)) return C.cos(S.Pi*(k + 1)/(n + 1))
def eval(cls, n, k): if not ((0 <= k) is (k < n) is True): raise ValueError("must have 0 <= k < n, " "got k = %s and n = %s" % (k, n)) return C.cos(S.Pi * (k + 1) / (n + 1))
def canonize(cls, n, k): if not 0 <= k < n: raise ValueError("must have 0 <= k < n") return C.cos(S.Pi*(2*k+1)/(2*n))
def _eval_expand_func(self, **hints): n, m, theta, phi = self.args return (sqrt( (2 * n + 1) / (4 * pi) * C.factorial(n - m) / C.factorial(n + m)) * C.exp(I * m * phi) * assoc_legendre(n, m, C.cos(theta)))
def _eval_expand_complex(self, *args): re, im = self.args[0].as_real_imag() cos, sin = C.cos(im), C.sin(im) return exp(re) * cos + S.ImaginaryUnit * exp(re) * sin
def arbitrary_point(self, parameter_name='t'): """Returns a symbolic point that is on the ellipse.""" t = C.Symbol(parameter_name, real=True) return Point( self.center[0] + self.hradius*C.cos(t), self.center[1] + self.vradius*C.sin(t))
def _eval_rewrite_as_cos(self, arg): I = S.ImaginaryUnit return C.cos(I*arg) + I*C.cos(I*arg+S.Pi/2)