Opened 12 years ago

Closed 12 years ago

# [with patch, positive review] Enhanced Typesetting of Symbolic Functions

Reported by: Owned by: gmhossain cwitty major sage-4.1 symbolics Enhance Typesetting, LaTeX, Symbolic Functions burcin, jason, jhpalmieri, schymans sage-4.1.alpha0 Golam Mortuza Hossain Burcin Erocal

Here is a patch that enhances current typesetting capability of symbolic functions within sage.

This issue has been under a long discussion in the thread

Note: Switch to new symbolics has caused some functions to be changed

Main enhancements are:

(1) Symbolics functions with name in Greek letters (with possible suffixes), are typeset nicely in LaTeX.

Ex: psi(x) => \psi(x)

f0(x) => f_0(x)

(2) Functions such as "diff", "integrate", "limit", "conjugate", "laplace", "inverse_laplace" are now typeset within Sage itself.

Ex: integrate(f(x),x) => \int f(x) dx

(3) Default (fall-back) typesetting for unknown functions (as in Maxima).

Ex: myfn(x) => {\it myfn}(x)

(4) [ This is diasbled in new symbolics. However, equivalent feature will be available in new symbolics ] Allows users to define their own/custom LaTeX expression for any symbolic functions via a new method "set_latex()" for the class SymbolicFunctionEvaluation?.

Ex:

var('t');
hubble(t) = function('hubble',t)
hubble(t).set_latex('\\mathcal{H}')

#To reset custom LaTeX expression
hubble(t).set_latex()


(5) [ This has been disabled in new Symbolics as SymbolicVariable? class has changed ] If the arguments of a symbolic function are all symbolic variables then typesetting will avoid using \left(, \right).

Ex: Phi(x,y) => \Phi(x, y) (if x,y are symbolic vars)

(6) [New in the rebased patch] New symbolics uses "D" format for derivatives instead of old "diff" format. The rebased patch typesets symbolic derivatives in old "diff" format by default as in this format typeset version looks similar to those found in text books, journals.

However see this thread for known limitations of current conversion between these two formats

One can switch between two typesetting format as follows

f(x) = function('f',x)
g = diff(f(x),x)
latex(g)
\frac{d f\left(x\right)}{d x}
# Switch to D format
sage.symbolic.pynac.typeset_d_as_diff=False
latex(g)
D[0]f\left(x\right)


(7) [New in the rebased patch] The rebased patch resolves the issue

[Update: in v3 (4.0.2) ]

As suggested by Burcin in his referee report, following changes are made in the patch:

(1) Typesetting of "diff" is moved to a new ticket #6344

(2) Four helper functions _limit_latex_(), _integrate_latex_(), _laplace_latex_() and _inverse_laplace_latex_() have been moved to calculus/calculus.py. Then they are hooked to the instances of SFunction class by using dummy functions for better integration with the new symbolics.

(3) Four earlier functions latex_symbolic_function(), _symbolic_function_default_latex_(), _args_latex_(), _conjugate_latex() are removed.

(4) latex_function_name() is also replaced as the updated latex_variable_name() is augmented to take a new flag "is_fname". This will ensure that same typesetting convention is followed for both known functions such as \sin (:= {\rm sin}), \cos (:= {\rm cos}) and user defined function names such as "mysin" (=> {\rm mysin}).

### comment:3 Changed 12 years ago by jason

burcin: do you want to review this? Does the move to the new symbolics affect this patch?

### comment:4 follow-up: ↓ 5 Changed 12 years ago by jhpalmieri

• Summary changed from [with patch, needs review] Enhanced Typesetting of Symbolic Functions to [with patch, needs rebase] Enhanced Typesetting of Symbolic Functions

Patch doesn't apply cleanly against 4.0.1.

### comment:5 in reply to: ↑ 4 Changed 12 years ago by gmhossain

Patch doesn't apply cleanly against 4.0.1.

Yes, recent switch to new symbolics has affected this patch quite a bit. In fact, the class "SymbolicFunctionEvaluation?" (whose enhancement was aimed through this patch) doesn't exist anymore. I am now looking into the new symbolics code to properly rebase the patch.

### comment:6 Changed 12 years ago by gmhossain

• Description modified (diff)
• Summary changed from [with patch, needs rebase] Enhanced Typesetting of Symbolic Functions to [with patch, needs review] Enhanced Typesetting of Symbolic Functions

### comment:7 follow-ups: ↓ 10 ↓ 16 Changed 12 years ago by kcrisman

