Ticket #7377: trac_7377-maximalib_p2.patch

File trac_7377-maximalib_p2.patch, 34.8 KB (added by jpflori, 8 years ago)

Patch based on Sage 4.6.2.alpha4, ECL 11.1.1 and Maxima 5.23.1, apply 2

  • sage/calculus/calculus.py

    # HG changeset patch
    # User Jean-Pierre Flori <flori@enst.fr>
    # Date 1297785799 -3600
    # Node ID 1160d58a0f0abf2904a1e73853937277832a2c5c
    # Parent  fee8c73d93a27081c5ae1e56125202426bbfa1e5
    # Parent  da649f808701e7c5174174205748a007094da249
    Maxima via library; used by calculus
    
    diff -r fee8c73d93a2 -r 1160d58a0f0a sage/calculus/calculus.py
    a b  
    374374from sage.symbolic.integration.integral import indefinite_integral, \
    375375        definite_integral
    376376import sage.symbolic.pynac
     377import sage.interfaces.maxima_lib
    377378
    378379"""
    379380Check if maxima has redundant variables defined after initialization #9538::
    380381
    381     sage: maxima = Maxima(init_code = ['load(simplify_sum)'])
     382    sage: maxima = sage.interfaces.maxima_lib.maxima
    382383    sage: maxima('f1')
    383384    f1
    384385    sage: sage.calculus.calculus.maxima('f1')
    385386    f1
    386387"""
    387 maxima = Maxima(init_code = ['display2d:false', 'domain: complex',
    388                              'keepfloat: true', 'load(to_poly_solver)', 'load(simplify_sum)'],
    389                 script_subdirectory=None)
     388maxima = sage.interfaces.maxima_lib.maxima
    390389
    391390########################################################
    392391def symbolic_sum(expression, v, a, b, algorithm='maxima'):
  • new file sage/interfaces/maxima_lib.py

    diff -r fee8c73d93a2 -r 1160d58a0f0a sage/interfaces/maxima_lib.py
    - +  
     1r"""
     2Interface to Maxima
     3
     4Maxima is a free GPL'd general purpose computer algebra system
     5whose development started in 1968 at MIT. It contains symbolic
     6manipulation algorithms, as well as implementations of special
     7functions, including elliptic functions and generalized
     8hypergeometric functions. Moreover, Maxima has implementations of
     9many functions relating to the invariant theory of the symmetric
     10group `S_n`. (However, the commands for group invariants,
     11and the corresponding Maxima documentation, are in French.) For many
     12links to Maxima documentation see
     13http://maxima.sourceforge.net/docs.shtml/.
     14
     15AUTHORS:
     16
     17- William Stein (2005-12): Initial version
     18
     19- David Joyner: Improved documentation
     20
     21- William Stein (2006-01-08): Fixed bug in parsing
     22
     23- William Stein (2006-02-22): comparisons (following suggestion of
     24  David Joyner)
     25
     26- William Stein (2006-02-24): *greatly* improved robustness by adding
     27  sequence numbers to IO bracketing in _eval_line
     28
     29If the string "error" (case insensitive) occurs in the output of
     30anything from Maxima, a RuntimeError exception is raised.
     31
     32EXAMPLES: We evaluate a very simple expression in Maxima.
     33
     34::
     35
     36    sage: maxima('3 * 5')
     37    15
     38
     39We factor `x^5 - y^5` in Maxima in several different ways.
     40The first way yields a Maxima object.
     41
     42::
     43
     44    sage: F = maxima.factor('x^5 - y^5')
     45    sage: F
     46    -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
     47    sage: type(F)
     48    <class 'sage.interfaces.maxima_abstract.MaximaElement'>
     49
     50Note that Maxima objects can also be displayed using "ASCII art";
     51to see a normal linear representation of any Maxima object x. Just
     52use the print command: use ``str(x)``.
     53
     54::
     55
     56    sage: print F
     57                               4      3    2  2    3      4
     58                   - (y - x) (y  + x y  + x  y  + x  y + x )
     59
     60You can always use ``repr(x)`` to obtain the linear
     61representation of an object. This can be useful for moving maxima
     62data to other systems.
     63
     64::
     65
     66    sage: repr(F)
     67    '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
     68    sage: F.str()
     69    '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
     70
     71The ``maxima.eval`` command evaluates an expression in
     72maxima and returns the result as a *string* not a maxima object.
     73
     74::
     75
     76    sage: print maxima.eval('factor(x^5 - y^5)')
     77    -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
     78
     79We can create the polynomial `f` as a Maxima polynomial,
     80then call the factor method on it. Notice that the notation
     81``f.factor()`` is consistent with how the rest of Sage
     82works.
     83
     84::
     85
     86    sage: f = maxima('x^5 - y^5')
     87    sage: f^2
     88    (x^5-y^5)^2
     89    sage: f.factor()
     90    -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
     91
     92Control-C interruption works well with the maxima interface,
     93because of the excellent implementation of maxima. For example, try
     94the following sum but with a much bigger range, and hit control-C.
     95
     96::
     97
     98    sage: maxima('sum(1/x^2, x, 1, 10)')
     99    1968329/1270080
     100
     101Tutorial
     102--------
     103
     104We follow the tutorial at
     105http://maxima.sourceforge.net/docs/intromax/.
     106
     107::
     108
     109    sage: maxima('1/100 + 1/101')
     110    201/10100
     111
     112::
     113
     114    sage: a = maxima('(1 + sqrt(2))^5'); a
     115    (sqrt(2)+1)^5
     116    sage: a.expand()
     117    3*2^(7/2)+5*sqrt(2)+41
     118
     119::
     120
     121    sage: a = maxima('(1 + sqrt(2))^5')
     122    sage: float(a)               
     123    82.012193308819747
     124    sage: a.numer()
     125    82.01219330881975
     126
     127::
     128
     129    sage: maxima.eval('fpprec : 100')
     130    '100'
     131    sage: a.bfloat()
     132    8.20121933088197564152489730020812442785204843859314941221237124017312418754011041266612384955016056b1
     133
     134::
     135
     136    sage: maxima('100!')
     137    93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
     138
     139::
     140
     141    sage: f = maxima('(x + 3*y + x^2*y)^3')
     142    sage: f.expand()
     143    x^6*y^3+9*x^4*y^3+27*x^2*y^3+27*y^3+3*x^5*y^2+18*x^3*y^2+27*x*y^2+3*x^4*y+9*x^2*y+x^3
     144    sage: f.subst('x=5/z')
     145    (5/z+25*y/z^2+3*y)^3
     146    sage: g = f.subst('x=5/z')
     147    sage: h = g.ratsimp(); h
     148    (27*y^3*z^6+135*y^2*z^5+(675*y^3+225*y)*z^4+(2250*y^2+125)*z^3+(5625*y^3+1875*y)*z^2+9375*y^2*z+15625*y^3)/z^6
     149    sage: h.factor()
     150    (3*y*z^2+5*z+25*y)^3/z^6
     151
     152::
     153
     154    sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])
     155    sage: s = eqn.solve('[a,b,c]'); s
     156    [[a=(25*sqrt(79)*%i+25)/(6*sqrt(79)*%i-34),b=(5*sqrt(79)*%i+5)/(sqrt(79)*%i+11),c=(sqrt(79)*%i+1)/10],[a=(25*sqrt(79)*%i-25)/(6*sqrt(79)*%i+34),b=(5*sqrt(79)*%i-5)/(sqrt(79)*%i-11),c=-(sqrt(79)*%i-1)/10]]
     157
     158Here is an example of solving an algebraic equation::
     159
     160    sage: maxima('x^2+y^2=1').solve('y')
     161    [y=-sqrt(1-x^2),y=sqrt(1-x^2)]
     162    sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')
     163    [y=-sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2),y=sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2)]
     164
     165You can even nicely typeset the solution in latex::
     166
     167    sage: latex(s)
     168    \left[ \left[ a={{25\,\sqrt{79}\,i+25}\over{6\,\sqrt{79}\,i-34}} ,   b={{5\,\sqrt{79}\,i+5}\over{\sqrt{79}\,i+11}} , c={{\sqrt{79}\,i+1  }\over{10}} \right]  , \left[ a={{25\,\sqrt{79}\,i-25}\over{6\,  \sqrt{79}\,i+34}} , b={{5\,\sqrt{79}\,i-5}\over{\sqrt{79}\,i-11}} ,   c=-{{\sqrt{79}\,i-1}\over{10}} \right]  \right]
     169
     170To have the above appear onscreen via ``xdvi``, type
     171``view(s)``. (TODO: For OS X should create pdf output
     172and use preview instead?)
     173
     174::
     175
     176    sage: e = maxima('sin(u + v) * cos(u)^3'); e
     177    cos(u)^3*sin(v+u)
     178    sage: f = e.trigexpand(); f
     179    cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))
     180    sage: f.trigreduce()
     181    (sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8
     182    sage: w = maxima('3 + k*%i')
     183    sage: f = w^2 + maxima('%e')^w
     184    sage: f.realpart()
     185    %e^3*cos(k)-k^2+9
     186
     187::
     188
     189    sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f
     190    x^3*%e^(k*x)*sin(w*x)
     191    sage: f.diff('x')
     192    k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x)*cos(w*x)
     193    sage: f.integrate('x')
     194    (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3+(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(-18*k*w^4-12*k^3*w^2+6*k^5)*x-6*w^4+36*k^2*w^2-6*k^4)*%e^(k*x)*sin(w*x)+((-w^7-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3+24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8)
     195
     196::
     197
     198    sage: f = maxima('1/x^2')
     199    sage: f.integrate('x', 1, 'inf')
     200    1
     201    sage: g = maxima('f/sinh(k*x)^4')
     202    sage: g.taylor('x', 0, 3)
     203    f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945
     204
     205::
     206
     207    sage: maxima.taylor('asin(x)','x',0, 10)
     208    x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152
     209
     210Examples involving matrices
     211---------------------------
     212
     213We illustrate computing with the matrix whose `i,j` entry
     214is `i/j`, for `i,j=1,\ldots,4`.
     215
     216::
     217
     218    sage: f = maxima.eval('f[i,j] := i/j')
     219    sage: A = maxima('genmatrix(f,4,4)'); A
     220    matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])
     221    sage: A.determinant()
     222    0
     223    sage: A.echelon()
     224    matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])
     225    sage: A.eigenvalues()
     226    [[0,4],[3,1]]
     227    sage: A.eigenvectors()
     228    [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]
     229
     230We can also compute the echelon form in Sage::
     231
     232    sage: B = matrix(QQ, A)
     233    sage: B.echelon_form()
     234    [  1 1/2 1/3 1/4]
     235    [  0   0   0   0]
     236    [  0   0   0   0]
     237    [  0   0   0   0]
     238    sage: B.charpoly('x').factor()
     239    (x - 4) * x^3
     240
     241Laplace Transforms
     242------------------
     243
     244We illustrate Laplace transforms::
     245
     246    sage: _ = maxima.eval("f(t) := t*sin(t)")
     247    sage: maxima("laplace(f(t),t,s)")
     248    2*s/(s^2+1)^2
     249
     250::
     251
     252    sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function
     253    %e^-(3*s)
     254
     255::
     256
     257    sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")
     258    sage: maxima("laplace(f(t),t,s)")
     259    1/(s^2-2*s+2)
     260
     261::
     262
     263    sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")
     264    sage: maxima("laplace(f(t),t,s)")
     265    360*(2*s-2)/(s^2-2*s+2)^4-480*(2*s-2)^3/(s^2-2*s+2)^5+120*(2*s-2)^5/(s^2-2*s+2)^6
     266    sage: print maxima("laplace(f(t),t,s)")
     267                                             3                 5
     268               360 (2 s - 2)    480 (2 s - 2)     120 (2 s - 2)
     269              --------------- - --------------- + ---------------
     270                2           4     2           5     2           6
     271              (s  - 2 s + 2)    (s  - 2 s + 2)    (s  - 2 s + 2)
     272
     273::
     274
     275    sage: maxima("laplace(diff(x(t),t),t,s)")
     276    s*'laplace(x(t),t,s)-x(0)
     277
     278::
     279
     280    sage: maxima("laplace(diff(x(t),t,2),t,s)")
     281    -?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s
     282
     283It is difficult to read some of these without the 2d
     284representation::
     285
     286    sage: print maxima("laplace(diff(x(t),t,2),t,s)")
     287                         !
     288                d        !         2
     289              - -- (x(t))!      + s  laplace(x(t), t, s) - x(0) s
     290                dt       !
     291                         !t = 0
     292
     293Even better, use
     294``view(maxima("laplace(diff(x(t),t,2),t,s)"))`` to see
     295a typeset version.
     296
     297Continued Fractions
     298-------------------
     299
     300A continued fraction `a + 1/(b + 1/(c + \cdots))` is
     301represented in maxima by the list `[a, b, c, \ldots]`.
     302
     303::
     304
     305    sage: maxima("cf((1 + sqrt(5))/2)")
     306    [1,1,1,1,2]
     307    sage: maxima("cf ((1 + sqrt(341))/2)")
     308    [9,1,2,1,2,1,17,1,2,1,2,1,17,1,2,1,2,1,17,2]
     309
     310Special examples
     311----------------
     312
     313In this section we illustrate calculations that would be awkward to
     314do (as far as I know) in non-symbolic computer algebra systems like
     315MAGMA or GAP.
     316
     317We compute the gcd of `2x^{n+4} - x^{n+2}` and
     318`4x^{n+1} + 3x^n` for arbitrary `n`.
     319
     320::
     321
     322    sage: f = maxima('2*x^(n+4) - x^(n+2)')
     323    sage: g = maxima('4*x^(n+1) + 3*x^n')
     324    sage: f.gcd(g)
     325    x^n
     326
     327You can plot 3d graphs (via gnuplot)::
     328
     329    sage: maxima('plot3d(x^2-y^2, [x,-2,2], [y,-2,2], [grid,12,12])')  # not tested
     330    [displays a 3 dimensional graph]
     331
     332You can formally evaluate sums (note the ``nusum``
     333command)::
     334
     335    sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')
     336    sage: print S
     337                            2/n + 3                   2/n + 1
     338                          %e                        %e
     339                   ----------------------- - -----------------------
     340                      1/n         1/n           1/n         1/n
     341                   (%e    - 1) (%e    + 1)   (%e    - 1) (%e    + 1)
     342
     343We formally compute the limit as `n\to\infty` of
     344`2S/n` as follows::
     345
     346    sage: T = S*maxima('2/n')
     347    sage: T.tlimit('n','inf')
     348    %e^3-%e
     349
     350Miscellaneous
     351-------------
     352
     353Obtaining digits of `\pi`::
     354
     355    sage: maxima.eval('fpprec : 100')
     356    '100'
     357    sage: maxima(pi).bfloat()
     358    3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068b0
     359
     360Defining functions in maxima::
     361
     362    sage: maxima.eval('fun[a] := a^2')
     363    'fun[a]:=a^2'
     364    sage: maxima('fun[10]')
     365    100
     366
     367Interactivity
     368-------------
     369
     370Unfortunately maxima doesn't seem to have a non-interactive mode,
     371which is needed for the Sage interface. If any Sage call leads to
     372maxima interactively answering questions, then the questions can't be
     373answered and the maxima session may hang. See the discussion at
     374http://www.ma.utexas.edu/pipermail/maxima/2005/011061.html for some
     375ideas about how to fix this problem. An example that illustrates this
     376problem is ``maxima.eval('integrate (exp(a*x), x, 0, inf)')``.
     377
     378Latex Output
     379------------
     380
     381To TeX a maxima object do this::
     382
     383    sage: latex(maxima('sin(u) + sinh(v^2)'))
     384    \sinh v^2+\sin u
     385
     386Here's another example::
     387
     388    sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c')
     389    sage: latex(g)
     390    -{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c
     391
     392Long Input
     393----------
     394
     395The MAXIMA interface reads in even very long input (using files) in
     396a robust manner, as long as you are creating a new object.
     397
     398.. note::
     399
     400   Using ``maxima.eval`` for long input is much less robust, and is
     401   not recommended.
     402
     403::
     404
     405    sage: t = '"%s"'%10^10000   # ten thousand character string.
     406    sage: a = maxima(t)
     407
     408TESTS: This working tests that a subtle bug has been fixed::
     409
     410    sage: f = maxima.function('x','gamma(x)')
     411    sage: g = f(1/7)
     412    sage: g
     413    gamma(1/7)
     414    sage: del f
     415    sage: maxima(sin(x))
     416    sin(x)
     417
     418This tests to make sure we handle the case where Maxima asks if an
     419expression is positive or zero.
     420
     421::
     422
     423    sage: var('Ax,Bx,By')
     424    (Ax, Bx, By)
     425    sage: t = -Ax*sin(sqrt(Ax^2)/2)/(sqrt(Ax^2)*sqrt(By^2 + Bx^2))
     426    sage: t.limit(Ax=0, dir='+')
     427    0
     428
     429A long complicated input expression::
     430
     431    sage: maxima._eval_line('((((((((((0) + ((1) / ((n0) ^ (0)))) + ((1) / ((n1) ^ (1)))) + ((1) / ((n2) ^ (2)))) + ((1) / ((n3) ^ (3)))) + ((1) / ((n4) ^ (4)))) + ((1) / ((n5) ^ (5)))) + ((1) / ((n6) ^ (6)))) + ((1) / ((n7) ^ (7)))) + ((1) / ((n8) ^ (8)))) + ((1) / ((n9) ^ (9)));')
     432    '1/n9^9+1/n8^8+1/n7^7+1/n6^6+1/n5^5+1/n4^4+1/n3^3+1/n2^2+1/n1+1'
     433"""
     434
     435#*****************************************************************************
     436#       Copyright (C) 2005 William Stein <wstein@gmail.com>
     437#
     438#  Distributed under the terms of the GNU General Public License (GPL)
     439#
     440#    This code is distributed in the hope that it will be useful,
     441#    but WITHOUT ANY WARRANTY; without even the implied warranty of
     442#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     443#    General Public License for more details.
     444#
     445#  The full text of the GPL is available at:
     446#
     447#                  http://www.gnu.org/licenses/
     448#*****************************************************************************
     449
     450from __future__ import with_statement
     451
     452import os, re, sys, subprocess
     453import pexpect
     454cygwin = os.uname()[0][:6]=="CYGWIN"
     455
     456from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString
     457from pexpect import EOF
     458
     459from random import randrange
     460
     461##import sage.rings.all
     462import sage.rings.complex_number
     463
     464from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT
     465
     466from sage.misc.multireplace import multiple_replace
     467
     468COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE
     469
     470import sage.server.support
     471
     472import maxima_abstract
     473from maxima_abstract import MaximaFunctionElement, MaximaExpectFunction, MaximaElement, MaximaFunction, maxima_console
     474
     475# The Maxima "apropos" command, e.g., apropos(det) gives a list
     476# of all identifiers that begin in a certain way.  This could
     477# maybe be useful somehow... (?)  Also maxima has a lot for getting
     478# documentation from the system -- this could also be useful.
     479
     480####################################################################
     481## We begin here by initializing maxima in library more
     482from sage.libs.ecl import *
     483ecl_eval("(setf *load-verbose* NIL)")
     484ecl_eval("(require 'maxima)")
     485ecl_eval("(in-package :maxima)")
     486ecl_eval("(setq $nolabels t))")
     487ecl_eval("(defvar *MAXIMA-LANG-SUBDIR* NIL)")
     488ecl_eval("(set-pathnames)")
     489ecl_eval("(defun add-lineinfo (x) x)")
     490ecl_eval("""(defun retrieve (msg flag &aux (print? nil))(error (concatenate 'string "Maxima asks:" (meval (list '($string) msg)))))""")
     491ecl_eval('(defparameter *dev-null* (make-two-way-stream (make-concatenated-stream) (make-broadcast-stream)))')
     492ecl_eval('(defun principal nil (error "Divergent Integral"))')
     493
     494maxima_eval=ecl_eval("""
     495    (defun maxima-eval( form )
     496        (let ((result (catch 'macsyma-quit (cons 'maxima_eval (meval form)))))
     497            ;(princ (list "result=" result))
     498            ;(terpri)
     499            ;(princ (list "$error=" $error))
     500            ;(terpri)
     501            (cond
     502                ((and (consp result) (eq (car result) 'maxima_eval)) (cdr result))
     503                ((eq result 'maxima-error) (error (cadr $error)))
     504                (t (error (concatenate 'string "Maxima condition. result:" (princ-to-string result) "$error:" (princ-to-string $error))))
     505            )
     506        )
     507    )
     508""")
     509
     510#ecl_eval('(defun ask-evod (x even-odd)(error "Maxima asks a question"))')
     511#ecl_eval('(defun ask-integerp (x)(error "Maxima asks a question"))')
     512#ecl_eval('(defun ask-declare (x property)(error "Maxima asks a question"))')
     513#ecl_eval('(defun ask-prop (object property fun-or-number)(error "Maxima asks a question"))')
     514#ecl_eval('(defun asksign01 (a)(error "Maxima asks a question"))')
     515#ecl_eval('(defun asksign (x)(error "Maxima asks a question"))')
     516#ecl_eval('(defun asksign1 ($askexp)(error "Maxima asks a question"))')
     517#ecl_eval('(defun ask-greateq (x y)(error "Maxima asks a question"))')
     518#ecl_eval('(defun askinver (a)(error "Maxima asks a question"))')
     519#ecl_eval('(defun npask (exp)(error "Maxima asks a question"))')
     520
     521
     522import sage.symbolic.expression
     523from sage.symbolic.ring import is_SymbolicVariable
     524from sage.symbolic.ring import SR
     525
     526maxima_lib_instances = 0
     527
     528maxprint=EclObject("$STRING")
     529meval=EclObject("MEVAL")
     530
     531def max_to_string(s):
     532     return meval(EclObject([[maxprint],s])).python()[1:-1]
     533
     534class Maxima(maxima_abstract.Maxima):
     535    """
     536    Interface to the Maxima interpreter.
     537    """
     538    def __init__(self, script_subdirectory=None, logfile=None, server=None,
     539                 init_code = None):
     540        """
     541        Create an instance of the Maxima interpreter.
     542
     543        TESTS::
     544       
     545            sage: maxima == loads(dumps(maxima))
     546            True
     547
     548        We make sure labels are turned off (see trac 6816)::
     549       
     550            sage: 'nolabels:true' in maxima._Expect__init_code
     551            True
     552        """
     553        global maxima_lib_instances
     554        if maxima_lib_instances > 0:
     555            raise RuntimeError, "Maxima interface in library mode can only be instantiated once"
     556        maxima_lib_instances += 1
     557       
     558        #the single one gets defined in the Expect interface
     559        self._eval_using_file_cutoff = 10**9
     560        #the double underscore one seems to by private to the Maxima interface
     561        #this must have started as a typo by someone
     562        self.__eval_using_file_cutoff = 10**9
     563        self._available_vars = []
     564        self._Expect__seq = 0
     565        self._session_number = 1
     566        self._Expect__name = "maxima"
     567
     568        if True:
     569            # display2d -- no ascii art output
     570            # keepfloat -- don't automatically convert floats to rationals
     571            init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)']
     572           
     573        # Turn off the prompt labels, since computing them *very
     574        # dramatically* slows down the maxima interpret after a while.
     575        # See the function makelabel in suprv1.lisp.
     576        # Many thanks to andrej.vodopivec@gmail.com and also
     577        # Robert Dodier for figuring this out!
     578        # See trac # 6818. 
     579        init_code.append('nolabels : true')
     580        ecl_eval("(setf original-standard-output *standard-output*)")
     581        ecl_eval("(setf *standard-output* *dev-null*)")
     582        for l in init_code:
     583            ecl_eval("#$%s$"%l)
     584        ecl_eval("(setf *standard-output* original-standard-output)")
     585       
     586    def _function_class(self):
     587        """
     588        EXAMPLES::
     589       
     590            sage: maxima._function_class()
     591            <class 'sage.interfaces.maxima_abstract.MaximaExpectFunction'>
     592        """
     593        return MaximaExpectFunction
     594
     595    def _start(self):
     596        """
     597        Starts the Maxima interpreter.
     598       
     599        EXAMPLES::
     600       
     601            sage: m = Maxima()
     602            sage: m.is_running()
     603            False
     604            sage: m._start()
     605            sage: m.is_running()
     606            True
     607        """
     608        ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))")
     609
     610    def __reduce__(self):
     611        """
     612        EXAMPLES::
     613       
     614            sage: maxima.__reduce__()
     615            (<function reduce_load_Maxima at 0x...>, ())
     616        """
     617        return reduce_load_Maxima, tuple([])
     618
     619    def _sendline(self, str):
     620        self._sendstr(str)
     621        os.write(self._expect.child_fd, os.linesep)
     622
     623    def _expect_expr(self, expr=None, timeout=None):
     624        """
     625        EXAMPLES:
     626            sage: a,b=var('a,b')
     627            sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x)
     628            Traceback (most recent call last):
     629            ...
     630            TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume(a>0)' before integral or limit evaluation, for example):
     631            Is  a  positive or negative?
     632            sage: assume(a>0)
     633            sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x)
     634            2/9*sqrt(3)*b^2*arctan(1/3*(2*(b*x + a)^(1/3) + a^(1/3))*sqrt(3)/a^(1/3))/a^(7/3) + 2/9*b^2*log((b*x + a)^(1/3) - a^(1/3))/a^(7/3) - 1/9*b^2*log((b*x + a)^(2/3) + (b*x + a)^(1/3)*a^(1/3) + a^(2/3))/a^(7/3) + 1/6*(4*(b*x + a)^(5/3)*b^2 - 7*(b*x + a)^(2/3)*a*b^2)/((b*x + a)^2*a^2 - 2*(b*x + a)*a^3 + a^4)
     635            sage: var('x, n')
     636            (x, n)
     637            sage: integral(x^n,x)
     638            Traceback (most recent call last):
     639            ...
     640            TypeError: Computation failed since Maxima requested additional constraints (try the command 'assume(n+1>0)' before integral or limit evaluation, for example):
     641            Is  n+1  zero or nonzero?
     642            sage: assume(n+1>0)
     643            sage: integral(x^n,x)
     644            x^(n + 1)/(n + 1)
     645            sage: forget()
     646        """
     647        if expr is None:
     648            expr = self._prompt_wait
     649        if self._expect is None:
     650            self._start()
     651        try:
     652            if timeout:
     653                i = self._expect.expect(expr,timeout=timeout)
     654            else:
     655                i = self._expect.expect(expr)
     656            if i > 0:
     657                v = self._expect.before
     658
     659                #We check to see if there is a "serious" error in Maxima.
     660                #Note that this depends on the order of self._prompt_wait
     661                if expr is self._prompt_wait and i > len(self._ask):
     662                    self.quit()
     663                    raise ValueError, "%s\nComputation failed due to a bug in Maxima -- NOTE: Maxima had to be restarted."%v
     664
     665                j = v.find('Is ')
     666                v = v[j:]
     667                k = v.find(' ',4)
     668                msg = "Computation failed since Maxima requested additional constraints (try the command 'assume(" + v[4:k] +">0)' before integral or limit evaluation, for example):\n" + v + self._ask[i-1]
     669                self._sendline(";")
     670                self._expect_expr()
     671                raise ValueError, msg
     672        except KeyboardInterrupt, msg:
     673            #print self._expect.before
     674            i = 0
     675            while True:
     676                try:
     677                    print "Control-C pressed.  Interrupting Maxima. Please wait a few seconds..."
     678                    self._sendstr('quit;\n'+chr(3))
     679                    self._sendstr('quit;\n'+chr(3))
     680                    self.interrupt()
     681                    self.interrupt()
     682                except KeyboardInterrupt:
     683                    i += 1
     684                    if i > 10:
     685                        break
     686                    pass
     687                else:
     688                    break
     689            raise KeyboardInterrupt, msg
     690
     691    def _eval_line(self, line, allow_use_file=False,
     692                   wait_for_prompt=True, reformat=True, error_check=True):
     693        return max_to_string(maxima_eval("#$%s$"%line))
     694
     695
     696    def _synchronize(self):
     697        """
     698        Synchronize pexpect interface.
     699       
     700        This put a random integer (plus one!) into the output stream, then
     701        waits for it, thus resynchronizing the stream. If the random
     702        integer doesn't appear within 1 second, maxima is sent interrupt
     703        signals.
     704       
     705        This way, even if you somehow left maxima in a busy state
     706        computing, calling _synchronize gets everything fixed.
     707       
     708        EXAMPLES: This makes Maxima start a calculation::
     709       
     710            sage: maxima._sendstr('1/1'*500)
     711       
     712        When you type this command, this synchronize command is implicitly
     713        called, and the above running calculation is interrupted::
     714       
     715            sage: maxima('2+2')
     716            4
     717        """
     718        marker = '__SAGE_SYNCHRO_MARKER_'
     719        if self._expect is None: return
     720        r = randrange(2147483647)
     721        s = marker + str(r+1)
     722
     723        # The 0; *is* necessary... it comes up in certain rare cases
     724        # that are revealed by extensive testing.  Don't delete it. -- william stein
     725        cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r)
     726        self._sendstr(cmd)
     727        try:
     728            self._expect_expr(timeout=0.5)
     729            if not s in self._before():
     730                self._expect_expr(s,timeout=0.5)
     731                self._expect_expr(timeout=0.5)
     732        except pexpect.TIMEOUT, msg:
     733            self._interrupt()
     734        except pexpect.EOF:
     735            self._crash_msg()
     736            self.quit()
     737
     738    ###########################################
     739    # Direct access to underlying lisp interpreter.
     740    ###########################################
     741    def lisp(self, cmd):
     742        """
     743        Send a lisp command to maxima.
     744       
     745        .. note::
     746
     747           The output of this command is very raw - not pretty.
     748       
     749        EXAMPLES::
     750       
     751            sage: maxima.lisp("(+ 2 17)")   # random formatted output
     752             :lisp (+ 2 17)
     753            19
     754            (
     755        """
     756        self._eval_line(':lisp %s\n""'%cmd, allow_use_file=False, wait_for_prompt=False, reformat=False, error_check=False)
     757        self._expect_expr('(%i)')
     758        return self._before()
     759
     760    ###########################################
     761    # Interactive help
     762    ###########################################
     763    def _command_runner(self, command, s, redirect=True):
     764        """
     765        Run ``command`` in a new Maxima session and return its
     766        output as an ``AsciiArtString``.
     767       
     768        If redirect is set to False, then the output of the command is not
     769        returned as a string. Instead, it behaves like os.system. This is
     770        used for interactive things like Maxima's demos. See maxima.demo?
     771       
     772        EXAMPLES::
     773       
     774            sage: maxima._command_runner('describe', 'gcd')
     775            -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
     776            ...
     777        """
     778        cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s)
     779        if sage.server.support.EMBEDDED_MODE:
     780            cmd += '< /dev/null'
     781
     782        if redirect:
     783            p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
     784                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     785            res = p.stdout.read()
     786            # ecl-10.2 : 3 lines
     787            # ecl-10.4 : 5 lines
     788            # ecl-11.1 : 4 lines fancy a tango?
     789            # We now get 4 lines of commented verbosity
     790            # every time Maxima starts, so we need to get rid of them
     791            for _ in range(4):
     792                res = res[res.find('\n')+1:]
     793            return AsciiArtString(res)
     794        else:
     795            subprocess.Popen(cmd, shell=True)
     796
     797    def _object_class(self):
     798        """
     799        Return the Python class of Maxima elements.
     800       
     801        EXAMPLES::
     802       
     803            sage: maxima._object_class()
     804            <class 'sage.interfaces.maxima_abstract.MaximaElement'>
     805        """
     806        return MaximaElement
     807
     808    def _function_element_class(self):
     809        """     
     810        EXAMPLES::
     811       
     812            sage: maxima._function_element_class()
     813            <class 'sage.interfaces.maxima_abstract.MaximaFunctionElement'>
     814        """
     815        return MaximaFunctionElement
     816
     817    def function(self, args, defn, rep=None, latex=None):
     818        """
     819        Return the Maxima function with given arguments and definition.
     820       
     821        INPUT:
     822       
     823       
     824        -  ``args`` - a string with variable names separated by
     825           commas
     826       
     827        -  ``defn`` - a string (or Maxima expression) that
     828           defines a function of the arguments in Maxima.
     829       
     830        -  ``rep`` - an optional string; if given, this is how
     831           the function will print.
     832       
     833       
     834        EXAMPLES::
     835       
     836            sage: f = maxima.function('x', 'sin(x)')
     837            sage: f(3.2)
     838            -.058374143427580...
     839            sage: f = maxima.function('x,y', 'sin(x)+cos(y)')
     840            sage: f(2,3.5)
     841            sin(2)-.9364566872907963
     842            sage: f
     843            sin(x)+cos(y)
     844       
     845        ::
     846       
     847            sage: g = f.integrate('z')
     848            sage: g
     849            (cos(y)+sin(x))*z
     850            sage: g(1,2,3)
     851            3*(cos(2)+sin(1))
     852       
     853        The function definition can be a maxima object::
     854       
     855            sage: an_expr = maxima('sin(x)*gamma(x)')
     856            sage: t = maxima.function('x', an_expr)
     857            sage: t
     858            gamma(x)*sin(x)
     859            sage: t(2)
     860             sin(2)
     861            sage: float(t(2))
     862            0.90929742682568171
     863            sage: loads(t.dumps())
     864            gamma(x)*sin(x)
     865        """
     866        name = self._next_var_name()
     867        if isinstance(defn, MaximaElement):
     868            defn = defn.str()
     869        elif not isinstance(defn, str):
     870            defn = str(defn)
     871        if isinstance(args, MaximaElement):
     872            args = args.str()
     873        elif not isinstance(args, str):
     874            args = str(args)
     875        cmd = '%s(%s) := %s'%(name, args, defn)
     876        maxima._eval_line(cmd)
     877        if rep is None:
     878            rep = defn
     879        f = MaximaFunction(self, name, rep, args, latex)
     880        return f
     881
     882    def set(self, var, value):
     883        """
     884        Set the variable var to the given value.
     885       
     886        INPUT:
     887       
     888       
     889        -  ``var`` - string
     890       
     891        -  ``value`` - string
     892       
     893       
     894        EXAMPLES::
     895       
     896            sage: maxima.set('xxxxx', '2')
     897            sage: maxima.get('xxxxx')
     898            '2'
     899        """
     900        if not isinstance(value, str):
     901            raise TypeError
     902        cmd = '%s : %s$'%(var, value.rstrip(';'))
     903        if len(cmd) > self.__eval_using_file_cutoff:
     904            self._batch(cmd, batchload=True)
     905        else:
     906            self._eval_line(cmd)
     907            #self._sendline(cmd)
     908            #self._expect_expr()
     909            #out = self._before()
     910            #self._error_check(cmd, out)
     911
     912    def clear(self, var):
     913        """
     914        Clear the variable named var.
     915
     916        EXAMPLES::
     917
     918            sage: maxima.set('xxxxx', '2')
     919            sage: maxima.get('xxxxx')
     920            '2'
     921            sage: maxima.clear('xxxxx')
     922            sage: maxima.get('xxxxx')
     923            'xxxxx'
     924        """
     925        try:
     926            self._expect.send('kill(%s)$'%var)
     927        except (TypeError, AttributeError):
     928             pass
     929
     930    def get(self, var):
     931        """
     932        Get the string value of the variable var.
     933       
     934        EXAMPLES::
     935       
     936            sage: maxima.set('xxxxx', '2')
     937            sage: maxima.get('xxxxx')
     938            '2'
     939        """
     940        s = self._eval_line('%s;'%var)
     941        return s
     942   
     943    def version(self):
     944        """
     945        Return the version of Maxima that Sage includes.
     946       
     947        EXAMPLES::
     948       
     949            sage: maxima.version()
     950            '5.23.2'
     951        """
     952        return maxima_version()
     953
     954
     955##     def display2d(self, flag=True):
     956##         """
     957##         Set the flag that determines whether Maxima objects are
     958##         printed using their 2-d ASCII art representation.  When the
     959##         maxima interface starts the default is that objects are not
     960##         represented in 2-d.
     961
     962##         INPUT:
     963##             flag -- bool (default: True)
     964
     965##         EXAMPLES
     966##             sage: maxima('1/2')
     967##             1/2
     968##             sage: maxima.display2d(True)
     969##             sage: maxima('1/2')
     970##                                            1
     971##                                            -
     972##                                            2
     973##             sage: maxima.display2d(False)
     974##         """
     975##         self._display2d = bool(flag)
     976
     977def is_MaximaElement(x):
     978    """
     979    Returns True if x is of type MaximaElement.
     980   
     981    EXAMPLES::
     982   
     983        sage: from sage.interfaces.maxima import is_MaximaElement
     984        sage: m = maxima(1)
     985        sage: is_MaximaElement(m)
     986        True
     987        sage: is_MaximaElement(1)
     988        False
     989    """
     990    return isinstance(x, MaximaElement)
     991
     992# An instance
     993maxima = Maxima()
     994
     995def reduce_load_Maxima():
     996    """
     997    EXAMPLES::
     998   
     999        sage: from sage.interfaces.maxima import reduce_load_Maxima
     1000        sage: reduce_load_Maxima()
     1001        Maxima
     1002    """
     1003    return maxima
     1004
     1005
     1006def maxima_version():
     1007    """
     1008    EXAMPLES::
     1009   
     1010        sage: from sage.interfaces.maxima import maxima_version
     1011        sage: maxima_version()
     1012        '5.23.2'
     1013    """
     1014    return os.popen('maxima --version').read().split()[-1]
     1015
     1016def __doctest_cleanup():
     1017    import sage.interfaces.quit
     1018    sage.interfaces.quit.expect_quitall()
     1019
     1020
  • sage/symbolic/assumptions.py

    diff -r fee8c73d93a2 -r 1160d58a0f0a sage/symbolic/assumptions.py
    a b  
    475475    global _assumptions
    476476    if len(_assumptions) == 0:
    477477        return
    478     try:
    479         maxima._eval_line('forget(facts());')
    480     except TypeError:
    481         pass
    482478    #maxima._eval_line('forget([%s]);'%(','.join([x._maxima_init_() for x in _assumptions])))
    483479    for x in _assumptions[:]: # need to do this because x.forget() removes x from _assumptions
    484         if isinstance(x, GenericDeclaration):
    485             # these don't show up in facts()
    486             x.forget()
     480        x.forget()
    487481    _assumptions = []