| Issue 896: | inconsistency and wrong result with simplifying exponentation | |
| 7 people starred this issue and may be notified of changes. | Back to list |
Sign in to add a comment
|
First, from >>> simplify((a**2)**(1+a)) a**(2 + 2*a) follows that the result of >>> simplify((a**2)**(a)) (a**2)**a should be `a**(2*a)`. However, (a**2)**a==a**(2*a) does not hold in general. Take for example a==-1/2, then there is contradiction 2==-2. Hence also the result of the first simplification is wrong. |
||||||||||||||||
,
Jun 22, 2008
Thanks for the spot. So it should only work for a>0, right?
Labels: -Priority-Medium Priority-High WrongResult
|
|||||||||||||||||
,
Jun 22, 2008
The question is whether (expr ** n) ** a where n is integer, should simplify to expr ** (n * a) . This transformation is valid if a is integer (both positive and negative). However, it is late now and I don't see why it should hold also for positive rational numbers in general. |
|||||||||||||||||
,
Jul 13, 2008
The expression (expr ** n) ** a where n is integer should not simplify for general rational a, because for example ((-1) ** 3) ** (1/3) = (-1)**(1/3) has one real root (-1), but the principal value is given by In [34]: ((-1)**Rational(1,3)).evalf() Out[34]: 0.5 + 0.866025403784439*ⅈ therefore ((-1)**3)**(1/3) != -1 This expression can be simplified to expr**(a*b) if: - expr is positive; a, b are real - a, b are integer it simplifies to abs(expr)**(a*b) if: - expr is real, a is even Are there some other possible simplifications? |
|||||||||||||||||
,
Jul 13, 2008
Maybe there are, but let's just implement those two simplifications for the start. Thanks for looking into that. |
|||||||||||||||||
,
Aug 25, 2008
Very simple counterexamples with square roots: >>> sqrt(1/x) x**(-1/2) >>> 1/sqrt(x) x**(-1/2) >>> sqrt(1/(-1)) I >>> 1/sqrt(-1) -I >>> sqrt(x*y) x**(1/2)*y**(1/2) >>> sqrt(x)*sqrt(y) x**(1/2)*y**(1/2) >>> sqrt((-1)*(-2)) 2**(1/2) >>> sqrt(-1)*sqrt(-2) -2**(1/2) |
|||||||||||||||||
,
Aug 25, 2008
Could anyone please try to fix it? I think this should be fixed soon.
Labels: Milestone-Release0.6.3
|
|||||||||||||||||
,
Aug 26, 2008
I tried it some time ago and it caused a lot of test failures Attached is patch with basic simplification rules. I found quite general formula for simplification: assume x is complex, a,b are real then (x**a)**b == x**(a*b) if and only if modpi(b * modpi(a * arg(x))) == modpi(a * b * arg(x)) where modpi(x) = ((x + pi) mod pi) - pi |
|||||||||||||||||
,
Aug 26, 2008
i forgot the patch |
|||||||||||||||||
,
Aug 26, 2008
Thanks a lot, if I find time I'll look into that. |
|||||||||||||||||
,
Aug 26, 2008
I fixed some failing tests. I was mainly because tested identities hold only for real variables, but tests were written for generic symbols. There are still many failures in series tests. Each fixed test is in separate patch. |
|||||||||||||||||
,
Aug 26, 2008
Thanks! Don't worry about the series tests, we are refactoring them in the issue 1029 . |
|||||||||||||||||
,
Aug 26, 2008
Here are two other fixes. In both of them, the problem
was, that the summation index has to be explicitly
set as integer eg
In [10]: n = Symbol('n')
In [11]: Sum((-1)**n / n, (n, 1, oo)).evalf()
fails, but
In [12]: n = Symbol('n', integer=True)
In [13]: Sum((-1)**n / n, (n, 1, oo)).evalf()
Out[13]: -0.693147180559945
probably the assumption should be made inside sum (issue 1047)
|
|||||||||||||||||
,
Aug 26, 2008
Thanks Štěpán. I just polished the series patches, sent for a review. If you want to get these things fixed faster, please review them in the sympy-patches mailinglist. I'll then look at this what can be done with it. Btw, I noticed you can also use git, I've setup: http://git.sympy.org/ but unfortunately it cannot yet be pulled over the web interface, so stay tuned. :) |
|||||||||||||||||
,
Aug 27, 2008
I could look at this after I finish my thesis, hopefully < 1 week. |
|||||||||||||||||
,
Aug 27, 2008
Here is one more patch. The problem is similar to summation. The correct assumptions have to be set before calling nseries. Now there is only one strange failing test_heurisch_symbolic_coeffs(): It fails in the full test suite ... sympy/integrals/tests/test_integrals.py[28] ...........................f sympy/integrals/tests/test_risch.py[18] ..........F...ssss sympy/integrals/tests/test_trigonometry.py[2] .. ... but works if run separately py.test sympy/integrals/tests/test_risch.py ... sympy/integrals/tests/test_risch.py[18] ..............ssss attached is also a corrected exponentiation.patch the original contained trailing whitespaces. BTW good luck with your thesis and dont hurry with this, thesis is more important. I printed mine on monday. |
|||||||||||||||||
,
Aug 27, 2008
Do you think you could please create a repo at freehg.sympy.org (for example) or github and push your patches in? I'll pull it and look if I can fix it easily. |
|||||||||||||||||
,
Aug 27, 2008
I created a repo at http://freehg.sympy.org/u/tetaberta/sympy/ |
|||||||||||||||||
,
Aug 27, 2008
Thanks. Here are couple more patches to make nseries work:
diff --git a/sympy/series/tests/test_nseries.py b/sympy/series/tests/test_nseries.py
--- a/sympy/series/tests/test_nseries.py
+++ b/sympy/series/tests/test_nseries.py
@@ -121,7 +121,7 @@ def testseries2():
assert (1/(1+1/x**2)).nseries(x,0,6) == x**2-x**4+O(x**6, x)
def test_bug2(): ### 1/log(0) * log(0) problem
- w = Symbol("w")
+ w = Symbol("w", real=True, positive=True)
e =
(w**(-1)+w**(-log(3)*log(2)**(-1)))**(-1)*(3*w**(-log(3)*log(2)**(-1))+2*w**(-1))
e = e.expand()
#should be 3, but is 2
@@ -164,7 +164,7 @@ def test_genexp_x():
# more complicated example
def test_genexp_x2():
- x = Symbol("x")
+ x = Symbol("x", real=True, positive=True)
p = Rational(3,2)
e = (2/x+3/x**p)/(1/x+1/x**p)
assert e.nseries(x,0,3) == 3 - sqrt(x) + x + O(sqrt(x)**3)
@@ -221,7 +221,7 @@ def test_issue159():
assert a.nseries(x,0,6) == 1 - x/2 - x**4/720 + x**2/12 + O(x**5)
def test_issue105():
- x = Symbol("x")
+ x = Symbol("x", real=True, positive=True)
f = sin(x**3)**Rational(1,3)
assert f.nseries(x,0,17) == x - x**7/18 - x**13/3240 + O(x**17)
But I don't have time for the rest now. But surely it can be fixed, there are just
couple more failures.
|
|||||||||||||||||
,
Aug 27, 2008
I've put your patch into my repository. Is the real=True necessary? If it is positive, it must be real, doesnt it? Now all tests pass or xfail except the test_risch |
|||||||||||||||||
,
Aug 27, 2008
> Is the real=True necessary? Maybe not, didn't have time to play with it. > Now all tests pass or xfail except the test_risch. Excellent.
Cc: mattpap
|
|||||||||||||||||
,
Aug 28, 2008
Ondrej, Stepan, what's the state of this? Please ping me when it is ok to pull from your repo, ok? Thanks beforehand. |
|||||||||||||||||
,
Aug 28, 2008
I don't have time for this now, but the state imho is that most of the tests pass, but not all yet. Also the patches should be probably merged/polished etc. But it's on a good way. |
|||||||||||||||||
,
Aug 28, 2008
Thanks for the update, looking forward! |
|||||||||||||||||
,
Sep 07, 2008
I think some of the patches to tests above could be merged and imported to sympy already, because they test the right behavior and they shouldn't introduce any bugs. I'll look into that... |
|||||||||||||||||
,
Sep 24, 2008
I sent a patch for most of the tests to sympy-patches, however, new problems
appeared. With the exponentiation.patch applied some test in the galgebra
module fails
_______________________________________________________________ entrypoint:
test_noneuclidian _______________________________________________________________
def test_noneuclidian():
global s,c,Binv,M,S,C,alpha
#set_main(sys.modules[__name__])
metric = '0 # #,'+ \
'# 0 #,'+ \
'# # 1,'
MV.setup('X Y e',metric,debug=0)
MV.set_str_format(1)
L = X^Y^e
B = L*e
Bsq = (B*B)()
BeBr =B*e*B.rev()
make_symbols('s c Binv M S C alpha')
Bhat = Binv*B # Normalize translation generator
R = c+s*Bhat # Rotor R = exp(alpha*Bhat/2)
Z = R*X*R.rev()
Z.expand()
Z.collect([Binv,s,c,XdotY])
W = Z|Y
W.expand()
W.collect([s*Binv])
M = 1/Bsq
W.subs(Binv**2,M)
W.simplify()
Bmag = sympy.sqrt(XdotY**2-2*XdotY*Xdote*Ydote)
W.collect([Binv*c*s,XdotY])
W.subs(2*XdotY**2-4*XdotY*Xdote*Ydote,2/(Binv**2))
W.subs(2*c*s,S)
W.subs(c**2,(C+1)/2)
W.subs(s**2,(C-1)/2)
W.simplify()
W.subs(1/Binv,Bmag)
W = W().expand()
#print '(R*X*R.rev()).Y =',W
Wd = collect(W,[C,S],exact=True,evaluate=False)
#print 'Wd =',Wd
Wd_1 = Wd[ONE]
Wd_C = Wd[C]
Wd_S = Wd[S]
#print '|B| =',Bmag
Wd_1 = Wd_1.subs(Bmag,1/Binv)
Wd_C = Wd_C.subs(Bmag,1/Binv)
Wd_S = Wd_S.subs(Bmag,1/Binv)
#print 'Wd[ONE] =',Wd_1
#print 'Wd[C] =',Wd_C
#print 'Wd[S] =',Wd_S
lhs = Wd_1+Wd_C*C
rhs = -Wd_S*S
lhs = lhs**2
rhs = rhs**2
W = (lhs-rhs).expand()
W = (W.subs(1/Binv**2,Bmag**2)).expand()
#print 'W =',W
W = (W.subs(S**2,C**2-1)).expand()
W = collect(W,[C**2,C],evaluate=False)
#print 'W =',W
a = W[C**2]
E b = W[abs(C)]
> KeyError: abs(C)
[/home/rouckas/prgm/sympy-896/sympy/galgebra/tests/test_GA.py:96]
W = {1: -2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2 + (X.e)**2*(Y.e)**2, C**2: (X.e)**2*(Y.e)**2,
(C**2)**(1/2): 2*(X.Y)*(X.e)*(Y.e) - 2*(X.e)**2*(Y.e)**2}
Because C is defined as complex, the expression (C**2)**(1/2) cannot be simplified
to abs(C). Maybe C could be defined real, but I'm not sure about meaning of this
variable.
|
|||||||||||||||||
,
Sep 25, 2008
If we let the C to be complex, it could be fixed with this patch.
The only remaining problem is the heurisch test:
_____________________________________________________________________________________________________________________________________________________________
_________________________________________________________ entrypoint:
test_heurisch_symbolic_coeffs _________________________________________________________
def test_heurisch_symbolic_coeffs():
assert heurisch(1/(x+y), x) == log(x+y)
assert heurisch(1/(x+sqrt(2)), x) == log(x+sqrt(2))
assert heurisch(1/(x**2+y), x) == I*y**(-S.Half)*log(x + (-y)**S.Half)/2 - \
E I*y**(-S.Half)*log(x - (-y)**S.Half)/2
> AssertionError: (inconsistently failed
then succeeded)
[/home/rouckas/prgm/sympy-896/sympy/integrals/tests/test_risch.py:109]
|
|||||||||||||||||
,
Sep 25, 2008
Thanks for the work. So which patches are ready for review? |
|||||||||||||||||
,
Sep 25, 2008
I have one patch that implements the exponentiation and other one that fixes the tests. Is it OK to submit patches that break tests if applied separately or should I merge them? There still remains the problem with the failing heurisch test. I think that it is quite important but I have no idea how to fix it. The functionality itself isn't broken, it works in sympy or if the test is run separately using py.test. It fails only if the full test suite is executed. |
|||||||||||||||||
,
Sep 25, 2008
It's better if the patches don't break stuff (so that hg/git bisect works nice), and it's also good if each patch is semantically just one change. But sometimes one needs to make compromises. So post what you have, we'll look at it. |
|||||||||||||||||
,
Sep 25, 2008
Ok, I'll post it in ~two hours, now I have to go to some presentation as I'm attending some conference in Hungary. |
|||||||||||||||||
,
Sep 25, 2008
Here is what I have: The spherical.patch could be aplied without problems. exponantiation.patch introduces 3 failing tests. Two of them (except risch) are fixed in tests.patch. |
|||||||||||||||||
,
Sep 25, 2008
I did some experiments to see what causes the risch test to fail, but the results don't make sense to me. py.test sympy/core/ sympy/integrals/tests/test_risch.py OK py.test sympy/concrete/ sympy/integrals/tests/test_risch.py OK, but py.test sympy/concrete/ sympy/core/ sympy/integrals/tests/test_risch.py FAIL py.test sympy/functions/ sympy/geometry/ sympy/integrals/tests/test_risch.py OK py.test sympy/galgebra/ sympy/integrals/tests/test_risch.py OK, but py.test sympy/functions/ sympy/galgebra/ sympy/geometry/ sympy/integrals/tests/test_risch.py FAIL I guess it could be problem of memory management or caching? I noticed, that similar error appeared in issue 597 |
|||||||||||||||||
,
Sep 25, 2008
I think, that in order to solve this problem with exponentiation, we could XFAIL the risch test and start a new issue for it. What do you think about it? |
|||||||||||||||||
,
Sep 27, 2008
Did you try it without caching? If it's only one failing test, I'm +1 for XFAIL.
Status: Started
|
|||||||||||||||||
,
Sep 29, 2008
It fails also with caching disabled SYMPY_USE_CACHE=no py.test sympy/ ... sympy/integrals/tests/test_risch.py[18] ..........F...ssss ... |
|||||||||||||||||
,
Oct 12, 2008
The inconsistency in simplifying expressions of the form (x**y)**z is now imho removed. What remains to be fixed is this: >>> sqrt(x*y) x**(1/2)*y**(1/2) >>> sqrt(x)*sqrt(y) x**(1/2)*y**(1/2) >>> sqrt((-1)*(-2)) 2**(1/2) >>> sqrt(-1)*sqrt(-2) -2**(1/2) |
|||||||||||||||||
,
Oct 17, 2008
(No comment was entered for this change.)
Labels: -Milestone-Release0.6.3 Milestone-Release0.6.4
|
|||||||||||||||||
,
Feb 08, 2009
(No comment was entered for this change.)
Labels: -Milestone-Release0.6.4 Milestone-Release0.6.5
|
|||||||||||||||||
,
Jul 13, 2009
(No comment was entered for this change.)
Labels: Milestone-Release0.6.6
|
|||||||||||||||||
,
Nov 18, 2009
The last problems seem to have been fixed at some point.
In [1]: sqrt(x*y)
Out[1]:
⎽⎽⎽⎽⎽
╲╱ x⋅y
In [2]: sqrt(x)*sqrt(y)
Out[2]:
⎽⎽⎽ ⎽⎽⎽
╲╱ x ⋅╲╱ y
In [3]: a,b = symbols('ab', positive=True)
In [4]: sqrt(a*b)
Out[4]:
⎽⎽⎽ ⎽⎽⎽
╲╱ a ⋅╲╱ b
In [5]: sqrt(-1*-2)
Out[5]:
⎽⎽⎽
╲╱ 2
In [6]: sqrt(-1)*sqrt(-2)
Out[6]:
⎽⎽⎽
-╲╱ 2
Status: Fixed
|
|||||||||||||||||
|
|
|||||||||||||||||