• Summary changed from [with patch, needs review] Enhanced Typesetting of Symbolic Functions to [with patch, partial positive review, needs review] Enhanced Typesetting of Symbolic Functions

This is really impressive. I assume that stan s and the others will want to review this more since they would use it more intensely and understand LaTeX better than I do, but I threw it a lot of stuff and the only "problems" I found were additional cases one might want, which could easily be a separate ticket after this is merged. The integrals, limits, Laplace, derivatives work out nice now, as does the option for D.

1. Only some underscore things do subscripts, and double subscripts don't work. That's fine, but might as well search for them if possible, e.g. HH_sigma or WWW_xy_z or something could also typeset.
2. The weird cases mentioned in various threads such as D[0](f)(sin(x)*cos(x)) look nice but have e.g. dcos(x)*sin(x) in the denominator, not giving Jason's suggestion of -(sin(x)2-cos(x)2)*\frac{df}{dx}(sin(x)*cos(x)). I assume that's okay but wanted to check.
3. There is still the same typesetting for e.g. variables mu and mu_. I think that sort of makes sense, since mu_1 and mu1 give the same thing, but it does seem strange.
4. Some stuff still doesn't work, but I don't know if it did before. For instance, sqrt(mu) is okay, but e(sqrt(mu)) is not, or even e(sqrt(x)). So #6211 can't be closed, not that you claimed it could - but it would fit naturally here. Check out show(efunction(f_mu,x)) for a real kick.
5. Limit and integral syntax don't (yet) allow multiple things for multiple variables, but since they are nested by parentheses it would be nice for those to show up, which they currently don't (however, they do calculate properly). This definitely is not within the purview of this ticket.

Great work from my view! Except I almost always declare my function f(x)=x2, not symbolic, so I will probably not use it much. But it will be good for subscripts for sure!

### comment:8 follow-up: ↓ 9 Changed 12 years ago by jhpalmieri

• Summary changed from [with patch, partial positive review, needs review] Enhanced Typesetting of Symbolic Functions to [with patch, needs work] Enhanced Typesetting of Symbolic Functions

This patch does not pass doctests on sage.math:

sage -t  "devel/sage/sage/symbolic/function.pyx"
**********************************************************************
File "/scratch/palmieri/sage-4.0.1/devel/sage/sage/symbolic/function.pyx", line 121:
sage: latex(foo(x,y^z))
Expected:
\mbox{t}\left(x, y^{z}\right)
Got:
t\left(x, y^{z}\right)
**********************************************************************
File "/scratch/palmieri/sage-4.0.1/devel/sage/sage/symbolic/function.pyx", line 129:
sage: latex(foo(x,y^z))
Expected:
\mbox{foo}\left(x, y^{z}\right)
Got:
foo\left(x, y^{z}\right)
**********************************************************************
2 of  45 in __main__.example_2
***Test Failed*** 2 failures.
For whitespace errors, see the file /scratch/palmieri/sage-4.0.1/tmp/.doctest_function.py
[1.2 s]
exit code: 1024


Should be easy enough to fix.

### comment:9 in reply to: ↑ 8 Changed 12 years ago by gmhossain

• Summary changed from [with patch, needs work] Enhanced Typesetting of Symbolic Functions to [with patch, needs review] Enhanced Typesetting of Symbolic Functions

Thanks! I have fixed these two doctest failure and updated the rebased patch.

### comment:10 in reply to: ↑ 7 Changed 12 years ago by gmhossain

Thanks kcrisman! As you have suggested, I would also prefer to fix only the blockers in this patch and leave other enhancements for follow-up patches.

1. Some stuff still doesn't work, but I don't know if it did before. For instance, sqrt(mu) is okay, but e(sqrt(mu)) is not, or even e(sqrt(x)). So #6211 can't be closed, not that you claimed it could - but it would fit naturally here. Check out show(efunction(f_mu,x)) for a real kick.

This seems to be a bug for "exp" function. Other functions such as "abs", "sin" etc work fine. I have posted my comments there with a easy fix. It would be better to have a separate patch for that bug.

### comment:11 in reply to: ↑ description ; follow-up: ↓ 12 Changed 12 years ago by burcin

• Component changed from misc to symbolics
• Summary changed from [with patch, needs review] Enhanced Typesetting of Symbolic Functions to [with patch, needs work] Enhanced Typesetting of Symbolic Functions

Hi Golam,

