Skip to content

Conversation

@oscargus
Copy link
Contributor

@oscargus oscargus commented Jun 23, 2019

References to other Issues or PRs

Brief description of what is fixed or changed

Unfortunately this is a mess of fixes, although all are related to printing. Probably the easiest is to check the release notes and the code to see what has changed. I will add some before and after tables in the comments.

No tests yet, but they will come.

Other comments

Release Notes

  • printing
    • erf2 and Li are printed using erfand li, respectively, if the latter is supported, but not the former for all code printers.
    • Better LambertW printing for LaTeX, pretty, and MathML presentation.
    • Mathematica printing for many special functions added.
    • Some functions added to Octave printer.
    • Some functions added to pretty printer.

@sympy-bot
Copy link

sympy-bot commented Jun 23, 2019

Hi, I am the SymPy bot (v147). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

  • printing
    • erf2 and Li are printed using erfand li, respectively, if the latter is supported, but not the former for all code printers. (#17080 by @oscargus)

    • Better LambertW printing for LaTeX, pretty, and MathML presentation. (#17080 by @oscargus)

    • Mathematica printing for many special functions added. (#17080 by @oscargus)

    • Some functions added to Octave printer. (#17080 by @oscargus)

    • Some functions added to pretty printer. (#17080 by @oscargus)

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.5.

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it.

Click here to see the pull request description that was parsed.

<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234". See
https://github.com/blog/1506-closing-issues-via-pull-requests . Please also
write a comment on that issue linking back to this pull request once it is
open. -->


#### Brief description of what is fixed or changed
Unfortunately this is a mess of fixes, although all are related to printing. Probably the easiest is to check the release notes and the code to see what has changed. I will add some before and after tables in the comments.

No tests yet, but they will come.



#### Other comments


#### Release Notes

<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. The bot will check your release notes
automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* printing 
   * `erf2` and `Li` are printed using `erf`and `li`, respectively, if the latter is supported, but not the former for all code printers.
   * Better `LambertW` printing for LaTeX, pretty, and MathML presentation.
   * Mathematica printing for many special functions added.
   * Some functions added to Octave printer.
   * Some functions added to pretty printer.

<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

@oscargus
Copy link
Contributor Author

Resulting code for Mathematica and Octave printers for almost all functions in sympy.functions.special

Before:

Str Mathematica Octave
DiracDelta(x) DiracDelta[x] dirac(x)
Heaviside(x) Heaviside[x] heaviside(x)
SingularityFunction(x, a, n) SingularityFunction[x, a, n] % Not supported in Octave:
% SingularityFunction
SingularityFunction(x, a, n)
gamma(x) Gamma[x] gamma(x)
polygamma(x, y) PolyGamma[x, y] psi(x, y)
polygamma(0, x) PolyGamma[0, x] psi(0, x)
polygamma(1, x) PolyGamma[1, x] psi(1, x)
uppergamma(n, x) Gamma[n, x] (gammainc(x, n, 'upper').*gamma(n))
lowergamma(n, x) lowergamma[n, x] (gammainc(x, n).*gamma(n))
beta(x, y) Beta[x, y] beta(x, y)
erf(x) Erf[x] erf(x)
erfc(x) Erfc[x] erfc(x)
erfi(x) Erfi[x] erfi(x)
erf2(x, y) Erf[x, y] % Not supported in Octave:
% erf2
erf2(x, y)
erfinv(x) InverseErf[x] erfinv(x)
erfcinv(x) InverseErfc[x] erfcinv(x)
erf2inv(x, y) InverseErf[x, y] % Not supported in Octave:
% erf2inv
erf2inv(x, y)
fresnels(x) FresnelS[x] fresnels(x)
fresnelc(x) FresnelC[x] fresnelc(x)
Ei(x) ExpIntegralEi[x] % Not supported in Octave:
% Ei
Ei(x)
expint(a, x) ExpIntegralE[a, x] % Not supported in Octave:
% expint
expint(a, x)
expint(1, x) ExpIntegralE[1, x] expint(x)
li(x) LogIntegral[x] logint(x)
Li(x) Li[x] % Not supported in Octave:
% Li
Li(x)
Si(x) SinIntegral[x] sinint(x)
Ci(x) CosIntegral[x] cosint(x)
Shi(x) SinhIntegral[x] sinhint(x)
Chi(x) CoshIntegral[x] coshint(x)
besselj(n, x) besselj[n, x] besselj(n, x)
bessely(n, x) bessely[n, x] bessely(n, x)
besseli(n, x) besseli[n, x] besseli(n, x)
besselk(n, x) besselk[n, x] besselk(n, x)
hankel1(n, x) hankel1[n, x] besselh(n, 1, x)
hankel2(n, x) hankel2[n, x] besselh(n, 2, x)
jn(n, x) jn[n, x] sqrt(2)*sqrt(pi)*sqrt(1./x).*besselj(n + 1/2, x)/2
yn(n, x) yn[n, x] sqrt(2)*sqrt(pi)*sqrt(1./x).*bessely(n + 1/2, x)/2
airyai(x) airyai[x] airy(0, x)
airybi(x) airybi[x] airy(2, x)
airyaiprime(x) airyaiprime[x] airy(1, x)
airybiprime(x) airybiprime[x] airy(3, x)
zeta(x, y) zeta[x, y] % Not supported in Octave:
% zeta
zeta(x, y)
dirichlet_eta(x) dirichlet_eta[x] % Not supported in Octave:
% dirichlet_eta
dirichlet_eta(x)
polylog(n, x) polylog[n, x] polylog(n, x)
lerchphi(x, y, z) lerchphi[x, y, z] % Not supported in Octave:
% lerchphi
lerchphi(x, y, z)
stieltjes(n) stieltjes[n] % Not supported in Octave:
% stieltjes
stieltjes(n)
stieltjes(n, m) stieltjes[n, m] % Not supported in Octave:
% stieltjes
stieltjes(n, m)
hyper((n, m, y), (z, a), x) hyper[{n, m, y}, {z, a}, x] % Not supported in Octave:
% hyper
hyper((n, m, y), (z, a), x)
meijerg(((y, z), (a, b)), ((m,), ()), x) meijerg[{{y, z}, {a, b}}, {{m}, {}}, x] % Not supported in Octave:
% meijerg
meijerg(((y, z), (a, b)), ((m,), ()), x)
elliptic_k(x) elliptic_k[x] % Not supported in Octave:
% elliptic_k
elliptic_k(x)
elliptic_f(x, y) elliptic_f[x, y] % Not supported in Octave:
% elliptic_f
elliptic_f(x, y)
elliptic_e(x) elliptic_e[x] % Not supported in Octave:
% elliptic_e
elliptic_e(x)
elliptic_e(x, y) elliptic_e[x, y] % Not supported in Octave:
% elliptic_e
elliptic_e(x, y)
elliptic_pi(x, y) elliptic_pi[x, y] % Not supported in Octave:
% elliptic_pi
elliptic_pi(x, y)
elliptic_pi(x, y, z) elliptic_pi[x, y, z] % Not supported in Octave:
% elliptic_pi
elliptic_pi(x, y, z)
mathieus(x, y, z) mathieus[x, y, z] % Not supported in Octave:
% mathieus
mathieus(x, y, z)
mathieuc(x, y, z) mathieuc[x, y, z] % Not supported in Octave:
% mathieuc
mathieuc(x, y, z)
mathieusprime(x, y, z) mathieusprime[x, y, z] % Not supported in Octave:
% mathieusprime
mathieusprime(x, y, z)
mathieucprime(x, y, z) mathieucprime[x, y, z] % Not supported in Octave:
% mathieucprime
mathieucprime(x, y, z)
jacobi(n, a, b, z) JacobiP[n, a, b, z] % Not supported in Octave:
% jacobi
jacobi(n, a, b, z)
gegenbauer(n, a, x) GegenbauerC[n, a, x] % Not supported in Octave:
% gegenbauer
gegenbauer(n, a, x)
chebyshevt(n, x) ChebyshevT[n, x] chebyshevT(n, x)
chebyshevu(n, x) ChebyshevU[n, x] chebyshevU(n, x)
legendre(n, x) LegendreP[n, x] % Not supported in Octave:
% legendre
legendre(n, x)
assoc_legendre(n, m, x) LegendreP[n, m, x] % Not supported in Octave:
% assoc_legendre
assoc_legendre(n, m, x)
hermite(n, x) HermiteH[n, x] % Not supported in Octave:
% hermite
hermite(n, x)
laguerre(n, x) LaguerreL[n, x] laguerreL(n, x)
assoc_laguerre(n, m, x) LaguerreL[n, m, x] % Not supported in Octave:
% assoc_laguerre
assoc_laguerre(n, m, x)
Ynm(n, m, x, y) Ynm[n, m, x, y] % Not supported in Octave:
% Ynm
Ynm(n, m, x, y)
Znm(n, m, x, y) Znm[n, m, x, y] % Not supported in Octave:
% Znm
Znm(n, m, x, y)
LeviCivita(x, y, z) LeviCivita[x, y, z] % Not supported in Octave:
% LeviCivita
LeviCivita(x, y, z)
KroneckerDelta(x, y) KroneckerDelta[x, y] double(x == y)
LambertW(x) LambertW[x] lambertw(x)

After:

Str Mathematica Octave
DiracDelta(x) DiracDelta[x] dirac(x)
Heaviside(x) HeavisideTheta[x] heaviside(x)
SingularityFunction(x, a, n) (* Not supported in Wolfram Language: *)
(* SingularityFunction *)
SingularityFunction[x, a, n]
% Not supported in Octave:
% SingularityFunction
SingularityFunction(x, a, n)
gamma(x) Gamma[x] gamma(x)
polygamma(x, y) PolyGamma[x, y] psi(x, y)
polygamma(0, x) PolyGamma[0, x] psi(0, x)
polygamma(1, x) PolyGamma[1, x] psi(1, x)
uppergamma(n, x) Gamma[n, x] (gammainc(x, n, 'upper').*gamma(n))
lowergamma(n, x) (* Not supported in Wolfram Language: *)
(* lowergamma *)
lowergamma[n, x]
(gammainc(x, n).*gamma(n))
beta(x, y) Beta[x, y] beta(x, y)
erf(x) Erf[x] erf(x)
erfc(x) Erfc[x] erfc(x)
erfi(x) Erfi[x] erfi(x)
erf2(x, y) Erf[x, y] -erf(x) + erf(y)
erfinv(x) InverseErf[x] erfinv(x)
erfcinv(x) InverseErfc[x] erfcinv(x)
erf2inv(x, y) InverseErf[x, y] % Not supported in Octave:
% erf2inv
erf2inv(x, y)
fresnels(x) FresnelS[x] fresnels(x)
fresnelc(x) FresnelC[x] fresnelc(x)
Ei(x) ExpIntegralEi[x] % Not supported in Octave:
% Ei
Ei(x)
expint(a, x) ExpIntegralE[a, x] % Not supported in Octave:
% expint
expint(a, x)
expint(1, x) ExpIntegralE[1, x] expint(x)
li(x) LogIntegral[x] logint(x)
Li(x) LogIntegral[x] - LogIntegral[2] logint(x) - logint(2)
Si(x) SinIntegral[x] sinint(x)
Ci(x) CosIntegral[x] cosint(x)
Shi(x) SinhIntegral[x] sinhint(x)
Chi(x) CoshIntegral[x] coshint(x)
besselj(n, x) BesselJ[n, x] besselj(n, x)
bessely(n, x) BesselY[n, x] bessely(n, x)
besseli(n, x) BesselI[n, x] besseli(n, x)
besselk(n, x) BesselK[n, x] besselk(n, x)
hankel1(n, x) HankelH1[n, x] besselh(n, 1, x)
hankel2(n, x) HankelH2[n, x] besselh(n, 2, x)
jn(n, x) SphericalBesselJ[n, x] sqrt(2)*sqrt(pi)*sqrt(1./x).*besselj(n + 1/2, x)/2
yn(n, x) SphericalBesselY[n, x] sqrt(2)*sqrt(pi)*sqrt(1./x).*bessely(n + 1/2, x)/2
airyai(x) AiryAi[x] airy(0, x)
airybi(x) AiryBi[x] airy(2, x)
airyaiprime(x) AiryAiPrime[x] airy(1, x)
airybiprime(x) AiryBiPrime[x] airy(3, x)
zeta(x, y) Zeta[x, y] % Not supported in Octave:
% zeta
zeta(x, y)
dirichlet_eta(x) (* Not supported in Wolfram Language: *)
(* dirichlet_eta *)
dirichlet_eta[x]
% Not supported in Octave:
% dirichlet_eta
dirichlet_eta(x)
polylog(n, x) PolyLog[n, x] polylog(n, x)
lerchphi(x, y, z) LerchPhi[x, y, z] % Not supported in Octave:
% lerchphi
lerchphi(x, y, z)
stieltjes(n) StieltjesGamma[n] % Not supported in Octave:
% stieltjes
stieltjes(n)
stieltjes(n, m) Exception % Not supported in Octave:
% stieltjes
stieltjes(n, m)
hyper((n, m, y), (z, a), x) HypergeometricPFQ[{n, m, y}, {z, a}, x] % Not supported in Octave:
% hyper
hyper((n, m, y), (z, a), x)
meijerg(((y, z), (a, b)), ((m,), ()), x) MeijerG[{{y, z}, {a, b}}, {{m}, {}}, x] % Not supported in Octave:
% meijerg
meijerg(((y, z), (a, b)), ((m,), ()), x)
elliptic_k(x) EllipticK[x] % Not supported in Octave:
% elliptic_k
elliptic_k(x)
elliptic_f(x, y) EllipticE[x, y] % Not supported in Octave:
% elliptic_f
elliptic_f(x, y)
elliptic_e(x) EllipticE[x] % Not supported in Octave:
% elliptic_e
elliptic_e(x)
elliptic_e(x, y) EllipticE[x, y] % Not supported in Octave:
% elliptic_e
elliptic_e(x, y)
elliptic_pi(x, y) EllipticPi[x, y] % Not supported in Octave:
% elliptic_pi
elliptic_pi(x, y)
elliptic_pi(x, y, z) EllipticPi[x, y, z] % Not supported in Octave:
% elliptic_pi
elliptic_pi(x, y, z)
mathieus(x, y, z) MathieuS[x, y, z] % Not supported in Octave:
% mathieus
mathieus(x, y, z)
mathieuc(x, y, z) MathieuC[x, y, z] % Not supported in Octave:
% mathieuc
mathieuc(x, y, z)
mathieusprime(x, y, z) MathieuSPrime[x, y, z] % Not supported in Octave:
% mathieusprime
mathieusprime(x, y, z)
mathieucprime(x, y, z) MathieuCPrime[x, y, z] % Not supported in Octave:
% mathieucprime
mathieucprime(x, y, z)
jacobi(n, a, b, z) JacobiP[n, a, b, z] % Not supported in Octave:
% jacobi
jacobi(n, a, b, z)
gegenbauer(n, a, x) GegenbauerC[n, a, x] % Not supported in Octave:
% gegenbauer
gegenbauer(n, a, x)
chebyshevt(n, x) ChebyshevT[n, x] chebyshevT(n, x)
chebyshevu(n, x) ChebyshevU[n, x] chebyshevU(n, x)
legendre(n, x) LegendreP[n, x] legendre(n, x)
assoc_legendre(n, m, x) LegendreP[n, m, x] % Not supported in Octave:
% assoc_legendre
assoc_legendre(n, m, x)
hermite(n, x) HermiteH[n, x] % Not supported in Octave:
% hermite
hermite(n, x)
laguerre(n, x) LaguerreL[n, x] laguerreL(n, x)
assoc_laguerre(n, m, x) LaguerreL[n, m, x] % Not supported in Octave:
% assoc_laguerre
assoc_laguerre(n, m, x)
Ynm(n, m, x, y) (* Not supported in Wolfram Language: *)
(* Ynm *)
Ynm[n, m, x, y]
% Not supported in Octave:
% Ynm
Ynm(n, m, x, y)
Znm(n, m, x, y) (* Not supported in Wolfram Language: *)
(* Znm *)
Znm[n, m, x, y]
% Not supported in Octave:
% Znm
Znm(n, m, x, y)
LeviCivita(x, y, z) (* Not supported in Wolfram Language: *)
(* LeviCivita *)
LeviCivita[x, y, z]
% Not supported in Octave:
% LeviCivita
LeviCivita(x, y, z)
KroneckerDelta(x, y) KroneckerDelta[x, y] double(x == y)
LambertW(x) ProductLog[x] lambertw(x)

Note that it says that some Mathematica functions are not supported in the after table. They were not supported earlier either. Just that it wasn't shown.

@oscargus
Copy link
Contributor Author

Primarily pretty printing (MathML in another PR in preparation).

Before:

image

After:

image

@jmig5776
Copy link
Member

It seems from travis build that some of the doctests are failing.

return self._print_Function(expr)
else:
from sympy.functions.special.error_functions import erf
return self._print(erf(expr.args[1]) - erf(expr.args[0]))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe should do rewrite here instead.

return self._print_Function(expr)
else:
from sympy.functions.special.error_functions import li
return self._print(li(expr.args[0]) - li(2))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here.

@oscargus
Copy link
Contributor Author

Yes, both because e.g. LambertW is now printed as W and because the "Not supported"-comments in Mathematica. Not sure if it was a good idea to add those... This is not really the output that one would prefer:

Expected:
    T*x[-T]*Sin[(T + t)/T]/(T + t) + T*x[T]*Sin[(-T + t)/T]/(-T + t) + T*x[0]*Sin[
    t/T]/t
Got:
                          (* Not supported in Wolfram Language: *)                
                                          (* x *)                                 
                                          (* x *)                                 
                                          (* x *)                                 
    T*x[-T]*Sin[(T + t)/T]/(T + t) + T*x[T]*Sin[(-T + t)/T]/(-T + t) + T*x[0]*Sin[
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    t/T]/t

will look more into it later.

Will update the failing tests once I add tests for the new code.

@codecov
Copy link

codecov bot commented Jun 25, 2019

Codecov Report

Merging #17080 into master will decrease coverage by 0.007%.
The diff coverage is 100%.

@@              Coverage Diff              @@
##            master    #17080       +/-   ##
=============================================
- Coverage   74.459%   74.451%   -0.008%     
=============================================
  Files          623       623               
  Lines       161114    161159       +45     
  Branches     37814     37827       +13     
=============================================
+ Hits        119964    119986       +22     
- Misses       35820     35847       +27     
+ Partials      5330      5326        -4

@oscargus oscargus changed the title [WIP] Many different printing fixes Many different printing fixes Jun 25, 2019
@oscargus
Copy link
Contributor Author

Some updates:

I removed the unsupported function printing for Mathematica (and updated the release notes). It makes sense to not have it since Mathematica just leaves unknown functions as an undefined function.

I added a dict in CodePrinter, _rewriteable_functions which contains suggestions for "simple" rewrites that can be applied to an unsupported function. This can of course be done arbitrarily large (and maybe even automatically generated), but currently the idea is just to have some hand-coded suggestions that commonly shows up. Probably one can remove a bit of the current printing code as well. For example, the Octave printer seems to rely on rewriting a bit and this can be a way to simplify that code by overloading the rewrite dictionary.

From my side, this is good to go.

@oscarbenjamin
Copy link
Collaborator

Looks good

@oscarbenjamin oscarbenjamin merged commit f216b9d into sympy:master Jun 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants