Opened 14 months ago
Closed 13 months ago
#29833 closed defect (fixed)
Translate Mathematica's "E" as e
Reported by:  charpent  Owned by:  

Priority:  major  Milestone:  sage9.2 
Component:  interfaces  Keywords:  
Cc:  Merged in:  
Authors:  Emmanuel Charpentier  Reviewers:  KarlDieter Crisman, Markus Wageringel 
Report Upstream:  N/A  Work issues:  
Branch:  be9d130 (Commits, GitHub, GitLab)  Commit:  be9d130b08e6c3e5ce3b2e8026080ed03a932b7a 
Dependencies:  Stopgaps: 
Description
Mathematica may return exp(x) as E^x
. This is missed by our current translation to Sage, both in the sage
method of objects with Mathematica
parent and in the "mathematica_free" integrator.
Clarification by exemple:
var('x a b') (x, a, b) assume(b > 0) f = (exp((xa)/b) + 1)**(1) (f*f).integrate(x, algorithm="mathematica_free") b*log(1/E^((a  x)/b) + 1) + x + b/(1/E^((a  x)/b) + 1)
Exploration shows that in this symbolic expression, E is taken as the Gap function E (returns the "n"th root of unity as an element of the universal cyclotomic field).
However:
mathematica.Integrate(f^2,x).sage(locals={"E":e}) b*log(e^((a  x)/b) + 1) + x + b/(e^((a  x)/b) + 1)
which is correct:
integrate(f^2,x) b*log(e^(a/b + x/b) + 1)  a + x + b/(e^(a/b + x/b) + 1)
This simple workaround, however, cannot be used with Sage objects returned by integrate(..., algorithm="mathematica_free")
. A fix to our translation is needed. It doesn't seems obvious, since e
translation is handled by exp
.
Change History (19)
comment:1 Changed 14 months ago by
comment:2 followup: ↓ 3 Changed 14 months ago by
That's right, that is the correct place to handle such translations.
comment:3 in reply to: ↑ 2 Changed 14 months ago by
Replying to kcrisman:
That's right, that is the correct place to handle such translations.
This won't work. From src/sage/symbolic/constants.py
:
# The base of the natural logarithm, e, is not a constant in GiNaC/Sage. It is # represented by exp(1). A dummy class to make this work with arithmetic and # coercion is implemented in the module sage.symbolic.constants_c for speed.
At the time other constants are initialized by constants.pyx
, e
isn't yet available. And I wasn't able to make it available at the end of the _init__
method for exponentian in constant_c.pyx
.
Hints ?
comment:4 Changed 14 months ago by
Sorry, I had forgotten about the special case. Hmm... how does it handle other similar conversions, or are they all lowercase?
comment:5 Changed 14 months ago by
 Branch set to u/charpent/translate_mathematica_s__e__as_e
comment:6 Changed 14 months ago by
 Commit set to 5fa13e0b9be188e898defdd33abe52fdb2d01caf
 Status changed from new to needs_review
This can be done in the same constants.py
file, but after global definition of e
. Doctested in the mathematica.py
interface (passes for me).
===>needs_review
.
New commits:
5fa13e0  Backtranslate Mathematica's E exponential symbol to Sage's e.

comment:8 followup: ↓ 10 Changed 14 months ago by
 Reviewers set to KarlDieter Crisman
 Status changed from needs_review to needs_work
Thanks for fixing this, that was definitely an oversight  Maxima also has a weird symbol for e
but we handle that with a perhaps somewhat stupid removal of %
signs in strings, if I recall correctly, which wouldn't work so well here. A few comments:
 You might as well add the original example as a test somewhere (perhaps in the integration file), because that provides an opportunity to test for regression in two ways then  one with people who have Mathematica, the other with people who might run internet tests. Something like this?
sage: (x,a,b)=var('x a b') sage: assume(b > 0) sage: f = (exp((xa)/b) + 1)**(1) sage: (f*f).integrate(x, algorithm="mathematica_free") # optional  internet b*log(e^((a  x)/b) + 1) + x + b/(e^((a  x)/b) + 1)
 You have this already earlier in the file:
from sage.libs.pynac.pynac import register_symbol, I
and the function is used, so do you need the wholefoo
construction? Seems likeregister_symbol
should be available. bachtranslated
> I am a big fan of Bach, but didn't know he also was responsible for the natural base of the logarithm! :)
comment:9 Changed 14 months ago by
 Commit changed from 5fa13e0b9be188e898defdd33abe52fdb2d01caf to f37400a8e527c2c755a4619a7ee1bce3e41519a9
Branch pushed to git repo; I updated commit sha1. New commits:
f37400a  Mathematica's E backtranslation: typo/thinko fixes, more doctests.

comment:10 in reply to: ↑ 8 ; followup: ↓ 11 Changed 14 months ago by
 Status changed from needs_work to needs_review