Thanks for your continued work on this. I see that your patch improves the typesetting of symbolic functions dramatically. I believe with a few improvements it would fit better in the new symbolics framework.

Here is my referee report:

Quotes from the description:

(2) Functions such as "diff", "integrate", "limit", "conjugate", "laplace", "inverse_laplace" are now typeset within Sage itself.

Ex: integrate(f(x),x) => \int f(x) dx

These should be handled using the custom printing facilities of sage.symbolic.function.SFunction. Special casing them in the new latex_symbolic_function() function is not scalable. This approach would also make the checks for the number of arguments as well as the calls to _symbolic_function_default_latex_() in each of these functions redundant.

I see that there is already a _limit function defined in sage/calculus/calculus.py. I think the best solution for the short term would be to put these printing functions there, and give them as an argument to the SFunction constructor.

sage: latex(x.conjugate())
\bar{x}


Why is \overline better?

(6) [New in the rebased patch] New symbolics uses "D" format for derivatives instead of old "diff" format. The rebased patch typesets symbolic derivatives in old "diff" format by default as in this format typeset version looks similar to those found in text books, journals.

However see this thread for known limitations of current conversion between these two formats

One can switch between two typesetting format as follows

f(x) = function('f',x)
g = diff(f(x),x)
latex(g)
\frac{d f\left(x\right)}{d x}
# Switch to D format
sage.symbolic.pynac.typeset_d_as_diff=False
latex(g)
D[0]f\left(x\right)


I believe this issue needs more debate, preferably with examples of how Maple and MMA handle this problem. I will post a new message about this to sage-devel soon. For now, I suggest we split this to a different ticket.

(1) Symbolics functions with name in Greek letters (with possible suffixes), are typeset nicely in LaTeX.

Ex: psi(x) => \psi(x)

f0(x) => f_0(x)

Can't this be handled by a call to the new latex_function_name() from sage.symbolic.pynac.py_latex_function_pystring()?

(3) Default (fall-back) typesetting for unknown functions (as in Maxima).

Ex: myfn(x) => {\it myfn}(x)

We have the GiNaC convention of falling back to \mbox at the moment. Previously, maxima didn't do anything for function names with one variable, and added an \it:

sage: version()
'Sage Version 3.4.2, Release Date: 2009-05-05'
sage: var('a')
a
sage: f = function('f')
sage: latex(f(a))
f\left(a\right)



As you mention in the docstring for latex_function_name(), there is considerable code duplication between this function and latex_variable_name(). Your previous response to my question about the differences between these two functions is here:

It seems that your goal of returning a different response as default behavior can be achieved by passing a parameter to the latex_varify() calls at the end of latex_variable_name(). Is there a reason why the further recursions performed by latex_variable_name() are not relevant for function names? In any case, the string processing code in latex_variable_name() shouldn't be duplicated.

(7) [New in the rebased patch] The rebased patch resolves the issue

This seems to be caused by a thinko on my part. It can be fixed by modifying lines 416-149 in sage/symbolic/pynac.pyx. You seem to do something similar at the end of latex_symbolic_function() and _symbolic_function_default_latex_() functions.

Overall I think the patch looks very crowded and confusing. With the changes suggested above,

• the new functions latex_symbolic_function(), _symbolic_function_default_latex_(), _args_latex_(), can be eliminated.
• derivative related functions latex_d_derivative() and _derivative_latex_() should be split to a new ticket.
• specialized printing functions _integrate_latex_(), _inverse_laplace_latex_(), _laplace_latex_(), _limit_latex_() should be moved to sage/calculus/calculus.py and hooked up to the right sage.symbolic.function.SFunction instance.
• _conjugate_latex_() doesn't seem necessary.

### comment:12 in reply to: ↑ 11 Changed 12 years ago by gmhossain

Thanks Burcin for your detailed review. See below for my responses. I would be happy to hear you back before I start making some of the changes, you have suggested.

(2) Functions such as "diff", "integrate", "limit", "conjugate", "laplace", "inverse_laplace" are now typeset within Sage itself.

These should be handled using the custom printing facilities of sage.symbolic.function.SFunction.

I fully agree! However, does new symbolics has such framework ready for the mentioned functions?

I see that there is already a _limit function defined in sage/calculus/calculus.py. I think the best solution for the short term would be to put these printing functions there, and give them as an argument to the SFunction constructor.

Could you please give an short example for such construction (my current understanding of new symbolics is limited)?

Why is it better to put these functions in calculus/calculus.py even as a "short term" solution? (I gather from William's note http://480.sagenb.org/home/pub/45/ that "calculus" direcotory is to be deleted. This conflicts with your suggestion.)

sage: latex(x.conjugate())
\bar{x}


Why is \overline better?

"\bar" is ok for variable but is insufficient for symbolic functions. Please try the followings in the notebook:

jsmath('\\bar{\\psi\\left(x, y\\right)}')
jsmath('\\overline{\\psi\\left(x, y\\right)}')


then you will see the reason yourself.

(6) [New in the rebased patch] New symbolics uses "D" format

I believe this issue needs more debate, I suggest we split this to a different ticket.

Sure, I will open a new ticket for this.

(1) Symbolics functions with name in Greek letters (with possible suffixes), are typeset nicely in LaTeX.

Ex: psi(x) => \psi(x)

f0(x) => f_0(x)

Can't this be handled by a call to the new latex_function_name() from sage.symbolic.pynac.py_latex_function_pystring()?

Provided all other symbolic "functions" ("integrate",...) have been typeset somewhere else which is not the case at present.

(3) Default (fall-back) typesetting for unknown functions (as in Maxima).

Ex: myfn(x) => {\it myfn}(x)

We have the GiNaC convention of falling back to \mbox at the moment.

Frankly, it is disappointing to see another inconsistent typesetting. Why should a function named "sin" should be typseset as "\sin" (=>"\rm sin") where as another function named "mysin" is typeset as "\mbox{mysin}"? Please compare them side-by-side to see the contrast.

Previously, maxima didn't do anything for function names with one variable, and added an \it:

So as in this patch! Though, I wanted to use "\rm" as {\rm myfunc} but decided to stick to maxima usage.

As you mention in the docstring for latex_function_name(), there is considerable code duplication between this function and latex_variable_name().

I agree that we should avoid duplication of code.

Is there a reason why the further recursions performed by latex_variable_name() are not relevant for function names?

In physics, we often use functions such as "f_{\alpha\beta}". In sage, if I use current latex_variable_name() to typeset "f_alpha_beta" then it would typeset as f_{{\alpha}_{\beta}} which is completely different.

However I guees, thats my own preference and I shouldn't argue anymore on this. I guess #6290 will solve my problem altogether.

I will remove latex_function_name() and use latex_variable_name() instead.

### comment:13 Changed 12 years ago by gmhossain

• Description modified (diff)
• Summary changed from [with patch, needs work] Enhanced Typesetting of Symbolic Functions to [with patch, needs review] Enhanced Typesetting of Symbolic Functions

Burcin: I have updated the patch as you suggested. List of changes is given in the description.

doctest fixes

### comment:14 Changed 12 years ago by burcin

• Summary changed from [with patch, needs review] Enhanced Typesetting of Symbolic Functions to [with patch, positive review] Enhanced Typesetting of Symbolic Functions

Thanks Golam. The patch looks good to me. I added a small patch that fixes doctests in two places.

Only apply

• trac_5711-enhanced-symbolic-typesetting-rebased_to_4.0.2.patch
• trac_5711-doctest_fixes.patch

### comment:15 Changed 12 years ago by rlm

• Authors set to Golam Mortuza Hossain
• Merged in set to sage-4.1.alpha0
• Resolution set to fixed
• Reviewers set to Burcin Erocal
• Status changed from new to closed

### comment:16 in reply to: ↑ 7 ; follow-up: ↓ 17 Changed 12 years ago by schymans

This is really impressive. I assume that stan s and the others will want to review this more since they would use it more intensely and understand LaTeX better than I do, but I threw it a lot of stuff and the only "problems" I found were additional cases one might want, which could easily be a separate ticket after this is merged. The integrals, limits, Laplace, derivatives work out nice now, as does the option for D.

1. Only some underscore things do subscripts, and double subscripts don't work. That's fine, but might as well search for them if possible, e.g. HH_sigma or WWW_xy_z or something could also typeset.

[Snip] I am very fond of the set_latex() method for defining custom latex representations, which would allow for multiple subscripts etc. Unfortunately, it has been disabled with the new symbolics. Is there a plan to re-enable it again? In general, I think that it would be nice to give as much control to the user as possible, rather than hard-coding certain latex representations. Sorry I haven't been of any help with reviewing/patching, but I only now got back to the typesetting issues and found that my previous ad-hoc latex definitions don't work in Sage 4.x any more. :(

Great work, anyway, and many thanks to those that invested time and effort into improving the typesetting in Sage!