# HG changeset patch
# User J. Miguel Farto <jmfarto@eii.uva.es>
# Date 1360942195 3600
# Node ID 1da57f4899b39f2face55e6a37f98ec7ca6e554c
# Parent ec1fb07db6e23f9fbd4c34f0d48198d08ec76473
Trac 12295: fix Maple interface
diff git a/sage/interfaces/maple.py b/sage/interfaces/maple.py
a

b


27  27  sage: maple('3 * 5') # optional  maple 
28  28  15 
29  29  sage: maple.eval('ifactor(2005)') # optional  maple 
30   '"(5)*"(401)' 
 30  '``(5)*``(401)' 
31  31  sage: maple.ifactor(2005) # optional  maple 
32   "(5)*"(401) 
 32  ``(5)*``(401) 
33  33  sage: maple.fsolve('x^2=cos(x)+4', 'x=0..5') # optional  maple 
34  34  1.914020619 
35  35  sage: maple.factor('x^5  y^5') # optional  maple 
… 
… 

186  186  sage: maple.isprime(maple.fibonacci(27)) # optional  maple 
187  187  false 
188  188  sage: maple.ifactor(maple.fibonacci(27)) # optional  maple 
189   "(2)*"(17)*"(53)*"(109) 
 189  ``(2)*``(17)*``(53)*``(109) 
