Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sage 9.6 special function translation issue with fricas. elliptic_ec #34058

Closed
nasser1 opened this issue Jun 23, 2022 · 33 comments
Closed

sage 9.6 special function translation issue with fricas. elliptic_ec #34058

nasser1 opened this issue Jun 23, 2022 · 33 comments

Comments

@nasser1
Copy link

nasser1 commented Jun 23, 2022

Using sagemath 9.6 and fricas 1.3.8.

Fricas solve this integral and returns ellipticF and ellipticE in result, both which take two arguments.

Sagemath seems to translate these to its own elliptic_ec for some reason, which takes only 1 argument and hence gives an exception.

Why did it not translate these to sagemath elliptic_f and elliptic_e? Both which are available in sagemath and take 2 arguments?

Here is an example

>sage
┌────────────────────────────────────────────────────────────────────┐
│ SageMath version 9.6, Release Date: 2022-05-15                     │
│ Using Python 3.10.4. Type "help()" for help.                       │
└────────────────────────────────────────────────────────────────────┘

sage: var('x a b d c e f')
(x, a, b, d, c, e, f)
sage: integrate((f*x^3+e*x^2+d*x+c)*(b*x^4+a)^(1/2),x,algorithm="fricas")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-d0465c613c1a> in <module>
----> 1 integrate((f*x**Integer(3)+e*x**Integer(2)+d*x+c)*(b*x**Integer(4)+a)**(Integer(1)/Integer(2)),x,algorithm="fricas")

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/misc/functional.py in integral(x, *args, **kwds)
    762     """
    763     if hasattr(x, 'integral'):
--> 764         return x.integral(*args, **kwds)
    765     else:
    766         from sage.symbolic.ring import SR

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.integral (build/cythonized/sage/symbolic/expression.cpp:95445)()
  13192                     R = SR
  13193             return R(integral(f, v, a, b, **kwds))
> 13194         return integral(self, *args, **kwds)
  13195
  13196     integrate = integral

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/symbolic/integration/integral.py in integrate(expression, v, a, b, algorithm, hold)
   1045         if not integrator:
   1046             raise ValueError("Unknown algorithm: %s" % algorithm)
-> 1047         return integrator(expression, v, a, b)
   1048     if a is None:
   1049         return indefinite_integral(expression, v, hold=hold)

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/symbolic/integration/external.py in fricas_integrator(expression, v, a, b, noPole)
    205             result = e_fricas.integrate(seg)
    206
--> 207     result = result.sage()
    208
    209     if result == "failed":

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/interface.py in sage(self, *args, **kwds)
   1104             [0 0]
   1105         """
-> 1106         return self._sage_(*args, **kwds)
   1107
   1108     def __repr__(self):

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _sage_(self)
   2048             # we treat Expression Integer and Expression Complex
   2049             # Integer just the same
-> 2050             return FriCASElement._sage_expression(P.get_InputForm(self._name))
   2051
   2052         if head == 'DistributedMultivariatePolynomial':

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _sage_expression(fricas_InputForm)
   1730         register_symbol(convert_rootOf, {'fricas': 'rootOf'})
   1731
-> 1732         ex, _ = FriCASElement._parse_and_eval(fricas_InputForm)
   1733         # postprocessing of rootOf
   1734         from sage.rings.all import QQbar, PolynomialRing

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_and_eval(s, start)
   1319
   1320         if s[a] == FriCASElement._LEFTBRACKET:
-> 1321             return FriCASElement._parse_list(s, start=a)
   1322         elif s[a] == FriCASElement._STRINGMARKER:
   1323             return FriCASElement._parse_string(s, start=a)

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_list(s, start)
   1361         args = []
   1362         while s[a] != FriCASElement._RIGHTBRACKET:
-> 1363             e, a = FriCASElement._parse_and_eval(s, start=a)
   1364             args.append(e)
   1365             a += 1

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_and_eval(s, start)
   1319
   1320         if s[a] == FriCASElement._LEFTBRACKET:
