# 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: Ctrl-c pressed while running Maple |
| 318 | |
| 319 | :: |
| 320 | |
| 321 | sage: maple('Matrix(8000,8000)') #not tested |
| 322 | #Press ctrl-c |
| 323 | ^CInterrupting Maple... |
| 324 | ... |
| 325 | RuntimeError: Ctrl-c pressed while running Maple |
| 326 | """ |
301 | 327 | print "Interrupting %s..."%self |
302 | 328 | self._expect.sendline(chr(3)) # send ctrl-c |
303 | 329 | self._expect.expect(self._prompt) |
304 | | self._expect.expect(self._prompt) |
305 | 330 | raise RuntimeError, "Ctrl-c 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^2-3*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 |