190  190  
191  191  Note that the isprime function that is included with Sage (which 
192  192  uses PARI) is better than the Maple one (it is faster and gives a 
… 
… 

266  266  sage: maple == loads(dumps(maple)) 
267  267  True 
268  268  """ 
 269  __maple_iface_opts = [ 
 270  'screenwidth=infinity', 
 271  'errorcursor=false',] 
 272  __maple_command = 'maple t c "interface({})"'.format( 
 273  ','.join(__maple_iface_opts)) 
 274  #errorcursor=false avoids maple command line interface to dump 
 275  #into the editor when an error occurs. Thus pexpect interface 
 276  #is not messed up if a maple error occurs. 
 277  #screenwidth=infinity prevents maple command interface from cutting 
 278  #your input lines. By doing this, file interface also works in the 
 279  #event that sage_user_home + sage_tmp_file_stuff exceeds the 
 280  #length of 79 characters. 
269  281  Expect.__init__(self, 
270  282  name = 'maple', 
271  283  prompt = '#>', 
272   command = "maple t", 
 284  command = __maple_command, 
273  285  maxread = maxread, 
274  286  script_subdirectory = script_subdirectory, 
275  287  restart_on_ctrlc = False, 
… 
… 

277  289  server_tmpdir = server_tmpdir, 
278  290  verbose_start = False, 
279  291  logfile = logfile, 
280   eval_using_file_cutoff=1) # very important that this is 1 
281   # It's very important to use file i/o for everything, 
282   # since maple stupid command line interface always 
283   # dumps you into the editor when an error occurs, 
284   # and I can find no way to turn it off!! 
 292  eval_using_file_cutoff=2048) # 2048 is 
 293  #a small enough value to avoid conflicts with the 4096 limit 
 294  #hardcoded in Expect. 
285  295  
286  296  def _function_class(self): 
287  297  """ 
… 
… 

298  308  return MapleFunction 
299  309  
300  310  def _keyboard_interrupt(self): 
 311  """ 
 312  EXAMPLES:: 
 313  
 314  sage: maple._keyboard_interrupt() #not tested 
 315  Interrupting Maple... 
 316  ... 
 317  RuntimeError: Ctrlc pressed while running Maple 
 318  
 319  :: 
 320  
 321  sage: maple('Matrix(8000,8000)') #not tested 
 322  #Press ctrlc 
 323  ^CInterrupting Maple... 
 324  ... 
 325  RuntimeError: Ctrlc pressed while running Maple 
 326  """ 
301  327  print "Interrupting %s..."%self 
302  328  self._expect.sendline(chr(3)) # send ctrlc 
303  329  self._expect.expect(self._prompt) 
304   self._expect.expect(self._prompt) 
305  330  raise RuntimeError, "Ctrlc pressed while running %s"%self 
306  331  
307  332  def __reduce__(self): 
… 
… 

544  569  z = Expect._eval_line(self, line, allow_use_file=allow_use_file, 
545  570  wait_for_prompt=wait_for_prompt).replace('\\\n','').strip() 
546  571  if z.lower().find("error") != 1: 
547   # The following was very tricky to figure out. 
548   # When an error occurs using Maple, unfortunately, 
549   # Maple also dumps one into the line where the 
550   # error occurred with that line copied in. This 
551   # totally messes up the pexpect interface. However, 
552   # I think the following few lines successfully 
553   # "clear things out", i.e., delete the text from 
554   # the edit buffer and get a clean prompt. 
555   e = self.expect() 
556   e.sendline('%s__sage__;'%(chr(8)*len(line))) 
557   e.expect('__sage__;') 
558   e.expect(self._prompt) 
559  572  raise RuntimeError, "An error occurred running a Maple command:\nINPUT:\n%s\nOUTPUT:\n%s"%(line, z) 
560  573  return z 
561  574  
 575  def _eval_line_using_file(self, line, *args, **kwargs): 
 576  """ 
 577  EXAMPLES:: 
 578  
 579  sage: maple._eval_line_using_file('2+2') # optional  maple 
 580  '4' 
 581  """ 
 582  line += ';' #Adds the maple ";" thing like in self._eval_line 
 583  return Expect._eval_line_using_file( 
 584  self, line, *args, **kwargs) 
 585  
562  586  def cputime(self, t=None): 
563  587  r""" 
564  588  Returns the amount of CPU time that the Maple session has used. If 
… 
… 

693  717  
694  718  sage: print maple._source('curry').strip() # optional  maple 
695  719  p > subs('_X' = args[2 .. nargs], () > p(_X, args)) 
696   sage: maple._source('ZZZ') # optional  maple 
 720  sage: maple._source('ZZZ') #not tested 
697  721  Traceback (most recent call last): 
698  722  ... 
699  723  Exception: no source code could be found 
… 
… 

775  799  
776  800  :: 
777  801  
778   sage: maple.quit() # optional  to reset maple. 
 802  sage: maple.quit() # optional  requires maple. 
779  803  sage: maple('partition(10)') # optional  requires maple 
780  804  partition(10) 
781  805  sage: maple('bell(10)') # optional  requires maple 
… 
… 

796  820  """ 
797  821  Clear the variable named var. 
798  822  
799   Unfortunately, Maple does not have a clear command. The next best 
800   thing is to set equal to the constant 0, so that memory will be 
801   freed. 
 823  To clear a Maple variable, you must assign 'itself' to itself. 
 824  In Maple 'expr' prevents expr to be evaluated. 
802  825  
803  826  EXAMPLES:: 
804  827  
… 
… 

807  830  '2' 
808  831  sage: maple.clear('xx') # optional  maple 
809  832  sage: maple.get('xx') # optional  maple 
810   '0' 
 833  'xx' 
811  834  """ 
812   self.set(var, '0') 
 835  self.set(var, "'{}'".format(var)) 
813  836  
814  837  class MapleFunction(ExpectFunction): 
815  838  def _sage_doc_(self): 
… 
… 

834  857  
835  858  sage: print maple.curry._sage_src_().strip() # optional  maple 
836  859  p > subs('_X' = args[2 .. nargs], () > p(_X, args)) 
837   sage: maple.ZZZ._sage_src_() # optional  maple 
 860  sage: maple.ZZZ._sage_src_() #not tested 
838  861  Traceback (most recent call last): 
839  862  ... 
840  863  Exception: no source code could be found 
… 
… 

866  889  sage: print g.curry._sage_src_().strip() # optional  maple 
867  890  p > subs('_X' = args[2 .. nargs], () > p(_X, args)) 
868  891  sage: m = maple('2') # optional  maple 
869   sage: m.ZZZ._sage_src_() # optional  maple 
 892  sage: m.ZZZ._sage_src_() #not tested 
870  893  Traceback (most recent call last): 
871  894  ... 
872  895  Exception: no source code could be found 
… 
… 

910  933  sage: hash(m) # optional  maple 
911  934  2187277978252104690 
912  935  """ 
913   return int(maple.eval('StringTools:Hash(convert(%s, string));'%self.name())[1:1],16) 
 936  return int(maple.eval('StringTools:Hash(convert(%s, string))'%self.name())[1:1],16) 
914  937  
915  938  def __cmp__(self, other): 
916  939  """ 
… 
… 

1001  1024  sage: t = maple(5); u = maple(3) # optional  maple 
1002  1025  sage: t*u # optional  maple 
1003  1026  15 
 1027  sage: t._mul_(u) # optional  maple 
 1028  15 
1004  1029  sage: M = matrix(ZZ,2,range(4)) # optional  maple 
1005  1030  sage: Mm = maple(M) # optional  maple 
1006  1031  sage: Mm*Mm # optional  maple 
… 
… 

1064  1089  sage: print latex(maple('(x^4  y)/(y^23*x)')) # optional  requires maple 
1065  1090  {\frac {{x}^{4}y}{{y}^{2}3\,x}} 
1066  1091  sage: print latex(maple(pi  e^3)) # optional  requires maple 
1067   \pi  \left( {e^{1}} \right) ^{3} 
 1092  \pi{{\rm e}^{3}} 
 1093  sage: print maple(pi  e^3)._latex_() # optional  requires maple 
 1094  \pi{{\rm e}^{3}} 
1068  1095  
1069  1096  .. note:: 
1070  1097  
… 
… 

1085  1112  sage: m = maple('x^2 + 5*y') # optional  requires maple 
1086  1113  sage: m.sage() # optional  requires maple 
1087  1114  x^2 + 5*y 
 1115  sage: m._sage_() # optional  requires maple 
 1116  x^2 + 5*y 
1088  1117  
1089  1118  :: 
1090  1119  
diff git a/sage/symbolic/integration/integral.py b/sage/symbolic/integration/integral.py
a

b


477  477  
478  478  We integrate the above function in maple now:: 
479  479  
480   sage: g = maple(f); g # optional  requires maple 
 480  sage: g = maple(f); g # random; optional  requires maple 
481  481  sin(x^2)+y^z 
482   sage: g.integrate(x) # optional  requires maple 
 482  sage: g.integrate(x) # random; optional  requires maple 
483  483  1/2*2^(1/2)*Pi^(1/2)*FresnelS(2^(1/2)/Pi^(1/2)*x)+y^z*x 
484  484  
485  485  We next integrate a function with no closed form integral. Notice 