-> 1321             return FriCASElement._parse_list(s, start=a)
   1322         elif s[a] == FriCASElement._STRINGMARKER:
   1323             return FriCASElement._parse_string(s, start=a)

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_list(s, start)
   1361         args = []
   1362         while s[a] != FriCASElement._RIGHTBRACKET:
-> 1363             e, a = FriCASElement._parse_and_eval(s, start=a)
   1364             args.append(e)
   1365             a += 1

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_and_eval(s, start)
   1319
   1320         if s[a] == FriCASElement._LEFTBRACKET:
-> 1321             return FriCASElement._parse_list(s, start=a)
   1322         elif s[a] == FriCASElement._STRINGMARKER:
   1323             return FriCASElement._parse_string(s, start=a)

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_list(s, start)
   1361         args = []
   1362         while s[a] != FriCASElement._RIGHTBRACKET:
-> 1363             e, a = FriCASElement._parse_and_eval(s, start=a)
   1364             args.append(e)
   1365             a += 1

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_and_eval(s, start)
   1319
   1320         if s[a] == FriCASElement._LEFTBRACKET:
-> 1321             return FriCASElement._parse_list(s, start=a)
   1322         elif s[a] == FriCASElement._STRINGMARKER:
   1323             return FriCASElement._parse_string(s, start=a)

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_list(s, start)
   1361         args = []
   1362         while s[a] != FriCASElement._RIGHTBRACKET:
-> 1363             e, a = FriCASElement._parse_and_eval(s, start=a)
   1364             args.append(e)
   1365             a += 1

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_and_eval(s, start)
   1319
   1320         if s[a] == FriCASElement._LEFTBRACKET:
-> 1321             return FriCASElement._parse_list(s, start=a)
   1322         elif s[a] == FriCASElement._STRINGMARKER:
   1323             return FriCASElement._parse_string(s, start=a)

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/interfaces/fricas.py in _parse_list(s, start)
   1364             args.append(e)
   1365             a += 1
-> 1366         return fun(*args), a
   1367
   1368     @staticmethod

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/symbolic/function.pyx in sage.symbolic.function.BuiltinFunction.__call__ (build/cythonized/sage/symbolic/function.c:10972)()
   1031             res = self._evalf_try_(*args)
   1032             if res is None:
-> 1033                 res = super(BuiltinFunction, self).__call__(
   1034                         *args, coerce=coerce, hold=hold)
   1035

