fix the abs(sin(x)).limit(x,0)
[sympy.git] / sympy / functions / elementary / complexes.py
blobe5a73ba9f4ac6fbf8983a1e0dccb160b6ae814d2
2 from sympy.core.basic import Basic, S, C, sympify
3 from sympy.core.function import Function
4 from sympy.functions.elementary.miscellaneous import sqrt
6 ###############################################################################
7 ######################### REAL and IMAGINARY PARTS ############################
8 ###############################################################################
10 class re(Function):
11 """Returns real part of expression. This function performs only
12 elementary analysis and so it will fail to decompose properly
13 more complicated expressions. If completely simplified result
14 is needed then use Basic.as_real_imag() or perform complex
15 expansion on instance of this function.
17 >>> from sympy import *
19 >>> x, y = symbols('x', 'y')
21 >>> re(2*E)
22 2*E
24 >>> re(2*I + 17)
27 >>> re(2*I)
30 >>> re(im(x) + x*I + 2)
33 """
35 nargs = 1
37 is_real = True
39 @classmethod
40 def _eval_apply_subs(self, *args):
41 return
43 @classmethod
44 def canonize(cls, arg):
45 if arg is S.NaN:
46 return S.NaN
47 elif arg.is_real:
48 return arg
49 else:
50 if not arg.is_Add:
51 arg = [arg]
53 included, reverted, excluded = [], [], []
55 if isinstance(arg, Basic):
56 arg = arg.args
57 for term in arg:
58 coeff = term.as_coefficient(S.ImaginaryUnit)
60 if coeff is not None:
61 if not coeff.is_real:
62 reverted.append(coeff)
63 elif not term.has(S.ImaginaryUnit) and term.is_real:
64 excluded.append(term)
65 else:
66 included.append(term)
68 if len(arg[:]) != len(included):
69 a, b, c = map(lambda xs: C.Add(*xs),
70 [included, reverted, excluded])
72 return cls(a) - im(b) + c
74 def _eval_conjugate(self):
75 return self
77 def _eval_expand_complex(self, *args):
78 return self.args[0].as_real_imag()[0]
80 class im(Function):
81 """Returns imaginary part of expression. This function performs
82 only elementary analysis and so it will fail to decompose
83 properly more complicated expressions. If completely simplified
84 result is needed then use Basic.as_real_imag() or perform complex
85 expansion on instance of this function.
87 >>> from sympy import *
89 >>> x, y = symbols('x', 'y')
91 >>> im(2*E)
94 >>> re(2*I + 17)
97 >>> im(x*I)
98 re(x)
100 >>> im(re(x) + y)
101 im(y)
105 nargs = 1
107 is_real = True
109 @classmethod
110 def _eval_apply_subs(self, *args):
111 return
113 @classmethod
114 def canonize(cls, arg):
115 if arg is S.NaN:
116 return S.NaN
117 elif arg.is_real:
118 return S.Zero
119 else:
120 if not arg.is_Add:
121 arg = [arg]
123 included, reverted, excluded = [], [], []
125 if isinstance(arg, Basic):
126 arg = arg.args
127 for term in arg:
128 coeff = term.as_coefficient(S.ImaginaryUnit)
130 if coeff is not None:
131 if not coeff.is_real:
132 reverted.append(coeff)
133 else:
134 excluded.append(coeff)
135 elif term.has(S.ImaginaryUnit) or not term.is_real:
136 included.append(term)
138 if len(arg[:]) != len(included):
139 a, b, c = map(lambda xs: C.Add(*xs),
140 [included, reverted, excluded])
142 return cls(a) + re(b) + c
144 def _eval_conjugate(self):
145 return self
147 def _eval_expand_complex(self, *args):
148 return self.args[0].as_real_imag()[1]
150 ###############################################################################
151 ############### SIGN, ABSOLUTE VALUE, ARGUMENT and CONJUGATION ################
152 ###############################################################################
154 class sign(Function):
156 nargs = 1
158 @classmethod
159 def canonize(cls, arg):
160 if arg is S.NaN:
161 return S.NaN
162 if arg is S.Zero: return S.Zero
163 if arg.is_positive: return S.One
164 if arg.is_negative: return S.NegativeOne
165 if arg.is_Mul:
166 coeff, terms = arg.as_coeff_terms()
167 if coeff is not S.One:
168 return cls(coeff) * cls(C.Mul(*terms))
170 is_bounded = True
172 def _eval_conjugate(self):
173 return self
175 def _eval_is_zero(self):
176 return (self[0] is S.Zero)
178 class abs(Function):
180 nargs = 1
182 is_real = True
183 is_negative = False
185 def fdiff(self, argindex=1):
186 if argindex == 1:
187 return sign(self.args[0])
188 else:
189 raise ArgumentIndexError(self, argindex)
191 @classmethod
192 def _eval_apply_subs(self, *args):
193 return
195 @classmethod
196 def canonize(cls, arg):
197 if arg is S.NaN:
198 return S.NaN
199 if arg.is_zero: return arg
200 if arg.is_positive: return arg
201 if arg.is_negative: return -arg
202 coeff, terms = arg.as_coeff_terms()
203 if coeff is not S.One:
204 return cls(coeff) * cls(C.Mul(*terms))
205 if arg.is_real is False:
206 return sqrt( (arg * arg.conjugate()).expand() )
207 if arg.is_Pow:
208 base, exponent = arg.as_base_exp()
209 if exponent.is_Number:
210 if exponent.is_even:
211 return arg
212 return
214 @classmethod
215 def _eval_apply_evalf(cls, arg):
216 # XXX this is weird!!!
217 # XXX remove me when 'abs -> abs_' is done
218 arg = arg.evalf()
220 if arg.is_Number:
221 import operator
222 return operator.abs(float(arg))
224 def _eval_is_nonzero(self):
225 return self._args[0].is_nonzero
227 def _eval_is_positive(self):
228 return self.is_nonzero
230 def _eval_conjugate(self):
231 return self
233 def _eval_power(self,other):
234 if self.args[0].is_real and other.is_integer:
235 if other.is_even:
236 return self.args[0]**other
237 return
239 @staticmethod
240 def taylor_term(n, x, *previous_terms):
241 if n == 1:
242 return x
243 else:
244 return S.Zero
247 def _sage_(self):
248 import sage.all as sage
249 return sage.abs_symbolic(self.args[0]._sage_())
251 class arg(Function):
253 nargs = 1
255 is_real = True
256 is_bounded = True
258 @classmethod
259 def canonize(cls, arg):
260 x, y = re(arg), im(arg)
261 arg = C.atan2(y, x)
262 if arg.is_number:
263 return arg
265 def _eval_conjugate(self):
266 return self
268 class conjugate(Function):
269 """Changes the sign of the imaginary part of a complex number.
271 >>> from sympy import *
273 >>> conjugate(1 + I)
274 1 - I
278 nargs = 1
280 @classmethod
281 def canonize(cls, arg):
282 obj = arg._eval_conjugate()
283 if obj is not None:
284 return obj
286 def _eval_conjugate(self):
287 return self.args[0]
290 # /cyclic/
291 from sympy.core import basic as _
292 _.abs_ = abs
293 del _