Ticket #7661: trac_7661-maxima_convert_back.take2.patch
File trac_7661-maxima_convert_back.take2.patch, 18.8 KB (added by , 11 years ago) |
---|
-
sage/calculus/calculus.py
# HG changeset patch # User Burcin Erocal <burcin@erocal.org> # Date 1270839171 -7200 # Node ID 70c87157c24e7cd2a06a6ad006ba03f1a7ac5545 # Parent b016b621382817c725745151bcf9f2a51f1c7f5d trac 7661: fix problems with conversion of maxima elements to symbolic expressions diff --git a/sage/calculus/calculus.py b/sage/calculus/calculus.py
a b 292 292 x |--> 1/2 293 293 """ 294 294 295 import weakref296 295 import re 297 from sage.rings.all import (CommutativeRing, RealField, is_Polynomial, 298 is_MPolynomial, is_MPolynomialRing, is_FractionFieldElement, 299 is_RealNumber, is_ComplexNumber, RR, is_NumberFieldElement, 300 Integer, Rational, CC, QQ, CDF, ZZ, 301 PolynomialRing, ComplexField, RealDoubleElement, 302 algdep, Integer, RealNumber, RealIntervalField) 303 296 from sage.rings.all import RR, Integer, CC, QQ, RealDoubleElement, algdep 304 297 from sage.rings.real_mpfr import create_RealNumber 305 298 306 from sage.structure.element import RingElement, is_Element307 from sage.structure.parent_base import ParentWithBase308 309 import operator310 299 from sage.misc.latex import latex, latex_variable_name 311 from sage.misc.misc import uniq as unique312 from sage.structure.sage_object import SageObject313 314 300 from sage.interfaces.maxima import Maxima 315 316 import sage.numerical.optimize317 318 301 from sage.misc.parser import Parser 319 302 320 import math321 322 import sage.ext.fast_eval as fast_float323 324 303 from sage.symbolic.ring import var, SR, is_SymbolicVariable 325 304 from sage.symbolic.expression import Expression 326 305 from sage.symbolic.function import Function 327 306 from sage.symbolic.function_factory import function_factory, function 328 307 from sage.symbolic.integration.integral import indefinite_integral, \ 329 308 definite_integral 330 331 arc_functions = ['asin', 'acos', 'atan', 'asinh', 'acosh', 'atanh', 'acoth', 'asech', 'acsch', 'acot', 'acsc', 'asec'] 309 import sage.symbolic.pynac 332 310 333 311 maxima = Maxima(init_code = ['display2d:false', 'domain: complex', 'keepfloat: true', 'load(to_poly_solver)', 'load(simplify_sum)'], 334 312 script_subdirectory=None) … … 1024 1002 else: 1025 1003 raise NotImplementedError, "sympy does not support one-sided limits" 1026 1004 1005 return l.sage() 1027 1006 return ex.parent()(l) 1028 1007 1029 1008 lim = limit … … 1434 1413 register_symbol(minus_infinity, dict(maxima='minf')) 1435 1414 1436 1415 from sage.misc.multireplace import multiple_replace 1437 1438 1416 import re 1439 1417 1440 1441 1418 maxima_tick = re.compile("'[a-z|A-Z|0-9|_]*") 1442 1419 1443 1420 maxima_qp = re.compile("\?\%[a-z|A-Z|0-9|_]*") # e.g., ?%jacobi_cd … … 1453 1430 1454 1431 INPUT: 1455 1432 1456 1457 1433 - ``x`` - a string 1458 1434 1459 1435 - ``equals_sub`` - (default: False) if True, replace … … 1476 1452 sage: a.sage() 1477 1453 x != 0 1478 1454 """ 1479 syms = dict(_syms)1455 syms = sage.symbolic.pynac.symbol_table.get('maxima', {}).copy() 1480 1456 1481 1457 if len(x) == 0: 1482 1458 raise RuntimeError, "invalid symbolic expression -- ''" … … 1554 1530 is_simplified = False 1555 1531 1556 1532 1557 # External access used by restore1558 from sage.symbolic.pynac import symbol_table1559 _syms = syms_cur = symbol_table.get('maxima', {})1560 syms_default = dict(syms_cur)1561 1562 1533 # Comma format options for Maxima 1563 1534 def mapped_opts(v): 1564 1535 """ … … 1567 1538 1568 1539 INPUT: 1569 1540 1570 1571 1541 - ``v`` - an object 1572 1542 1573 1574 1543 OUTPUT: a string. 1575 1544 1576 1545 The main use of this is to turn Python bools into lower case … … 1603 1572 1604 1573 # Parser for symbolic ring elements 1605 1574 1575 # We keep two dictionaries syms_cur and syms_default to keep the current symbol 1576 # table and the state of the table at startup respectively. These are used by 1577 # the restore() function (see sage.misc.reset). 1578 # 1579 # The dictionary _syms is used as a lookup table for the system function 1580 # registry by _find_func() below. It gets updated by 1581 # symbolic_expression_from_string() before calling the parser. 1582 from sage.symbolic.pynac import symbol_table 1583 _syms = syms_cur = symbol_table.get('functions', {}) 1584 syms_default = dict(syms_cur) 1585 1586 # This dictionary is used to pass a lookup table other than the system registry 1587 # to the parser. A global variable is necessary since the parser calls the 1588 # _find_var() and _find_func() functions below without extra arguments. 1606 1589 _augmented_syms = {} 1607 1590 1591 from sage.symbolic.ring import pynac_symbol_registry 1592 1608 1593 def _find_var(name): 1609 1594 """ 1610 1595 Function to pass to Parser for constructing … … 1619 1604 I 1620 1605 """ 1621 1606 try: 1622 return (_augmented_syms or _syms)[name] 1607 res = _augmented_syms.get(name) 1608 if res is None: 1609 return pynac_symbol_registry[name] 1610 # _augmented_syms might contain entries pointing to functions if 1611 # previous computations polluted the maxima workspace 1612 if not isinstance(res, Function): 1613 return res 1623 1614 except KeyError: 1624 1615 pass 1616 1617 # try to find the name in the global namespace 1618 # needed for identifiers like 'e', etc. 1625 1619 try: 1626 1620 return SR(sage.all.__dict__[name]) 1627 1621 except (KeyError, TypeError): … … 1646 1640 0 1647 1641 """ 1648 1642 try: 1649 func = _ syms.get(name)1643 func = _augmented_syms.get(name) 1650 1644 if func is None: 1651 func = _ augmented_syms[name]1645 func = _syms[name] 1652 1646 if not isinstance(func, Expression): 1653 1647 return func 1654 1648 except KeyError: … … 1660 1654 except (KeyError, TypeError): 1661 1655 return function_factory(name) 1662 1656 1663 SR_parser = Parser(make_int = lambda x: SR(Integer(x)), 1657 SR_parser = Parser(make_int = lambda x: SR(Integer(x)), 1664 1658 make_float = lambda x: SR(RealDoubleElement(x)), 1665 1659 make_var = _find_var, 1666 1660 make_function = _find_func) … … 1673 1667 1674 1668 INPUT: 1675 1669 1676 1677 1670 - ``s`` - a string 1678 1671 1679 1672 - ``syms`` - (default: None) dictionary of … … 1689 1682 sage: sage.calculus.calculus.symbolic_expression_from_string('[sin(0)*x^2,3*spam+e^pi]',syms={'spam':y},accept_sequence=True) 1690 1683 [0, 3*y + e^pi] 1691 1684 """ 1692 # from sage.functions.constants import I # can't import this at the top, but need it now1693 # _syms['i'] = _syms['I'] = I1685 global _syms 1686 _syms = sage.symbolic.pynac.symbol_table['functions'].copy() 1694 1687 parse_func = SR_parser.parse_sequence if accept_sequence else SR_parser.parse_expression 1695 1688 if syms is None: 1696 1689 return parse_func(s) … … 1701 1694 return parse_func(s) 1702 1695 finally: 1703 1696 _augmented_syms = {} 1704 1705 def symbolic_expression_from_maxima_element(x, maxima=maxima):1706 """1707 Given an element of the calculus copy of the Maxima interface,1708 create the corresponding Sage symbolic expression.1709 1710 EXAMPLES::1711 1712 sage: a = sage.calculus.calculus.maxima('x^(sqrt(y)+%pi) + sin(%e + %pi)')1713 sage: sage.calculus.calculus.symbolic_expression_from_maxima_element(a)1714 x^(pi + sqrt(y)) - sin(e)1715 sage: var('x, y')1716 (x, y)1717 sage: v = sage.calculus.calculus.maxima.vandermonde_matrix([x, y, 1/2])1718 sage: sage.calculus.calculus.symbolic_expression_from_maxima_element(v)1719 [ 1 x x^2]1720 [ 1 y y^2]1721 [ 1 1/2 1/4]1722 """1723 return symbolic_expression_from_maxima_string(x.name(), maxima=maxima) -
sage/functions/other.py
diff --git a/sage/functions/other.py b/sage/functions/other.py
a b 3 3 """ 4 4 from sage.symbolic.function import GinacFunction, BuiltinFunction 5 5 from sage.symbolic.expression import Expression 6 from sage.symbolic.pynac import register_symbol, symbol_table 6 7 from sage.libs.pari.gen import pari 7 8 from sage.symbolic.all import SR 8 9 from sage.rings.all import Integer, Rational, RealField, CC, RR, \ … … 48 49 Traceback (most recent call last): 49 50 ... 50 51 TypeError: unable to simplify to complex approximation 52 53 TESTS: 54 55 Check if conversion from maxima elements work:: 56 57 sage: merf = maxima(erf(x)).sage().operator() 58 sage: merf == erf 59 True 51 60 """ 52 61 BuiltinFunction.__init__(self, "erf", latex_name=r"\text{erf}") 53 62 … … 690 699 raise TypeError, "Symbolic function gamma takes at most 2 arguments (%s given)"%(len(args)+1) 691 700 return incomplete_gamma(a,args[0],**kwds) 692 701 702 # We have to add the wrapper function manually to the symbol_table when we have 703 # two functions with different number of arguments and the same name 704 symbol_table['functions']['gamma'] = gamma 705 693 706 class Function_psi1(GinacFunction): 694 707 def __init__(self): 695 708 r""" … … 836 849 raise TypeError, "Symbolic function psi takes at most 2 arguments (%s given)"%(len(args)+1) 837 850 return psi2(x,args[0],**kwds) 838 851 852 # We have to add the wrapper function manually to the symbol_table when we have 853 # two functions with different number of arguments and the same name 854 symbol_table['functions']['psi'] = psi 839 855 840 856 class Function_factorial(GinacFunction): 841 857 def __init__(self): … … 1116 1132 pass 1117 1133 return _do_sqrt(x, *args, **kwds) 1118 1134 1119 # register sqrt in pynac symbol_table for conversion back from maxima1120 from sage.symbolic.pynac import register_symbol#, symbol_table 1121 register_symbol(sqrt, dict(maxima='sqrt', mathematica='Sqrt', maple='sqrt')) 1135 # register sqrt in pynac symbol_table for conversion back from other systems 1136 register_symbol(sqrt, dict(mathematica='Sqrt')) 1137 symbol_table['functions']['sqrt'] = sqrt 1122 1138 1123 1139 Function_sqrt = type('deprecated_sqrt', (), 1124 1140 {'__call__': staticmethod(sqrt), -
sage/functions/special.py
diff --git a/sage/functions/special.py b/sage/functions/special.py
a b 394 394 import sage.rings.ring as ring 395 395 from sage.functions.other import real, imag 396 396 from sage.symbolic.function import BuiltinFunction 397 from sage.calculus.calculus import maxima , symbolic_expression_from_maxima_element397 from sage.calculus.calculus import maxima 398 398 399 399 def meval(x): 400 from sage.calculus.calculus import symbolic_expression_from_maxima_element 401 return symbolic_expression_from_maxima_element(maxima(x), maxima) 400 return maxima(x).sage() 402 401 403 402 _done = False 404 403 def _init(): … … 513 512 if self.name() in repr(s): 514 513 return None 515 514 else: 516 return symbolic_expression_from_maxima_element(s)515 return s.sage() 517 516 518 517 from sage.misc.cachefunc import cached_function 519 518 -
sage/interfaces/maxima.py
diff --git a/sage/interfaces/maxima.py b/sage/interfaces/maxima.py
a b 1769 1769 sqrt(2) + sqrt(3) + 2.5 1770 1770 sage: type(d) 1771 1771 <type 'sage.symbolic.expression.Expression'> 1772 1773 sage: a = sage.calculus.calculus.maxima('x^(sqrt(y)+%pi) + sin(%e + %pi)') 1774 sage: a._sage_() 1775 x^(pi + sqrt(y)) - sin(e) 1776 sage: var('x, y') 1777 (x, y) 1778 sage: v = sage.calculus.calculus.maxima.vandermonde_matrix([x, y, 1/2]) 1779 sage: v._sage_() 1780 [ 1 x x^2] 1781 [ 1 y y^2] 1782 [ 1 1/2 1/4] 1783 1784 Check if #7661 is fixed:: 1785 1786 sage: var('delta') 1787 delta 1788 sage: (2*delta).simplify() 1789 2*delta 1772 1790 """ 1773 from sage.calculus.calculus import symbolic_expression_from_maxima_string1774 #return symbolic_expression_from_maxima_string(self.name(), maxima=self.parent())1775 return symbolic_expression_from_maxima_string(repr(self))1791 import sage.calculus.calculus as calculus 1792 return calculus.symbolic_expression_from_maxima_string(self.name(), 1793 maxima=self.parent()) 1776 1794 1777 1795 def _symbolic_(self, R): 1778 1796 """ -
sage/plot/plot3d/plot3d.py
diff --git a/sage/plot/plot3d/plot3d.py b/sage/plot/plot3d/plot3d.py
a b 174 174 [3, -1, 4] 175 175 """ 176 176 from sage.symbolic.expression import is_Expression 177 from sage. calculus.calculusimport is_RealNumber177 from sage.rings.real_mpfr import is_RealNumber 178 178 from sage.rings.integer import is_Integer 179 179 if params is not None and (is_Expression(func) or is_RealNumber(func) or is_Integer(func)): 180 180 return self.transform(**{ -
sage/symbolic/expression.pyx
diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
a b 6514 6514 [x == 1/2*pi] 6515 6515 sage: solve(cos(x)==0,x,to_poly_solve=True) 6516 6516 [x == 1/2*pi] 6517 sage: from sage.calculus.calculus import maxima , symbolic_expression_from_maxima_element6517 sage: from sage.calculus.calculus import maxima 6518 6518 sage: sol = maxima(cos(x)==0).to_poly_solve(x) 6519 sage: s ymbolic_expression_from_maxima_element(sol)6519 sage: sol.sage() 6520 6520 [[x == -1/2*pi + 2*pi*z57], [x == 1/2*pi + 2*pi*z59]] 6521 6521 6522 6522 If a returned unsolved expression has a denominator, but the … … 6524 6524 6525 6525 sage: solve(cos(x) * sin(x) == 1/2, x, to_poly_solve=True) 6526 6526 [sin(x) == 1/2/cos(x)] 6527 sage: from sage.calculus.calculus import maxima , symbolic_expression_from_maxima_element6527 sage: from sage.calculus.calculus import maxima 6528 6528 sage: sol = maxima(cos(x) * sin(x) == 1/2).to_poly_solve(x) 6529 sage: s ymbolic_expression_from_maxima_element(sol)6529 sage: sol.sage() 6530 6530 [[x == 1/4*pi + pi*z73]] 6531 6531 6532 6532 Some basic inequalities can be also solved:: … … 6646 6646 # but also allows for the possibility of approximate # 6647 6647 # solutions being returned. # 6648 6648 ######################################################## 6649 if to_poly_solve and not multiplicities: 6649 if to_poly_solve and not multiplicities: 6650 6650 if len(X)==0: # if Maxima's solve gave no solutions, only try it 6651 6651 try: 6652 6652 s = m.to_poly_solve(x) … … 6656 6656 X = [] 6657 6657 6658 6658 for eq in X: 6659 if repr(x) in map(repr, eq.rhs().variables()) or repr(x) in repr(eq.lhs()): # If the RHS of one solution also has the variable, or if the LHS is not the variable, try another way to get solutions 6660 from sage.calculus.calculus import symbolic_expression_from_maxima_element 6659 # If the RHS of one solution also has the variable, or if 6660 # the LHS is not the variable, try another way to get solutions 6661 if repr(x) in map(repr, eq.rhs().variables()) or \ 6662 repr(x) in repr(eq.lhs()): 6661 6663 try: 6662 Y = symbolic_expression_from_maxima_element((eq._maxima_()).to_poly_solve(x)) # try to solve it using to_poly_solve 6663 X.remove(eq) 6664 X.extend([y[0] for y in Y]) # replace with the new solutions 6664 # try to solve it using to_poly_solve 6665 Y = eq._maxima_().to_poly_solve(x).sage() 6666 X.remove(eq) 6667 # replace with the new solutions 6668 X.extend([y[0] for y in Y]) 6665 6669 except TypeError, mess: 6666 if "Error executing code in Maxima" in str(mess) or "unable to make sense of Maxima expression" in str(mess): 6670 if "Error executing code in Maxima" in str(mess) or \ 6671 "unable to make sense of Maxima expression" in\ 6672 str(mess): 6667 6673 if explicit_solutions: 6668 6674 X.remove(eq) # this removes an implicit solution 6669 6675 else: -
sage/symbolic/random_tests.py
diff --git a/sage/symbolic/random_tests.py b/sage/symbolic/random_tests.py
a b 15 15 # For creating expressions with the full power of Pynac's simple expression 16 16 # subset (with no quantifiers/operators; that is, no derivatives, integrals, 17 17 # etc.) 18 19 18 full_binary = [(0.3, operator.add), (0.1, operator.sub), (0.3, operator.mul), (0.2, operator.div), (0.1, operator.pow)] 20 19 full_unary = [(0.8, operator.neg), (0.2, operator.inv)] 21 full_functions = [(1.0, f, f.number_of_arguments()) for f in sage.symbolic.pynac.symbol_table['functions'].values() if f.number_of_arguments() > 0 and 'elliptic' not in str(f) and 'dickman_rho' not in str(f)] 22 full_nullary = [(1.0, c) for c in [pi, e]] + [(0.05, c) for c in [golden_ratio, log2, euler_gamma, catalan, khinchin, twinprime, mertens, brun]] 23 full_internal = [(0.6, full_binary, 2), (0.2, full_unary, 1), (0.2, full_functions)] 20 full_functions = [(1.0, f, f.number_of_arguments()) 21 for f in sage.symbolic.pynac.symbol_table['functions'].values() 22 if hasattr(f, 'number_of_arguments') and 23 f.number_of_arguments() > 0 ] 24 full_nullary = [(1.0, c) for c in [pi, e]] + [(0.05, c) for c in 25 [golden_ratio, log2, euler_gamma, catalan, khinchin, twinprime, 26 mertens, brun]] 27 full_internal = [(0.6, full_binary, 2), (0.2, full_unary, 1), 28 (0.2, full_functions)] 24 29 25 30 def normalize_prob_list(pl, extra=()): 26 31 r""" … … 202 207 203 208 sage: from sage.symbolic.random_tests import * 204 209 sage: random_expr(50, nvars=3, coeff_generator=CDF.random_element) 205 sinh( sinh((-0.314177274493 + 0.144437996366*I)/csc(-v1^2*e/v3) + erf((-0.708874026302 - 0.954135400334*I)*v3) + 0.0275857401668 - 0.479027260657*I))^(-cosh(-polylog((v2^2 + (0.067987275089 + 1.08529153495*I)*v3)^(-v1 - v3), (5.29385548262 + 2.57440711353*I)*e/cosh((-0.436810529675 + 0.736945423566*I)*arccot(pi)))))210 sinh(elliptic_kc(-1/csc(-((2.62756608636 + 1.20798164491*I)*v3 + (2.62756608636 + 1.20798164491*I)*e)*pi*v1) + erf((-0.708874026302 - 0.954135400334*I)*v3) - elliptic_pi(0.520184609653 - 0.734276246499*I, v3, pi)))^(-elliptic_f((v2^2 + (0.067987275089 + 1.08529153495*I)*v3)^(-v1 - v3), (5.29385548262 + 2.57440711353*I)*e/arccoth(v2*arccot(0.812302592816 - 0.302973871736*I)))) 206 211 sage: random_expr(5, verbose=True) 207 About to apply <built-in function add> to [v1, v1]208 About to apply <built-in function mul> to [v1, -1/2]209 About to apply <built-in function mul> to [2*v1, -1/2*v1]210 -v1^2 212 About to apply <built-in function mul> to [v1, v1] 213 About to apply <built-in function add> to [v1^2, v1] 214 About to apply <built-in function neg> to [v1^2 + v1] 215 -v1^2 - v1 211 216 """ 212 217 vars = [(1.0, sage.calculus.calculus.var('v%d' % (n+1))) for n in range(nvars)] 213 218 if ncoeffs is None: -
sage/symbolic/ring.pyx
diff --git a/sage/symbolic/ring.pyx b/sage/symbolic/ring.pyx
a b 35 35 36 36 from sage.rings.all import RR, CC 37 37 38 cdef dictpynac_symbol_registry = {}38 pynac_symbol_registry = {} 39 39 40 40 cdef class SymbolicRing(CommutativeRing): 41 41 """