~/DATA/sage-9.6/local/var/lib/sage/venv-python3.10/lib/python3.10/site-packages/sage/symbolic/function.pyx in sage.symbolic.function.Function.__call__ (build/cythonized/sage/symbolic/function.c:5588)()
    513         """
    514         if self._nargs > 0 and len(args) != self._nargs:
--> 515             raise TypeError("Symbolic function %s takes exactly %s arguments (%s given)" % (self._name, self._nargs, len(args)))
    516
    517         # if the given input is a symbolic expression, we don't convert it back

TypeError: Symbolic function elliptic_ec takes exactly 1 arguments (2 given)

Here is the result using fricas directly

>fricas
FRICAS="/usr/local/lib/fricas/target/x86_64-linux-gnu"
spad-lib="/usr/local/lib/fricas/target/x86_64-linux-gnu/lib/libspad.so"
                       FriCAS Computer Algebra System
                            Version: FriCAS 1.3.8
                   Timestamp: Tue Jun 21 15:11:38 CDT 2022


(22) -> setSimplifyDenomsFlag(true)
(23) -> anti:=integrate((f*x^3+e*x^2+d*x+c)*(b*x^4+a)^(1/2),x);
(24) -> unparse(anti::InputForm)

  "(((-12)*a*e+20*b*c)*x*2^(1/2)*(((-4)*a)/b)^(1/2)*b^(1/2)*((((-4)*a)/b)^(1/2)
  )^(1/2)*ellipticF((((((-4)*a)/b)^(1/2))^(1/2))/(x*2^(1/2)),-1)+(12*a*e*x*2^(1
  /2)*(((-4)*a)/b)^(1/2)*b^(1/2)*((((-4)*a)/b)^(1/2))^(1/2)*ellipticE((((((-4)*
  a)/b)^(1/2))^(1/2))/(x*2^(1/2)),-1)+(15*a*d*x*b^(1/2)*log((-2)*b*x^2*(b*x^4+a
  )^(1/2)+((-2)*b*x^4+(-1)*a)*b^(1/2))+(20*b*f*x^5+24*b*e*x^4+30*b*d*x^3+40*b*c
  *x^2+20*a*f*x+48*a*e)*(b*x^4+a)^(1/2))))/(120*b*x)"

You can see Fricas result do not contain elliptic_ec

Is this a translation problem? Is there something I can do to fix this before running this integral? Right now many integrals are failing using fricas due to this when they should not be failing.

Here is link to sagemath documentation on special functions

Depends on #34062

Component: interfaces

Keywords: FriCAS

Author: Martin Rubey

Branch: 7a172e2

Reviewer: Frédéric Chapoton

Issue created by migration from https://trac.sagemath.org/ticket/34058

@nasser1 nasser1 added this to the sage-9.7 milestone Jun 23, 2022
@fchapoton
Copy link
Contributor

comment:1

see #34062

@mantepse
Copy link
Collaborator

comment:2

It seems that FriCAS' ellipticE is different from sage's elliptic_e:

sage: var("y")
y
sage: fricas.ellipticE(x, y).D(x)
 +---------+
 |   2
\|- x y + 1
------------
  +--------+
  |   2
 \|- x  + 1

sage: fricas.ellipticE(x, y).D(y)
- ellipticF(x,y) + ellipticE(x,y)
---------------------------------
               2 y

sage: ascii_art(elliptic_e(x, y).diff(x))
   _________________
  /        2        
\/  - y*sin (x) + 1 

sage: ascii_art(elliptic_e(x, y).diff(y))
E(x|y) - F(x|y)
---------------
      2*y      

Do you know the precise relationship?

@fchapoton
Copy link
Contributor

comment:3

a reference is 19.2.5 in

https://dlmf.nist.gov/19.2

@fchapoton
Copy link
Contributor

comment:4

see also the comment before (53) in

https://mathworld.wolfram.com/EllipticIntegral.html

which explains the different competing notations

EDIT:

see rather https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html

@fchapoton
Copy link
Contributor

comment:5

Fricas : E(z,m) = integrate(sqrt(1-m*t<sup>2)/sqrt(1-t</sup>2), t = 0..z)

Sage : E(phi,m) = integrate(sqrt(1-m*sin(t)^2), t = 0..phi)

So Fricas definition is non-standard but with respect to z !

Ugly conversion : z = sin(phi)

@mantepse
Copy link
Collaborator

comment:6

For the complete elliptic integral, we are fine?

@fchapoton
Copy link
Contributor

comment:7

yes, and there is already a doctest for that in

src/sage/functions/special.py

@mantepse
Copy link
Collaborator

@mantepse
Copy link
Collaborator

Commit: 24b6495

@mantepse
Copy link
Collaborator

comment:9

doctest will be provided tomorrow or so


New commits:

71528acfirst try at enhanced conversion system
b4a8566adding wish of doctest
f81a1ccmaple conversion of zeta derivatives
c76dbdadetail in fricas interface
c0bbbe4fix Fricas back conversion
24b6495provide conversion to incomplete elliptic integral

@mantepse
Copy link
Collaborator

Dependencies: #34062

@fchapoton
Copy link
Contributor

comment:11

not sure that it's a good idea to build upon #34062, which may be in a very unstable state

any idea why Fricas does not use the standard definitions ? already for dilog..

@mantepse
Copy link
Collaborator

comment:12

I'm not sure, but I think without #34062 it won't work, because fricas.ellipticE accepts one or two arguments.

@nasser1
Copy link
Author

nasser1 commented Jun 26, 2022

comment:13

Fyi, list of Fricas special functions and their signatures at

https://fricas.github.io/api/SpecialFunctionCategory.html

From the above:

ellipticE(m) is the complete elliptic integral of the second kind: ellipticE(m) = integrate(sqrt(1-m*t^2)/sqrt(1-t^2), t = 0..1).

ellipticE(z, m) is the incomplete elliptic integral of the second kind: ellipticE(z, m) = integrate(sqrt(1-m*t^2)/sqrt(1-t^2), t = 0..z).

@mantepse
Copy link
Collaborator

comment:14

Should we somehow deal that the conversion is only valid for phi between -pi/2 and pi/2?

@mantepse
Copy link
Collaborator

comment:15

re comment:11: I don't think it's nonstandard, see https://en.wikipedia.org/wiki/Elliptic_integral

@mantepse
Copy link
Collaborator

Changed keywords from fricas intergate symbolic to FriCAS

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jun 27, 2022

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

3916cdbadd doctest

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jun 27, 2022

Changed commit from 24b6495 to 3916cdb

@fchapoton
Copy link
Contributor

comment:18

Replying to @mantepse:

re comment:11: I don't think it's nonstandard, see https://en.wikipedia.org/wiki/Elliptic_integral

Wikipedia is not a valid reference for scientific purposes. It uses a confusing notation with functions E(*,*) and E(*;*).

@mantepse
Copy link
Collaborator

mantepse commented Jul 5, 2022

comment:19

Ping? (especially comment:14)

@fchapoton
Copy link
Contributor

comment:20

the doctest in /src/sage/functions/special.py is missing the # optional - fricas tag

and the doctest there must now start with r"""

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jul 5, 2022

