def _eval_expand_complex(self, *args): if self.args[0].is_real: return self re, im = self.args[0].as_real_imag() denom = sin(re)**2 + C.sinh(im)**2 return (sin(re)*cos(re) - \ S.ImaginaryUnit*C.sinh(im)*C.cosh(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() return sin(re) * C.cosh(im) + S.ImaginaryUnit * cos(re) * C.sinh(im)
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() return sin(re)*C.cosh(im) + S.ImaginaryUnit*cos(re)*C.sinh(im)
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() return (cos(re) * C.cosh(im), -sin(re) * C.sinh(im))
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() return (cos(re)*C.cosh(im), -sin(re)*C.sinh(im))
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 = cos(re) ** 2 + C.sinh(im) ** 2 return (sin(re) * cos(re) / denom, C.sinh(im) * C.cosh(im) / denom)
def eval(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN 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.cosh(i_coeff) else: pi_coeff = arg.as_coefficient(S.Pi) if pi_coeff is not None: if pi_coeff.is_Rational: cst_table_some = { 1: S.One, 2: S.Zero, 3: S.Half, 4: S.Half * sqrt(2), 6: S.Half * sqrt(3), } cst_table_more = { (1, 5): (sqrt(5) + 1) / 4, (2, 5): (sqrt(5) - 1) / 4 } p = pi_coeff.p q = pi_coeff.q Q, P = 2 * p // q, p % q try: result = cst_table_some[q] except KeyError: if abs(P) > q // 2: P = q - P try: result = cst_table_more[(P, q)] except KeyError: if P != p: result = cls(C.Rational(P, q) * S.Pi) else: return None if Q % 4 in (1, 2): return -result else: return result if arg.is_Mul and arg.args[0].is_negative: return cls(-arg) if arg.is_Add: x, m = arg.as_independent(S.Pi) if m in [S.Pi / 2, S.Pi]: return cos(m) * cos(x) - sin(m) * sin(x) # normalize cos(-x-y) to cos(x+y) if arg.args[0].is_Mul: if arg.args[0].args[0].is_negative: # e.g. arg = -x - y if (-arg).args[0].is_Mul: if (-arg).args[0].args[0].is_negative: # This is to prevent infinite recursion in # the case cos(-x+y), for which # -arg = -y + x. See also #838 for the # root of the problem here. return # convert cos(-x-y) to cos(x+y) return cls(-arg) if arg.args[0].is_negative: if (-arg).args[0].is_negative: # This is to avoid infinite recursion in the case # sin(-x-1) return return cls(-arg) if isinstance(arg, acos): return arg.args[0] if isinstance(arg, atan): x = arg.args[0] return 1 / sqrt(1 + x**2) if isinstance(arg, asin): x = arg.args[0] return sqrt(1 - x**2) if isinstance(arg, acot): x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)
def eval(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN elif arg is S.Zero: return S.One elif arg is S.Infinity or arg is S.NegativeInfinity: # In this cases, it is unclear if we should # return S.NaN or leave un-evaluated. One # useful test case is how "limit(sin(x)/x,x,oo)" # is handled. # See test_sin_cos_with_infinity() an # Test for issue 209 # http://code.google.com/p/sympy/issues/detail?id=2097 # For now, we return un-evaluated. return if arg.could_extract_minus_sign(): return cls(-arg) i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return C.cosh(i_coeff) pi_coeff = _pi_coeff(arg) if pi_coeff is not None: if pi_coeff.is_integer: return (S.NegativeOne)**pi_coeff if not pi_coeff.is_Rational: narg = pi_coeff*S.Pi if narg != arg: return cls(narg) return None # cosine formula ##################### # http://code.google.com/p/sympy/issues/detail?id=2949 # explicit calculations are preformed for # cos(k pi / 8), cos(k pi /10), and cos(k pi / 12) # Some other exact values like cos(k pi/15) can be # calculated using a partial-fraction decomposition # by calling cos( X ).rewrite(sqrt) cst_table_some = { 3: S.Half, 5: (sqrt(5) + 1)/4, } if pi_coeff.is_Rational: q = pi_coeff.q p = pi_coeff.p % (2*q) if p > q: narg = (pi_coeff - 1)*S.Pi return -cls(narg) if 2*p > q: narg = (1 - pi_coeff)*S.Pi return -cls(narg) # If nested sqrt's are worse than un-evaluation # you can require q in (1, 2, 3, 4, 6) # q <= 12 returns expressions with 2 or fewer nestings. if q > 12: return None if q in cst_table_some: cts = cst_table_some[pi_coeff.q] return C.chebyshevt(pi_coeff.p, cts).expand() if 0 == q % 2: narg = (pi_coeff*2)*S.Pi nval = cls(narg) if None == nval: return None x = (2*pi_coeff + 1)/2 sign_cos = (-1)**((-1 if x < 0 else 1)*int(abs(x))) return sign_cos*sqrt( (1 + nval)/2 ) return None if arg.is_Add: x, m = _peeloff_pi(arg) if m: return cos(m)*cos(x) - sin(m)*sin(x) if arg.func is acos: return arg.args[0] if arg.func is atan: x = arg.args[0] return 1 / sqrt(1 + x**2) if arg.func is atan2: y, x = arg.args return x / sqrt(x**2 + y**2) if arg.func is asin: x = arg.args[0] return sqrt(1 - x ** 2) if arg.func is acot: x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)
def eval(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN elif arg is S.Zero: return S.One elif arg is S.Infinity: return if arg.could_extract_minus_sign(): return cls(-arg) i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return C.cosh(i_coeff) pi_coeff = _pi_coeff(arg) if pi_coeff is not None: if not pi_coeff.is_Rational: if pi_coeff.is_integer: return (S.NegativeOne)**pi_coeff narg = pi_coeff*S.Pi if narg != arg: return cls(narg) return None cst_table_some = { 1 : S.One, 2 : S.Zero, 3 : S.Half, 4 : S.Half*sqrt(2), 6 : S.Half*sqrt(3), } cst_table_more = { (1, 5) : (sqrt(5) + 1)/4, (2, 5) : (sqrt(5) - 1)/4 } p = pi_coeff.p q = pi_coeff.q Q, P = 2*p // q, p % q try: result = cst_table_some[q] except KeyError: if abs(P) > q // 2: P = q - P try: result = cst_table_more[(P, q)] except KeyError: if P != p: result = cls(C.Rational(P, q)*S.Pi) else: return None if Q % 4 in (1, 2): return -result else: return result if arg.is_Add: x, m = _peeloff_pi(arg) if m: return cos(m)*cos(x)-sin(m)*sin(x) if arg.func is acos: return arg.args[0] if arg.func is atan: x = arg.args[0] return 1 / sqrt(1 + x**2) if arg.func is asin: x = arg.args[0] return sqrt(1 - x ** 2) if arg.func is acot: x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)
def canonize(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN 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.cosh(i_coeff) else: pi_coeff = arg.as_coefficient(S.Pi) if pi_coeff is not None: if pi_coeff.is_Rational: cst_table = { 1 : S.One, 2 : S.Zero, 3 : S.Half, 4 : S.Half*sqrt(2), 6 : S.Half*sqrt(3), } try: result = cst_table[pi_coeff.q] if (2*pi_coeff.p // pi_coeff.q) % 4 in (1, 2): return -result else: return result except KeyError: pass if arg.is_Mul and arg.args[0].is_negative: return cls(-arg) if arg.is_Add: x, m = arg.as_independent(S.Pi) if m in [S.Pi/2, S.Pi]: return cos(m)*cos(x)-sin(m)*sin(x) # normalize cos(-x-y) to cos(x+y) if arg.args[0].is_Mul: if arg.args[0].args[0].is_negative: # e.g. arg = -x - y if (-arg).args[0].is_Mul: if (-arg).args[0].args[0].is_negative: # This is to prevent infinite recursion in # the case cos(-x+y), for which # -arg = -y + x. See also #838 for the # root of the problem here. return # convert cos(-x-y) to cos(x+y) return cls(-arg) if arg.args[0].is_negative: if (-arg).args[0].is_negative: # This is to avoid infinite recursion in the case # sin(-x-1) return return cls(-arg) if isinstance(arg, acos): return arg.args[0] if isinstance(arg, atan): x = arg.args[0] return 1 / sqrt(1 + x**2) if isinstance(arg, asin): x = arg.args[0] return sqrt(1 - x ** 2) if isinstance(arg, acot): x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)
def _eval_expand_complex(self, *args): if self.args[0].is_real: return self re, im = self.args[0].as_real_imag() return cos(re)*C.cosh(im) - \ S.ImaginaryUnit*sin(re)*C.sinh(im)
def eval(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN 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.cosh(i_coeff) else: pi_coeff = arg.as_coefficient(S.Pi) if pi_coeff is not None: if pi_coeff.is_Rational: cst_table_some = { 1 : S.One, 2 : S.Zero, 3 : S.Half, 4 : S.Half*sqrt(2), 6 : S.Half*sqrt(3), } cst_table_more = { (1, 5) : (sqrt(5) + 1)/4, (2, 5) : (sqrt(5) - 1)/4 } p = pi_coeff.p q = pi_coeff.q Q, P = 2*p // q, p % q try: result = cst_table_some[q] except KeyError: if abs(P) > q // 2: P = q - P try: result = cst_table_more[(P, q)] except KeyError: if P != p: result = cls(C.Rational(P, q)*S.Pi) else: return None if Q % 4 in (1, 2): return -result else: return result if arg.is_Mul and arg.args[0].is_negative: return cls(-arg) if arg.is_Add: x, m = arg.as_independent(S.Pi) if m in [S.Pi/2, S.Pi]: return cos(m)*cos(x)-sin(m)*sin(x) # normalize cos(-x-y) to cos(x+y) if arg.args[0].is_Mul: if arg.args[0].args[0].is_negative: # e.g. arg = -x - y if (-arg).args[0].is_Mul: if (-arg).args[0].args[0].is_negative: # This is to prevent infinite recursion in # the case cos(-x+y), for which # -arg = -y + x. See also #838 for the # root of the problem here. return # convert cos(-x-y) to cos(x+y) return cls(-arg) if arg.args[0].is_negative: if (-arg).args[0].is_negative: # This is to avoid infinite recursion in the case # sin(-x-1) return return cls(-arg) if isinstance(arg, acos): return arg.args[0] if isinstance(arg, atan): x = arg.args[0] return 1 / sqrt(1 + x**2) if isinstance(arg, asin): x = arg.args[0] return sqrt(1 - x ** 2) if isinstance(arg, acot): x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)
def eval(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN elif arg is S.Zero: return S.One elif arg is S.Infinity or arg is S.NegativeInfinity: # In this cases, it is unclear if we should # return S.NaN or leave un-evaluated. One # useful test case is how "limit(sin(x)/x,x,oo)" # is handled. # See test_sin_cos_with_infinity() an # Test for issue 209 # http://code.google.com/p/sympy/issues/detail?id=2097 # For now, we return un-evaluated. return if arg.could_extract_minus_sign(): return cls(-arg) i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return C.cosh(i_coeff) pi_coeff = _pi_coeff(arg) if pi_coeff is not None: if pi_coeff.is_integer: return (S.NegativeOne)**pi_coeff if not pi_coeff.is_Rational: narg = pi_coeff * S.Pi if narg != arg: return cls(narg) return None # cosine formula ##################### # http://code.google.com/p/sympy/issues/detail?id=2949 # explicit calculations are preformed for # cos(k pi / 8), cos(k pi /10), and cos(k pi / 12) # Some other exact values like cos(k pi/15) can be # calculated using a partial-fraction decomposition # by calling cos( X ).rewrite(sqrt) cst_table_some = { 3: S.Half, 5: (sqrt(5) + 1) / 4, } if pi_coeff.is_Rational: q = pi_coeff.q p = pi_coeff.p % (2 * q) if p > q: narg = (pi_coeff - 1) * S.Pi return -cls(narg) if 2 * p > q: narg = (1 - pi_coeff) * S.Pi return -cls(narg) # If nested sqrt's are worse than un-evaluation # you can require q in (1, 2, 3, 4, 6) # q <= 12 returns expressions with 2 or fewer nestings. if q > 12: return None if q in cst_table_some: cts = cst_table_some[pi_coeff.q] return C.chebyshevt(pi_coeff.p, cts).expand() if 0 == q % 2: narg = (pi_coeff * 2) * S.Pi nval = cls(narg) if None == nval: return None x = (2 * pi_coeff + 1) / 2 sign_cos = (-1)**((-1 if x < 0 else 1) * int(abs(x))) return sign_cos * sqrt((1 + nval) / 2) return None if arg.is_Add: x, m = _peeloff_pi(arg) if m: return cos(m) * cos(x) - sin(m) * sin(x) if arg.func is acos: return arg.args[0] if arg.func is atan: x = arg.args[0] return 1 / sqrt(1 + x**2) if arg.func is atan2: y, x = arg.args return x / sqrt(x**2 + y**2) if arg.func is asin: x = arg.args[0] return sqrt(1 - x**2) if arg.func is acot: x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)
def eval(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN elif arg is S.Zero: return S.One elif arg is S.Infinity: return if arg.could_extract_minus_sign(): return cls(-arg) i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return C.cosh(i_coeff) pi_coeff = _pi_coeff(arg) if pi_coeff is not None: if not pi_coeff.is_Rational: if pi_coeff.is_integer: even = pi_coeff.is_even if even: return S.One elif even is False: return S.NegativeOne narg = pi_coeff * S.Pi if narg != arg: return cls(narg) return None cst_table_some = { 1: S.One, 2: S.Zero, 3: S.Half, 4: S.Half * sqrt(2), 6: S.Half * sqrt(3), } cst_table_more = { (1, 5): (sqrt(5) + 1) / 4, (2, 5): (sqrt(5) - 1) / 4 } p = pi_coeff.p q = pi_coeff.q Q, P = 2 * p // q, p % q try: result = cst_table_some[q] except KeyError: if abs(P) > q // 2: P = q - P try: result = cst_table_more[(P, q)] except KeyError: if P != p: result = cls(C.Rational(P, q) * S.Pi) else: return None if Q % 4 in (1, 2): return -result else: return result if arg.is_Add: x, m = _peeloff_pi(arg) if m: return cos(m) * cos(x) - sin(m) * sin(x) if arg.func is acos: return arg.args[0] if arg.func is atan: x = arg.args[0] return 1 / sqrt(1 + x**2) if arg.func is asin: x = arg.args[0] return sqrt(1 - x**2) if arg.func is acot: x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)
def canonize(cls, arg): if arg.is_Number: if arg is S.NaN: return S.NaN 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.cosh(i_coeff) else: pi_coeff = arg.as_coefficient(S.Pi) if pi_coeff is not None: if pi_coeff.is_Rational: cst_table = { 1: S.One, 2: S.Zero, 3: S.Half, 4: S.Half * sqrt(2), 6: S.Half * sqrt(3), } try: result = cst_table[pi_coeff.q] if (2 * pi_coeff.p // pi_coeff.q) % 4 in (1, 2): return -result else: return result except KeyError: pass if arg.is_Mul and arg.args[0].is_negative: return cls(-arg) if arg.is_Add: x, m = arg.as_independent(S.Pi) if m in [S.Pi / 2, S.Pi]: return cos(m) * cos(x) - sin(m) * sin(x) # normalize cos(-x-y) to cos(x+y) if arg.args[0].is_Mul: if arg.args[0].args[0].is_negative: # e.g. arg = -x - y if (-arg).args[0].is_Mul: if (-arg).args[0].args[0].is_negative: # This is to prevent infinite recursion in # the case cos(-x+y), for which # -arg = -y + x. See also #838 for the # root of the problem here. return # convert cos(-x-y) to cos(x+y) return cls(-arg) if arg.args[0].is_negative: if (-arg).args[0].is_negative: # This is to avoid infinite recursion in the case # sin(-x-1) return return cls(-arg) if isinstance(arg, acos): return arg.args[0] if isinstance(arg, atan): x = arg.args[0] return 1 / sqrt(1 + x**2) if isinstance(arg, asin): x = arg.args[0] return sqrt(1 - x**2) if isinstance(arg, acot): x = arg.args[0] return 1 / sqrt(1 + 1 / x**2)