# Translate Mathematica's "E" as e

Reported by: Owned by: charpent major sage-9.2 interfaces Emmanuel Charpentier Karl-Dieter Crisman, Markus Wageringel N/A be9d130 be9d130b08e6c3e5ce3b2e8026080ed03a932b7a

### 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`.

### 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: ↓ 3 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

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:

 ​5fa13e0 `Backtranslate 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: ↓ 10 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:

 ​f37400a `Mathematica's E backtranslation: typo/thinko fixes, more doctests.`

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

• Status changed from needs_work to needs_review

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: ↓ 13 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

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 We find the `x` such that `e^x - 3x = 0`. :: sage: e = mathematica('Exp[x] - 3x == 0') # optional - mathematica sage: e.FindRoot(['x', 2])                # optional - mathematica sage: eqn = mathematica('Exp[x] - 3x == 0') # optional - mathematica sage: eqn.FindRoot(['x', 2])                # optional - mathematica {x -> 1.512134551657842} Note that this agrees with what the PARI interpreter gp produces:: correctly (:trac:`18888`, :trac:`28907`):: Check that Mathematica's `E` exponential symbol is correctly backtranslated as Sage's `e` (:trac:`29833`):: sage: x = var('x') sage: (e^x)._mathematica_().sage()  # optional -- mathematica e^x 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:

 ​be9d130 `Backtranslate 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.