Changed commit from 3916cdb to 7a172e2

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jul 5, 2022

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

7a172e2add missing optional - fricas tag

@fchapoton
Copy link
Contributor

Author: Martin Rubey

@fchapoton
Copy link
Contributor

comment:22

ok, let's go

note that the correct dilog function exists in fricas under then name li2. We should fix the forward conversion in another ticket.

@fchapoton
Copy link
Contributor

Reviewer: Frédéric Chapoton

@vbraun
Copy link
Member

vbraun commented Jul 10, 2022

@nasser1
Copy link
Author

nasser1 commented Jul 15, 2022

Changed commit from 7a172e2 to none

@nasser1
Copy link
Author

nasser1 commented Jul 15, 2022

comment:25

I tested this in sagemath 9.7 beta 5 on Linux.

But it is still not correct.

Even though there is no exception now, which is good, but the result from Fricas 1.3.8 returns ellipticF but there is no ellipticF in sagemath.

It should have been translated to sagemath elliptic_f ?

>./sage
┌────────────────────────────────────────────────────────────────────┐
│ SageMath version 9.7.beta5, Release Date: 2022-07-10               │
│ Using Python 3.10.5. Type "help()" for help.                       │
└────────────────────────────────────────────────────────────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Warning: this is a prerelease version, and it may be unstable.     ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
sage: var('a b c x d')
(a, b, c, x, d)
sage: integrate((b*x^2+a)^(1/2)*(d*x^2+c)^(1/2),x, algorithm="fricas")
1/3*((b*d^2*x^2 + b*c*d + a*d^2)*sqrt(b*x^2 + a)*sqrt(d*x^2 + c)*sqrt(b*d)*sqrt(-c/d) - (b^2*c^3 + a*b*c^2*d + 2*a*b*c*d^2)*x*ellipticF(sqrt(-c/d)/x, a*d/(b*c)) + (b^2*c^3 + a*b*c^2*d)*x*elliptic_e(arcsin(sqrt(-c/d)/x), a*d/(b*c)))/(sqrt(b*d)*b*d^2*x*sqrt(-c/d))
sage: ?ellipticF
Object `ellipticF` not found.


--Nasser

@nasser1
Copy link
Author

nasser1 commented Jul 15, 2022

comment:26

Should I open a new ticket on this new issues since this ticket is closed?

@mantepse
Copy link
Collaborator

comment:27

Yes, please!

@nasser1
Copy link
Author

nasser1 commented Jul 15, 2022

comment:28

OK. Created new ticket. Here is the link to it

#34186

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants