# Ticket #5711: enhanced-typesetting-of-symbolic-functions.patch

File enhanced-typesetting-of-symbolic-functions.patch, 18.1 KB (added by gmhossain, 12 years ago)
• ## sage/calculus/calculus.py

# HG changeset patch
# User Golam Mortuza Hossain <gmhossain@gmail.com>
# Date 1239118264 10800
# Node ID e190effda0d16b5b703ee277674984613411b0ab
# Parent  17fe77f21e21c79cb989aaab2e2fe128d16beaa1
Enhances typsetting of Symbolic functions within Sage

diff -r 17fe77f21e21 -r e190effda0d1 sage/calculus/calculus.py
 a from sage.structure.parent_base import ParentWithBase import operator from sage.misc.latex import latex, latex_variable_name from sage.misc.latex import latex, latex_variable_name, latex_symbolic_function from sage.misc.misc import uniq as unique from sage.structure.sage_object import SageObject def _latex_(self): r""" Return a latex version of the function EXAMPLES:: sage: var("t,u") (t, u) sage: y=function('y',u) sage: z=function('z',t,u) sage: latex(y) y\left(u\right) sage: latex(diff(y,u)) {{{\it \partial}}\over{{\it \partial}\,u}}\,y\left(u\right) sage: latex(diff(y,u,3)) {{{\it \partial}^3}\over{{\it \partial}\,u^3}}\,y\left(u\right) sage: latex(diff(z,u)) {{{\it \partial}}\over{{\it \partial}\,u}}\,z\left(t , u\right) sage: latex(diff(z,u,t,u,t)) {{{\it \partial}^4}\over{{\it \partial}\,t^2\,{\it \partial}\,u^2}}  \,z\left(t , u\right) sage: latex(integrate(y,u)) \int {y\left(u\right)}{\;du} Return a LaTeX expression of the function. EXAMPLES:: sage: var('x,y,a,b,t,s') (x, y, a, b, t, s) sage: psi(x) = function('psi',x) sage: latex(psi(x)) \psi(x) sage: latex(psi(x).conjugate()) {\psi}^*(x) sage: latex(limit(psi(x),x=a)) \lim_{x \to a}\, \psi(x) sage: f(t) = function('f',t) sage: latex(laplace(f(t),t,s)) \mathcal{L}\left(f(t), t, s\right) sage: F(s) = function('F',s) sage: latex(inverse_laplace(F(s),s,t)) \mathcal{L}^{-1}\left(F(s), s, t\right) sage: f(x) = function('f',x) sage: latex(integrate(f(x),x)) \int f(x)\,{d x} sage: latex(integrate(f(x),x,a,b)) \int_{a}^{b} f(x)\,{d x} sage: var('x,y') (x, y) sage: f(x) = function('f',x) sage: latex(diff(f(x),x)) \frac{d f(x)}{d x} sage: f(x,y) = function('f',x,y) sage: latex(diff(f(x,y),x)) \frac{\partial}{\partial x}f(x, y) sage: myfunc(x) = function('myfunc',x) sage: latex(myfunc(x)) {\it myfunc}(x) sage: latex(derivative(ceil(x), x)) {{{\it \partial}}\over{{\it \partial}\,x}}\,\left \lceil x \right \rceil """ try: return  latex(self._maxima_()) except: return "{\\rm %s}(%s)"%(self._f._name, ', '.join([x._latex_() for x in self._args])) \frac{d \left \lceil x \right \rceil}{d x} """ return latex_symbolic_function(self) def set_latex(self, expr=None): r""" Set custom LaTeX expression for the given symbolic function. INPUTS: -  expr  -- a valid LaTeX expression to be used for the function. Calling it without an arugment will reset any previously set custom LaTeX expression. See EXAMPLES section for explicit use. EXAMPLES:: sage: var('x') x sage: riemann(x) = function('riemann',x) sage: latex(riemann(x)) {\it riemann}(x) sage: riemann(x).set_latex('\\mathcal{R}') sage: latex(riemann(x)) \mathcal{R}(x) sage: riemann(x).set_latex() sage: latex(riemann(x)) {\it riemann}(x) AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ from sage.misc.latex import user_defined_latex_dict as ldict key = self._f._name # Some sanity checks if expr is not None and expr != "" and not expr.isspace(): ldict[key] = expr elif key in ldict: del ldict[key] return None def _maxima_init_(self): r"""
• ## sage/misc/latex.py

diff -r 17fe77f21e21 -r e190effda0d1 sage/misc/latex.py
 a 'omega', 'Omega'] def latex_symbolic_function(self): r""" Typeset a given symbolic function in LaTeX. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: latex_sym_fn = latex_module.latex_symbolic_function sage: var('x,a,b,t,s') (x, a, b, t, s) sage: psi(x) = function('psi',x) sage: latex_sym_fn(psi(x)) '\\psi(x)' sage: latex_sym_fn(psi(x).conjugate()) '{\\psi}^*(x)' sage: latex_sym_fn(limit(psi(x),x=a)) '\\lim_{x \\to a}\\, \\psi(x)' sage: f(t) = function('f',t) sage: latex_sym_fn(laplace(f(t),t,s)) '\\mathcal{L}\\left(f(t), t, s\\right)' sage: F(s) = function('F',s) sage: latex_sym_fn(inverse_laplace(F(s),s,t)) '\\mathcal{L}^{-1}\\left(F(s), s, t\\right)' sage: f(x) = function('f',x) sage: latex_sym_fn(integrate(f(x),x)) '\\int f(x)\\,{d x}' sage: latex_sym_fn(integrate(f(x),x,a,b)) '\\int_{a}^{b} f(x)\\,{d x}' sage: var('x,y') (x, y) sage: f(x) = function('f',x) sage: latex_sym_fn(diff(f(x),x)) '\\frac{d f(x)}{d x}' sage: f(x,y) = function('f',x,y) sage: latex_sym_fn(diff(f(x,y),x)) '\\frac{\\partial}{\\partial x}f(x, y)' sage: myfunc(x) = function('myfunc',x) sage: latex_sym_fn(myfunc(x)) '{\\it myfunc}(x)' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ # Get the name of symbolic function fname = self._f._name # Special handling of fname where specific processing is needed if fname == "conjugate": return _conjugate_latex_(self) elif fname == "limit": return _limit_latex_(self) elif fname == "laplace": return _laplace_latex_(self) elif fname == "ilt": return _inverse_laplace_latex_(self) elif fname == "integrate": return _integrate_latex_(self) elif fname == "diff": return _derivative_latex_(self) # Check whether fname has custom LaTeX string or is a Greek letter name = latex_function_name(fname) if name is not False: return "%s%s"%(name, _args_latex_(self)) # Use default typesetting scheme return _symbolic_function_default_latex_(self) def _symbolic_function_default_latex_(self): r""" Return LaTeX expression of a symbolic function using default scheme. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _sym_def_latex_ = latex_module._symbolic_function_default_latex_ sage: var('x') x sage: myfunc(x) = function('myfunc',x) sage: _sym_def_latex_(myfunc(x)) '{\\it myfunc}(x)' sage: my_func(x) = function('my_func',x) sage: _sym_def_latex_(my_func(x)) '{\\it my\\_func}(x)' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ # Get the name of the symbolic function fname = self._f._name fname = fname.replace("_", "\\_") # Default typesetting scheme (similar to Maxima scheme) return "{\\it %s}%s"%(fname, _args_latex_(self)) def _args_latex_(self): r""" Return LaTeX expression for the arguments of a symbolic function. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _args_latex_ = latex_module._args_latex_ sage: var('x') x sage: f(x) = function('f',x) sage: _args_latex_(f(x)) '(x)' sage: g(x) = function('g',x) sage: _args_latex_(f(g(x))) '\\left(g(x)\\right)' AUTHORS: - Golam Mortuza Hossain (2009-04-06) """ from sage.calculus.calculus import SymbolicVariable # If all arguments are SymbolicVariables then the function should be # typeset as f(x) rather than f\left(x\right) use_left_right = False for x in self._args: if not isinstance(x, SymbolicVariable): use_left_right = True break if use_left_right is True: return "\\left(%s\\right)"%(', '.join([latex(x) for x in self._args])) else: return "(%s)"%(', '.join([latex(x) for x in self._args])) def _derivative_latex_(self): r""" Return LaTeX expression for derivatives of a symbolic function. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _derivative_latex_ = latex_module._derivative_latex_ sage: var('x,y') (x, y) sage: f(x) = function('f',x) sage: _derivative_latex_(diff(f(x),x)) '\\frac{d f(x)}{d x}' sage: _derivative_latex_(diff(f(x),x,2)) '\\frac{d^{2} f(x)}{d {x}^{2}}' sage: f(x,y) = function('f',x,y) sage: _derivative_latex_(diff(f(x,y),x)) '\\frac{\\partial}{\\partial x}f(x, y)' sage: _derivative_latex_(diff(f(x,y),x,3)) '\\frac{\\partial^{3}}{\\partial {x}^{3}}f(x, y)' sage: _derivative_latex_(diff(f(x,y),x,y)) '\\frac{\\partial^{2}}{\\partial y\\partial x}f(x, y)' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ n = len(self._args) # We dont do any processing for n < 2 if n < 2: return _symbolic_function_default_latex_(self) # Read the function f = self._args[0] # Check whether it should be partial derivative # Logic taken from: http://trac.sagemath.org/sage_trac/ticket/4202 if len(f.variables()) == 1: d_latex = "d" else: d_latex = "\\partial" # Read the variables diffstr = ""; total = 0 for i in range(1,n-1,2): x = self._args[i]    # variable j = self._args[i+1]  # no of times diff acts on f w.r.t. variable x total = total + j    # total no of times diff acts if j == 1: diffstr = "%s %s"%(d_latex, latex(x)) + diffstr else: diffstr = "%s {%s}^{%s}"%(d_latex, latex(x), latex(j)) + diffstr # Return final expression if total == 1: if d_latex == "d": return "\\frac{%s %s}{%s}"%(d_latex, latex(f), diffstr) else: return "\\frac{%s}{%s}%s"%(d_latex, diffstr, latex(f)) if d_latex == "d": return "\\frac{%s^{%d} %s}{%s}"%(d_latex, total, latex(f), diffstr) else: return "\\frac{%s^{%d}}{%s}%s"%(d_latex, total, diffstr, latex(f)) def _integrate_latex_(self): r""" Return LaTeX expression for integration of a symbolic function. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _integrate_latex_ = latex_module._integrate_latex_ sage: var('x,a,b') (x, a, b) sage: f(x) = function('f',x) sage: _integrate_latex_(integrate(f(x),x)) '\\int f(x)\\,{d x}' sage: _integrate_latex_(integrate(f(x),x,a,b)) '\\int_{a}^{b} f(x)\\,{d x}' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ n = len(self._args) # We dont process if number of arguments is neither 2 nor 4 if n != 2 and n != 4: # Return default typesetting return _symbolic_function_default_latex_(self) f = self._args[0] x = self._args[1] # Check whether its a definite integral if n == 4: a = self._args[2] b = self._args[3] return "\\int_{%s}^{%s} %s\\,{d %s}"%(latex(a), latex(b), latex(f), latex(x)) # Typeset as indefinite integral return "\\int %s\\,{d %s}"%(latex(f), latex(x)) def _inverse_laplace_latex_(self): r""" Return LaTeX expression for inverse Laplace transform of a symbolic function. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _inverse_laplace_latex_ = latex_module._inverse_laplace_latex_ sage: var('s,t') (s, t) sage: F(s) = function('F',s) sage: _inverse_laplace_latex_(inverse_laplace(F(s),s,t)) '\\mathcal{L}^{-1}\\left(F(s), s, t\\right)' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ return "\\mathcal{L}^{-1}\\left(%s\\right)"%(', '.join([latex(x) for x in self._args])) def _laplace_latex_(self): r""" Return LaTeX expression for Laplace transform of a symbolic function. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _laplace_latex_ = latex_module._laplace_latex_ sage: var('s,t') (s, t) sage: f(t) = function('f',t) sage: _laplace_latex_(laplace(f(t),t,s)) '\\mathcal{L}\\left(f(t), t, s\\right)' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ return "\\mathcal{L}\\left(%s\\right)"%(', '.join([latex(x) for x in self._args])) def _limit_latex_(self): r""" Return latex expression for limit of a symbolic function. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _limit_latex_ = latex_module._limit_latex_ sage: var('x,a') (x, a) sage: psi(x) = function('psi',x) sage: _limit_latex_(limit(psi(x),x=a)) '\\lim_{x \\to a}\\, \\psi(x)' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ # We process only if there are precisely three arguments if len(self._args) == 3: # Read f,x,a from arguments f = self._args[0] x = self._args[1] a = self._args[2] return "\\lim_{%s \\to %s}\\, %s"%(latex(x), latex(a), latex(f)) # Return default typesetting return _symbolic_function_default_latex_(self) def _conjugate_latex_(self): r""" Return LaTeX expression for conjugate of a symbolic function. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: _conjugate_latex_ = latex_module._conjugate_latex_ sage: var('x') x sage: psi(x) = function('psi',x) sage: _conjugate_latex_(psi(x).conjugate()) '{\\psi}^*(x)' AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ # We process only if there is only one argument if len(self._args) == 1: chld = self._args[0] name = latex_function_name(chld._f._name) if name is not False: # conjugate(psi(x)) => psi^*(x) return "{%s}^*%s"%(name, _args_latex_(chld)) # Return default typesetting return _symbolic_function_default_latex_(self) user_defined_latex_dict = {} def latex_function_name(x): r""" Return common function names such as alpha, beta1, psi_00, R_mn, etc. as latex symbols, else return False. EXAMPLES:: sage: import sage.misc.latex as latex_module sage: latex_function_name = latex_module.latex_function_name sage: latex_function_name('psi') '\\psi' sage: latex_function_name('psi0') '\\psi_{0}' sage: latex_function_name('f1') 'f_{1}' sage: latex_function_name('psi_mu') '\\psi_{\\mu}' sage: latex_function_name('psi_11') '\\psi_{11}' sage: latex_function_name('R_ab') 'R_{ab}' sage: latex_function_name('R_nu') 'R_{\\nu}' sage: latex_function_name('myfunc') False sage: latex_function_name('psi_') False sage: latex_function_name('abc_xyz_psi') False sage: latex_function_name('abc_beta') False NOTES: This function is based largely on latex_variable_name function. AUTHORS: - Golam Mortuza Hossain (2009-04-05) """ # If user has defined latex string then use it first if x in user_defined_latex_dict: return user_defined_latex_dict[x] # For known names return them after preprending with "\\" if x in common_varnames: return "\\" + x # Look for underscrore. If found then use its postion to # find the suffix underscore = x.find("_") if underscore == -1: import re # * The "\d|[.,]" means "decimal digit" or period or comma # * The "+" means "1 or more" # * The "$" means "at the end of the line" m = re.search('(\d|[.,])+$',x) if m is None: prefix = x suffix = None else: prefix = x[:m.start()] suffix = x[m.start():] else: prefix = x[:underscore] suffix = x[underscore+1:] if len(suffix)== 0: return False # If suffix contains underscores then don't process if suffix and suffix.find("_") != -1: return False # If prefix is not a common name or a more-than-one letters word # then don't process if prefix not in common_varnames and len(prefix) != 1: return False # Check if prefix or suffix is a common name if prefix in common_varnames: prefix = "\\" + prefix if suffix and len(suffix) > 0: if suffix in common_varnames: suffix = "\\" + suffix return '%s_{%s}'%(prefix, suffix) else: return '%s'%(prefix) def latex_varify(a): if a in common_varnames: return "\\" + a