2 from basic
import Basic
, S
, cache_it
, cache_it_immutable
3 from methods
import ArithMeths
, RelMeths
, NoRelMeths
6 def integer_nthroot(y
, n
):
10 Return a tuple containing x = floor(y**(1/n))
11 and a boolean indicating whether the result is exact (that is,
17 >>> integer_nthroot(16,2)
19 >>> integer_nthroot(26,2)
21 >>> integer_nthroot(1234567**7, 7)
23 >>> integer_nthroot(1234567**7+1, 7)
27 y
= int(y
); n
= int(n
)
28 if y
< 0: raise ValueError, "y must not be negative"
29 if n
< 1: raise ValueError, "n must be positive"
30 if y
in (0, 1): return y
, True
31 if n
== 1: return y
, True
33 # Search with Newton's method, starting from floating-point
34 # approximation. Care must be taken to avoid overflow.
35 from math
import log
as _log
36 guess
= 2**int(_log(y
, 2)/n
)
38 while abs(x
- xprev
) > 1:
40 xprev
, x
= x
, x
- (t
*x
-y
)//(n
*t
)
47 class Pow(Basic
, ArithMeths
, RelMeths
):
49 precedence
= Basic
.Pow_precedence
52 def __new__(cls
, a
, b
, **assumptions
):
55 if isinstance(b
, Basic
.Zero
):
57 if isinstance(b
, Basic
.One
):
59 obj
= a
._eval
_power
(b
)
61 obj
= Basic
.__new
__(cls
, a
, b
, **assumptions
)
72 def _eval_power(self
, other
):
73 if isinstance(other
, Basic
.Number
):
75 if isinstance(self
.exp
, Basic
.Number
):
76 # (a ** 2) ** 3 -> a ** (2 * 3)
77 return Pow(self
.base
, self
.exp
* other
)
78 if isinstance(other
, Basic
.Integer
):
79 # (a ** b) ** 3 -> a ** (3 * b)
80 return Pow(self
.base
, self
.exp
* other
)
81 elif isinstance(other
, (Basic
.Add
, Basic
.Mul
)):
82 # (a**b)**c = a**(b*c)
83 return Pow(self
.base
, self
.exp
* other
)
85 if other
.atoms(Basic
.Wild
):
86 return Pow(self
.base
, self
.exp
* other
)
89 def _eval_is_commutative(self
):
90 c1
= self
.base
.is_commutative
92 c2
= self
.base
.is_commutative
96 def _eval_is_comparable(self
):
97 c1
= self
.base
.is_comparable
99 c2
= self
.base
.is_comparable
100 if c2
is None: return
103 def _eval_is_even(self
):
104 if self
.exp
.is_integer
and self
.exp
.is_positive
:
105 if self
.base
.is_even
:
107 if self
.exp
.is_integer
:
110 def _eval_is_positive(self
):
111 if self
.base
.is_positive
:
114 elif self
.base
.is_negative
:
119 elif self
.base
.is_nonpositive
:
123 def _eval_is_negative(self
):
124 if self
.base
.is_negative
:
129 elif self
.base
.is_positive
:
132 elif self
.base
.is_nonnegative
:
135 elif self
.base
.is_nonpositive
:
138 elif self
.base
.is_real
:
142 def _eval_is_integer(self
):
143 c1
= self
.base
.is_integer
144 if c1
is None: return
145 c2
= self
.exp
.is_integer
146 if c2
is None: return
148 if self
.exp
.is_nonnegative
or self
.exp
.is_positive
:
150 if self
.exp
.is_negative
:
153 def _eval_is_real(self
):
154 c1
= self
.base
.is_real
155 if c1
is None: return
156 c2
= self
.exp
.is_real
157 if c2
is None: return
159 if self
.base
.is_positive
:
161 if self
.base
.is_negative
:
162 if self
.exp
.is_integer
:
165 def _eval_is_odd(self
):
166 if not (self
.base
.is_integer
and self
.exp
.is_nonnegative
): return
167 return self
.base
.is_odd
169 def _eval_is_bounded(self
):
170 if self
.exp
.is_negative
:
171 if self
.base
.is_infinitesimal
:
173 if self
.base
.is_unbounded
:
175 c1
= self
.base
.is_bounded
176 if c1
is None: return
177 c2
= self
.exp
.is_bounded
178 if c2
is None: return
180 if self
.exp
.is_nonnegative
:
183 def tostr(self
, level
=0):
184 precedence
= self
.precedence
185 b
= self
.base
.tostr(precedence
)
186 if isinstance(self
.exp
, Basic
.NegativeOne
):
189 r
= '%s**%s' % (b
,self
.exp
.tostr(precedence
))
190 if precedence
<= level
:
194 def _eval_subs(self
, old
, new
):
195 if self
==old
: return new
196 if isinstance(old
, self
.__class
__) and self
.base
==old
.base
:
197 coeff1
,terms1
= self
.exp
.as_coeff_terms()
198 coeff2
,terms2
= old
.exp
.as_coeff_terms()
199 if terms1
==terms2
: return new
** (coeff1
/coeff2
) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3*y)
200 if isinstance(old
, Basic
.exp
):
201 coeff1
,terms1
= old
[0].as_coeff_terms()
202 coeff2
,terms2
= (self
.exp
* Basic
.log(self
.base
)).as_coeff_terms()
203 if terms1
==terms2
: return new
** (coeff1
/coeff2
) # (x**(2*y)).subs(exp(3*y*log(x)),z) -> z**(2/3*y)
204 return self
.base
.subs(old
, new
) ** self
.exp
.subs(old
, new
)
206 def as_powers_dict(self
):
207 return { self
.base
: self
.exp
}
209 def as_base_exp(self
):
210 if isinstance(self
.base
, Basic
.Rational
) and self
.base
.p
==1:
211 return 1/self
.base
, -self
.exp
212 return self
.base
, self
.exp
214 def _eval_conjugate(self
):
215 from sympy
.functions
.elementary
.complexes
import conjugate
as c
216 return c(self
.base
)**self
.exp
218 def _eval_expand_complex(self
, *args
):
219 if isinstance(self
.exp
, Basic
.Integer
):
220 re
, im
= self
.base
.as_real_imag()
221 base
= re
+ S
.ImaginaryUnit
* im
222 return (base
**self
.exp
)._eval
_expand
_basic
(*args
)
223 elif isinstance(self
.exp
, Basic
.Rational
):
224 # NOTE: This is not totally correct since for x**(p/q) with
225 # x being imaginary there are actually q roots, but
226 # only a single one is returned from here.
227 re
, im
= self
.base
.as_real_imag()
229 r
= S
.Sqrt(re
**2 + im
**2)
230 t
= Basic
.atan(im
/ re
)
232 if im
== 0 and re
== -1:
235 rp
, tp
= r
**self
.exp
, t
*self
.exp
237 return rp
*Basic
.cos(tp
) + rp
*Basic
.sin(tp
)*S
.ImaginaryUnit
239 return S
.Re(self
) + S
.ImaginaryUnit
*S
.Im(self
)
241 def _eval_expand_basic(self
, *args
):
243 (a*b)**n -> a**n * b**n
244 (a+b+..) ** n -> a**n + n*a**(n-1)*b + .., n is positive integer
246 base
= self
.base
.expand()
247 exponent
= self
.exp
.expand()
248 result
= base
** exponent
249 if isinstance(result
, Pow
):
251 exponent
= result
.exp
254 if isinstance(exponent
, Basic
.Integer
):
255 if isinstance(base
, Basic
.Mul
):
256 return Basic
.Mul(*[t
**exponent
for t
in base
])
257 if exponent
.is_positive
and isinstance(base
, Basic
.Add
):
259 if base
.is_commutative
:
263 if isinstance(o
, Basic
.Order
):
264 order_terms
.append(o
)
268 # (f(x) + O(x^n))^m -> f(x)^m + m*f(x)^{m-1} *O(x^n)
270 fm1
= (f
**(m
-1)).expand()
271 return (f
*fm1
).expand() + m
*fm1
*Basic
.Add(*order_terms
)
272 ## Consider polynomial
273 ## P(x) = sum_{i=0}^n p_i x^k
274 ## and its m-th exponent
275 ## P(x)^m = sum_{k=0}^{m n} a(m,k) x^k
276 ## The coefficients a(m,k) can be computed using the
277 ## J.C.P. Miller Pure Recurrence [see D.E.Knuth,
278 ## Seminumerical Algorithms, The art of Computer
279 ## Programming v.2, Addison Wesley, Reading, 1981;]:
280 ## a(m,k) = 1/(k p_0) sum_{i=1}^n p_i ((m+1)i-k) a(m,k-i),
281 ## where a(m,0) = p_0^m.
283 cache
= {0: p
[0] ** m
}
284 p0
= [t
/p
[0] for t
in p
]
287 Rational
= Basic
.Rational
288 for k
in xrange(1, m
* n
+ 1):
290 for i
in xrange(1,n
+1):
292 a
.append(Mul(Rational((m
+1)*i
-k
,k
), p0
[i
], cache
[k
-i
]).expand())
300 return Basic
.Add(*[t1
*t2
for t1
in p
for t2
in p
])
301 return Basic
.Mul(base
, Pow(base
, m
-1).expand()).expand()
302 elif isinstance(exponent
, Basic
.Add
) and isinstance(base
, Basic
.Number
):
303 # n**(a+b) --> n**a * n**b with n and a Numbers
306 for term
in exponent
:
307 if isinstance(term
, Basic
.Number
):
311 result
= coeff
* base
**exp
315 def _eval_derivative(self
, s
):
316 dbase
= self
.base
.diff(s
)
317 dexp
= self
.exp
.diff(s
)
318 return self
* (dexp
* Basic
.log(self
.base
) + dbase
* self
.exp
/self
.base
)
320 _eval_evalf
= Basic
._seq
_eval
_evalf
322 def _calc_splitter(self
, d
):
325 base
= self
.base
._calc
_splitter
(d
)
326 exp
= self
.exp
._calc
_splitter
(d
)
327 if isinstance(exp
, Basic
.Integer
):
332 p1
= (base
** n
)._calc
_splitter
(d
)
333 p2
= (base
** r
)._calc
_splitter
(d
)
336 r
= (base
** n
)._calc
_splitter
(d
) ** 2
338 r
= (1/base
)._calc
_splitter
(d
) ** 2
345 s
= d
[r
] = Basic
.Temporary()
349 def count_ops(self
, symbolic
=True):
351 return Basic
.Add(*[t
.count_ops(symbolic
) for t
in self
[:]]) + Basic
.Symbol('POW')
352 return Basic
.Add(*[t
.count_ops(symbolic
) for t
in self
[:]]) + 1
354 def _eval_integral(self
, s
):
355 if not self
.exp
.has(s
):
358 return self
.base
** n
/n
359 y
= Basic
.Symbol('y',dummy
=True)
360 x
,ix
= self
.base
.solve4linearsymbol(y
,symbols
=set([s
]))
361 if isinstance(x
, Basic
.Symbol
):
362 dx
= 1/self
.base
.diff(x
)
364 return (y
**self
.exp
*dx
).integral(y
).subs(y
, self
.base
)
366 def _eval_defined_integral(self
, s
, a
, b
):
367 if not self
.exp
.has(s
):
371 x
,ix
= self
.base
.solve4linearsymbol(s
)
372 if isinstance(x
, Basic
.Symbol
):
374 if isinstance(dx
, Basic
.Number
):
375 y
= Basic
.Symbol('y',dummy
=True)
376 return (y
**self
.exp
*dx
).integral(y
==[self
.base
.subs(s
,a
), self
.base
.subs(s
,b
)])
378 def _eval_is_polynomial(self
, syms
):
379 if self
.exp
.has(*syms
):
382 if self
.base
.has(*syms
):
383 # it would be nice to have is_nni working
384 return self
.base
._eval
_is
_polynomial
(syms
) and \
385 self
.exp
.is_nonnegative
and \
390 def as_numer_denom(self
):
391 base
, exp
= self
.as_base_exp()
392 c
,t
= exp
.as_coeff_terms()
393 n
,d
= base
.as_numer_denom()
397 return n
** exp
, d
** exp
399 def matches(pattern
, expr
, repl_dict
={}, evaluate
=False):
400 Basic
.matches
.__doc
__
403 for old
,new
in repl_dict
.items():
404 pat
= pat
.subs(old
, new
)
406 return pat
.matches(expr
, repl_dict
)
408 expr
= Basic
.sympify(expr
)
409 b
, e
= expr
.as_base_exp()
411 # special case, pattern = 1 and expr.exp can match to 0
412 if isinstance(expr
, Basic
.One
):
414 d
= pattern
.exp
.matches(Basic
.Integer(0), d
, evaluate
=False)
419 d
= pattern
.base
.matches(b
, d
, evaluate
=False)
423 d
= pattern
.exp
.matches(e
, d
, evaluate
=True)
425 return Basic
.matches(pattern
, expr
, repl_dict
, evaluate
)
428 def _eval_oseries(self
, order
):
430 f**g + O(h) == (f+O(k))**g -> .. -> f**g + O(f**(g-1)*k), hence O(k)==O(h*f**(1-g)).
439 return exp(e
* ln(b
)).oseries(order
)
442 if isinstance(b0
, Basic
.Zero
) or b0
.is_unbounded
:
443 lt
= b
.as_leading_term(x
)
444 o
= order
* lt
**(1-e
)
446 if isinstance(bs
, Basic
.Add
):
447 # bs -> lt + rest -> lt * (1 + (bs/lt - 1))
448 return lt
**e
* ((bs
/lt
).expand()**e
).oseries(order
* lt
**(-e
))
451 # b -> b0 + (b-b0) -> b0 * (1 + (b/b0-1))
453 r
= self
._compute
_oseries
(z
, o
, self
.taylor_term
, lambda z
: 1+z
) * b0
**e
456 def _eval_as_leading_term(self
, x
):
457 if not self
.exp
.has(x
):
458 return self
.base
.as_leading_term(x
) ** self
.exp
459 return Basic
.exp(self
.exp
* Basic
.log(self
.base
)).as_leading_term(x
)
462 def taylor_term(self
, n
, x
, *previous_terms
): # of (1+x)**e
463 if n
<0: return S
.Zero
465 return S
.Binomial(self
.exp
, n
) * x
**n