#29833 closed defect (fixed)

Translate Mathematica's "E" as e

Reported by: charpent Owned by:
Priority: major Milestone: sage-9.2
Component: interfaces Keywords:
Cc: Merged in:
Authors: Emmanuel Charpentier Reviewers: Karl-Dieter Crisman, Markus Wageringel
Report Upstream: N/A Work issues:
Branch: be9d130 (Commits, GitHub, GitLab) Commit: be9d130b08e6c3e5ce3b2e8026080ed03a932b7a
Dependencies: Stopgaps:

Status badges

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((x-a)/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 gh-mwageringel

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 to sage.symbolic.constants.

sage: from sage.libs.pynac.pynac import register_symbol
sage: register_symbol(e, {'mathematica': 'E'})
sage: (f*f).integrate(x, algorithm="mathematica_free")
-b*log(e^(-(a - x)/b) + 1) + x + b/(e^(-(a - x)/b) + 1)

comment:2 follow-up: Changed 14 months ago by kcrisman

That's right, that is the correct place to handle such translations.

comment:3 in reply to: ↑ 2 Changed 14 months ago by charpent

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 kcrisman

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 charpent

  • Branch set to u/charpent/translate_mathematica_s__e__as_e

comment:6 Changed 14 months ago by charpent

  • 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:

5fa13e0Backtranslate Mathematica's E exponential symbol to Sage's e.

comment:7 Changed 14 months ago by charpent

  • Authors set to Emmanuel Charpentier

Forgot my name. Again...

comment:8 follow-up: Changed 14 months ago by kcrisman

  • Reviewers set to Karl-Dieter 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((x-a)/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 whole foo construction? Seems like register_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 git

  • Commit changed from 5fa13e0b9be188e898defdd33abe52fdb2d01caf to f37400a8e527c2c755a4619a7ee1bce3e41519a9

Branch pushed to git repo; I updated commit sha1. New commits:

f37400aMathematica's E backtranslation: typo/thinko fixes, more doctests.

comment:10 in reply to: ↑ 8 ; follow-up: Changed 14 months ago by charpent

  • 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((x-a)/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, I
    
    and the function is used, so do you need the whole foo construction? Seems like register_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 kcrisman

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 follow-up: Changed 14 months ago by gh-mwageringel

  • 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 charpent

Replying to gh-mwageringel:

The code block in integral.py needs to be indented.

Which one ?

comment:14 Changed 14 months ago by gh-mwageringel

There is just one. ;)

         Check for :trac:`29833`::

-        sage: (x,a,b)=var('x a b')
-        sage: assume(b > 0)
-        sage: f = (exp((x-a)/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((x-a)/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 gh-mwageringel

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`. 
    172172
    173173::
    174174
    175     sage: e = mathematica('Exp[x] - 3x == 0') # optional - mathematica
    176     sage: e.FindRoot(['x', 2])                # optional - mathematica
     175    sage: eqn = mathematica('Exp[x] - 3x == 0') # optional - mathematica
     176    sage: eqn.FindRoot(['x', 2])                # optional - mathematica
    177177    {x -> 1.512134551657842}
    178178
    179179Note that this agrees with what the PARI interpreter gp produces::
    correctly (:trac:`18888`, :trac:`28907`):: 
    358358Check that Mathematica's `E` exponential symbol is correctly backtranslated
    359359as Sage's `e` (:trac:`29833`)::
    360360
     361    sage: x = var('x')
    361362    sage: (e^x)._mathematica_().sage()  # optional -- mathematica
    362363    e^x
    363364    sage: exp(x)._mathematica_().sage() # optional -- mathematica

comment:16 Changed 14 months ago by git

  • Commit changed from f37400a8e527c2c755a4619a7ee1bce3e41519a9 to be9d130b08e6c3e5ce3b2e8026080ed03a932b7a

Branch pushed to git repo; I updated commit sha1. New commits:

be9d130Backtranslate Mathematica's E to Sage's e : assorted fixes.

comment:17 Changed 14 months ago by charpent

  • Status changed from needs_work to needs_review

The changes suggested by gh-mwageringel are sound, applied.

==>needs_review.

comment:18 Changed 14 months ago by gh-mwageringel

  • Reviewers changed from Karl-Dieter Crisman to Karl-Dieter Crisman, Markus Wageringel
  • Status changed from needs_review to positive_review

Ok, thank you for fixing this.

comment:19 Changed 13 months ago by vbraun

  • Branch changed from u/charpent/translate_mathematica_s__e__as_e to be9d130b08e6c3e5ce3b2e8026080ed03a932b7a
  • Resolution set to fixed
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.