Replying to kcrisman:
Thanks for fixing this, that was definitely an oversight  Maxima also has a weird symbol for
e
but we handle that with a perhaps somewhat stupid removal of%
signs in strings, if I recall correctly, which wouldn't work so well here. A few comments:
 You might as well add the original example as a test somewhere (perhaps in the integration file), because that provides an opportunity to test for regression in two ways then  one with people who have Mathematica, the other with people who might run internet tests. Something like this?
sage: (x,a,b)=var('x a b') sage: assume(b > 0) sage: f = (exp((xa)/b) + 1)**(1) sage: (f*f).integrate(x, algorithm="mathematica_free") # optional  internet b*log(e^((a  x)/b) + 1) + x + b/(e^((a  x)/b) + 1)
Done (in integration.py
).
 You have this already earlier in the file:
from sage.libs.pynac.pynac import register_symbol, Iand the function is used, so do you need the wholefoo
construction? Seems likeregister_symbol
should be available.
That was a nice thinko. Thanks for catching this !
bachtranslated
> I am a big fan of Bach, but didn't know he also was responsible for the natural base of the logarithm! :)
The musical scale is naturally logarithmic. Any musician uses it without having to be responsible for anything. ;) Typo nevertheless fixed.
==>needs_review
.
comment:11 in reply to: ↑ 10 Changed 14 months ago by
From my point of view this is fine, thanks for the quick work. I would want (as per usual with me and my inability to keep a working branch anywhere near develop) someone to do the doctest running. (I never know if we are supposed to trust the patchbot.)
bachtranslated
> I am a big fan of Bach, but didn't know he also was responsible for the natural base of the logarithm! :)The musical scale is naturally logarithmic. Any musician uses it without having to be responsible for anything. ;) Typo nevertheless fixed.
Let's not start getting into arguments over equal temperament versus Pythagorean tuning  after all, it's only the base 2 log that all agree on using :)
comment:12 followup: ↓ 13 Changed 14 months ago by
 Status changed from needs_review to needs_work
The code block in integral.py needs to be indented.
comment:13 in reply to: ↑ 12 Changed 14 months ago by
comment:14 Changed 14 months ago by
There is just one. ;)
Check for :trac:`29833`::  sage: (x,a,b)=var('x a b')  sage: assume(b > 0)  sage: f = (exp((xa)/b) + 1)**(1)  sage: (f*f).integrate(x, algorithm="mathematica_free") # optional  internet  b*log(e^((a  x)/b) + 1) + x + b/(e^((a  x)/b) + 1) + sage: (x,a,b)=var('x a b') + sage: assume(b > 0) + sage: f = (exp((xa)/b) + 1)**(1) + sage: (f*f).integrate(x, algorithm="mathematica_free") # optional  internet + b*log(e^((a  x)/b) + 1) + x + b/(e^((a  x)/b) + 1)
comment:15 Changed 14 months ago by
Also, please apply this change. Otherwise, the optional tests do not actually pass, as both x
and e
were set to something different in preceding tests.

src/sage/interfaces/mathematica.py
a b We find the `x` such that `e^x  3x = 0`. 172 172 173 173 :: 174 174 175 sage: e = mathematica('Exp[x]  3x == 0') # optional  mathematica176 sage: e .FindRoot(['x', 2]) # optional  mathematica175 sage: eqn = mathematica('Exp[x]  3x == 0') # optional  mathematica 176 sage: eqn.FindRoot(['x', 2]) # optional  mathematica 177 177 {x > 1.512134551657842} 178 178 179 179 Note that this agrees with what the PARI interpreter gp produces:: … … correctly (:trac:`18888`, :trac:`28907`):: 358 358 Check that Mathematica's `E` exponential symbol is correctly backtranslated 359 359 as Sage's `e` (:trac:`29833`):: 360 360 361 sage: x = var('x') 361 362 sage: (e^x)._mathematica_().sage() # optional  mathematica 362 363 e^x 363 364 sage: exp(x)._mathematica_().sage() # optional  mathematica
comment:16 Changed 14 months ago by
 Commit changed from f37400a8e527c2c755a4619a7ee1bce3e41519a9 to be9d130b08e6c3e5ce3b2e8026080ed03a932b7a
Branch pushed to git repo; I updated commit sha1. New commits:
be9d130  Backtranslate Mathematica's E to Sage's e : assorted fixes.

comment:17 Changed 14 months ago by
 Status changed from needs_work to needs_review
The changes suggested by ghmwageringel
are sound, applied.
==>needs_review
.
comment:18 Changed 14 months ago by
 Reviewers changed from KarlDieter Crisman to KarlDieter Crisman, Markus Wageringel
 Status changed from needs_review to positive_review
Ok, thank you for fixing this.
comment:19 Changed 13 months ago by
 Branch changed from u/charpent/translate_mathematica_s__e__as_e to be9d130b08e6c3e5ce3b2e8026080ed03a932b7a
 Resolution set to fixed
 Status changed from positive_review to closed
This can be solved by adding
E
to the symbol table, which takes care of the conversion from Mathematica to Sage. This should probably be added tosage.symbolic.constants
.