Author: Gregg Musiker (2006-02-02): initial version.
This tutorial is based on the Maple Tutorial for number theory from http://www.math.mun.ca/~drideout/m3370/numtheory.html.
There are several ways to use the Maple Interface in Sage. We will discuss two of those ways in this tutorial.
factor( (x^5-1));
sage: maple('factor(x^5-1)')
(x-1)*(x^4+x^3+x^2+x+1)
Notice, there is no need to use a semicolon.
factor() is a maple command, so we can also factor
in Sage using
sage: maple('(x^5-1)').factor()
(x-1)*(x^4+x^3+x^2+x+1)
where expression.command() means the same thing as
command(expression) in Maple. We will use this second type of
syntax whenever possible, resorting to the first when needed.
sage: maple('(x^12-1)/(x-1)').simplify()
x^11+x^10+x^9+x^8+x^7+x^6+x^5+x^4+x^3+x^2+x+1
The normal command will always reduce a rational function to the lowest terms. The factor command will factor a polynomial with rational coefficients into irreducible factors over the ring of integers. So for example,
sage: maple('(x^12-1)').factor( )
(x-1)*(x+1)*(x^2+x+1)*(x^2-x+1)*(x^2+1)*(x^4-x^2+1)
sage: maple('(x^28-1)').factor( )
(x-1)*(x^6+x^5+x^4+x^3+x^2+x+1)*(x+1)*(1-x+x^2-x^3+x^4-x^5+x^6)*(x^2+1)*(x^
12-x^10+x^8-x^6+x^4-x^2+1)
Another important feature of maple is its online help. We can access this through sage as well. After reading the description of the command, you can press q to immediately get back to your original prompt.
Incidentally you can always get into a maple console by the command
sage: maple.console() # not tested sage: !maple # not tested
Note that the above two commands are slightly different, and the first is preferred.
For example, for help on the maple command fibonacci, we type
sage: maple.help('fibonacci') # not tested, since it uses a pager
We see there are two choices. Type
sage: maple.help('combinat, fibonacci') # not tested, since it uses a pager
We now see how the Maple command fibonacci works under the combinatorics package. Try typing in
sage: maple.fibonacci(10) fibonacci(10)
You will get fibonacci(10) as output since Maple has not loaded the combinatorics package yet. To rectify this type
sage: maple('combinat[fibonacci]')(10)
55
instead.
If you want to load the combinatorics package for future calculations, in Sage this can be done as
sage: maple.with_package('combinat')
or
sage: maple.load('combinat')
Now if we type maple.fibonacci(10), we get the correct output:
sage: maple.fibonacci(10) 55
Some common maple packages include combinat, linalg, and
numtheory. To produce the first 19 Fibonacci
numbers, use the sequence command.
sage: maple('seq(fibonacci(i),i=1..19)')
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584,
4181
Two other useful Maple commands are ifactor and isprime. For example
sage: maple.isprime(maple.fibonacci(27)) false sage: maple.ifactor(maple.fibonacci(27)) ``(2)*``(17)*``(53)*``(109)
Note that the isprime function that is included with Sage (which uses PARI) is better than the Maple one (it is faster and gives a provably correct answer, whereas Maple is sometimes wrong).
sage: alpha = maple('(1+sqrt(5))/2')
sage: beta = maple('(1-sqrt(5))/2')
sage: f19 = alpha^19 - beta^19/maple('sqrt(5)')
sage: f19
(1/2+1/2*5^(1/2))^19-1/5*(1/2-1/2*5^(1/2))^19*5^(1/2)
sage: f19.simplify() # somewhat randomly ordered output...
6765+5778/5*5^(1/2)
Let's say we want to write a maple program now that squares a number if it is positive and cubes it if it is negative. In maple, that would look like
mysqcu := proc(x) if x > 0 then x^2; else x^3; fi; end;
sage: mysqcu = maple('proc(x) if x > 0 then x^2 else x^3 fi end')
sage: mysqcu(5)
25
sage: mysqcu(-5)
-125
More complicated programs should be put in a separate file and loaded.
Module-level Functions
| ) |
Spawn a new Maple command-line session.
sage: maple_console() #not tested
|\^/| Maple 11 (IBM INTEL LINUX)
._|\| |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple Inc.
2007
\ MAPLE / All rights reserved. Maple is a trademark of
<____ ____> Waterloo Maple Inc.
| Type ? for help.
>
| ) |
Returns the maple object created in sage.interfaces.maple.
sage: from sage.interfaces.maple import reduce_load_Maple sage: reduce_load_Maple() Maple
Class: Maple
Type maple.[tab] for a list of all the functions available
from your Maple install. Type maple.[tab]? for Maple's
help about a given function. Type maple(...) to create
a new Maple object, and maple.eval(...) to run a string
using Maple (and get the result back as a string).
| self, [maxread=100], [script_subdirectory=], [server=None], [server_tmpdir=None], [logfile=None]) |
Create an instance of the Maple interpreter.
sage: maple == loads(dumps(maple)) True
Functions: clear,
completions,
console,
cputime,
expect,
get,
help,
load,
set,
source,
trait_names,
with_package
| self, var) |
Clear the variable named var.
Unfortunately, Maple does not have a clear command. The next best thing is to set equal to the constant 0, so that memory will be freed.
sage: maple.set('xx', '2') #optional -- requires Maple
sage: maple.get('xx') #optional
'2'
sage: maple.clear('xx') #optional
sage: maple.get('xx') #optional
'0'
| self, s) |
Return all commands that complete the command starting with the string s. This is like typing s[Ctrl-T] in the maple interpreter.
sage: c = maple.completions('di') #optional -- requires Maple
sage: 'dilog' in c #optional
True
| self) |
Spawn a new Maple command-line session.
sage: maple.console() #not tested
|\^/| Maple 11 (IBM INTEL LINUX)
._|\| |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple Inc.
2007
\ MAPLE / All rights reserved. Maple is a trademark of
<____ ____> Waterloo Maple Inc.
| Type ? for help.
>
| self, [t=None]) |
Returns the amount of CPU time that the Maple session has used. If t is not None, then it returns the difference between the current CPU time and t.
sage: t = maple.cputime() #optional -- requires Maple sage: t #optional, random 0.02 sage: maple.diff(x^2, x) #optional 2*x sage: maple.cputime(t) #optional, random 0.0
| self) |
Returns the pexpect object for this Maple session.
sage: m = Maple() sage: m.expect() is None True sage: m._start() #optional -- requires Maple sage: m.expect() #optional <pexpect.spawn instance at 0x...> sage: m.quit() #optional
| self, var) |
Get the value of the variable var.
sage: maple.set('xx', '2') #optional -- requires Maple
sage: maple.get('xx') #optional
'2'
| self, str) |
Display Maple help about str. This is the same as typing "?str" in the Maple console.
Input:
sage: maple.help('digamma') #not tested
Psi - the Digamma and Polygamma functions
...
| self, package) |
Make a package of Maple procedures available in the interpreter.
Input:
Some functions are unknown to Maple until you use with to include the appropriate package.
sage: maple.quit() # optional -- to reset maple.
sage: maple('partition(10)') # optional
partition(10)
sage: maple('bell(10)') # optional
bell(10)
sage: maple.with_package('combinat') # optional
sage: maple('partition(10)') # optional
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 2], [1, 1, 1, 1,
1, 1, 2, 2], [1, 1, 1, 1, 2, 2, 2], [1, 1, 2, 2, 2, 2], [2, 2, 2, 2, 2],
[1, 1, 1, 1, 1, 1, 1, 3], [1, 1, 1, 1, 1, 2, 3], [1, 1, 1, 2, 2, 3], [1, 2,
2, 2, 3], [1, 1, 1, 1, 3, 3], [1, 1, 2, 3, 3], [2, 2, 3, 3], [1, 3, 3, 3],
[1, 1, 1, 1, 1, 1, 4], [1, 1, 1, 1, 2, 4], [1, 1, 2, 2, 4], [2, 2, 2, 4],
[1, 1, 1, 3, 4], [1, 2, 3, 4], [3, 3, 4], [1, 1, 4, 4], [2, 4, 4], [1, 1,
1, 1, 1, 5], [1, 1, 1, 2, 5], [1, 2, 2, 5], [1, 1, 3, 5], [2, 3, 5], [1, 4,
5], [5, 5], [1, 1, 1, 1, 6], [1, 1, 2, 6], [2, 2, 6], [1, 3, 6], [4, 6],
[1, 1, 1, 7], [1, 2, 7], [3, 7], [1, 1, 8], [2, 8], [1, 9], [10]]
sage: maple('bell(10)') # optional
115975
sage: maple('fibonacci(10)') # optional
55
| self, var, value) |
Set the variable var to the given value.
sage: maple.set('xx', '2') #optional -- requires Maple
sage: maple.get('xx') #optional
'2'
| self, s) |
Display the Maple source (if possible) about s. This is the same as returning the output produced by the following Maple commands:
interface(verboseproc=2): print(s)
Input:
sage: maple.source('curry') #not tested
p -> subs('_X' = args[2 .. nargs], () -> p(_X, args))
| self, [verbose=True], [use_disk_cache=True]) |
Returns a list of all the commands defined in Maple and optionally (per default) store them to disk.
sage: c = maple.trait_names(use_disk_cache=False, verbose=False) #optional sage: len(c) > 100 #optional True sage: 'dilog' in c #optional True
| self, package) |
Make a package of Maple procedures available in the interpreter.
Input:
Some functions are unknown to Maple until you use with to include the appropriate package.
sage: maple.quit() # optional -- to reset maple.
sage: maple('partition(10)') # optional
partition(10)
sage: maple('bell(10)') # optional
bell(10)
sage: maple.with_package('combinat') # optional
sage: maple('partition(10)') # optional
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 2], [1, 1, 1, 1,
1, 1, 2, 2], [1, 1, 1, 1, 2, 2, 2], [1, 1, 2, 2, 2, 2], [2, 2, 2, 2, 2],
[1, 1, 1, 1, 1, 1, 1, 3], [1, 1, 1, 1, 1, 2, 3], [1, 1, 1, 2, 2, 3], [1, 2,
2, 2, 3], [1, 1, 1, 1, 3, 3], [1, 1, 2, 3, 3], [2, 2, 3, 3], [1, 3, 3, 3],
[1, 1, 1, 1, 1, 1, 4], [1, 1, 1, 1, 2, 4], [1, 1, 2, 2, 4], [2, 2, 2, 4],
[1, 1, 1, 3, 4], [1, 2, 3, 4], [3, 3, 4], [1, 1, 4, 4], [2, 4, 4], [1, 1,
1, 1, 1, 5], [1, 1, 1, 2, 5], [1, 2, 2, 5], [1, 1, 3, 5], [2, 3, 5], [1, 4,
5], [5, 5], [1, 1, 1, 1, 6], [1, 1, 2, 6], [2, 2, 6], [1, 3, 6], [4, 6],
[1, 1, 1, 7], [1, 2, 7], [3, 7], [1, 1, 8], [2, 8], [1, 9], [10]]
sage: maple('bell(10)') # optional
115975
sage: maple('fibonacci(10)') # optional
55
Special Functions: __init__,
__reduce__,
_assign_symbol,
_commands,
_equality_symbol,
_eval_line,
_function_class,
_function_element_class,
_help,
_install_hints,
_keyboard_interrupt,
_object_class,
_quit_string,
_read_in_file_command,
_source,
_true_symbol
| self) |
sage: maple.__reduce__() (<function reduce_load_Maple at 0x...>, ()) sage: f, args = _ sage: f(*args) Maple
| self) |
Returns the symbol used for assignment in Maple.
sage: maple._assign_symbol() ':='
| self) |
Return list of all commands defined in Maple.
sage: c = maple._commands() #optional -- requires Maple sage: len(c) > 100 #optional True sage: 'dilog' in c #optional True
| self) |
Returns the symbol used for equality testing in Maple.
sage: maple._equality_symbol() '='
sage: maple(2) == maple(2) #optional -- requires Maples True
| self, line, [allow_use_file=True], [wait_for_prompt=True]) |
sage: maple._eval_line('2+2') #optional -- requires Maple
'4'
| self) |
sage: maple._function_class() <class 'sage.interfaces.maple.MapleFunction'>
sage: type(maple.diff) <class 'sage.interfaces.maple.MapleFunction'>
| self) |
Returns the MapleFunctionElement class.
sage: maple._function_element_class() <class 'sage.interfaces.maple.MapleFunctionElement'>
sage: two = maple(2) #optional -- requires Maple sage: type(two.gcd) #optional <class 'sage.interfaces.maple.MapleFunctionElement'>
| self, str) |
Returns the Maple help on str.
sage: maple._help('gcd') #optional -- requires Maple
"gcd - greatest common divisor of polynomials...
| self) |
Hints for installing Maple on your computer.
Author: William Stein and Justin Walker (2006-02-12).
sage: print maple._install_hints() In order...
| self) |
Returns the class of MapleElements.
sage: maple._object_class() <class 'sage.interfaces.maple.MapleElement'>
sage: m = maple(2) #optional -- requires Maple sage: type(m) #optional <class 'sage.interfaces.maple.MapleElement'>
| self) |
sage: maple._quit_string() 'quit'
sage: m = Maple() sage: a = m(2) #optional -- requires Maple sage: m.is_running() #optional True sage: m.quit() #optional sage: m.is_running() #optional False
| self, filename) |
Returns the string used to read filename into Maple.
sage: maple._read_in_file_command('test')
'read "test"'
sage: filename = tmp_filename()
sage: f = open(filename, 'w')
sage: f.write('xx := 22;
')
sage: f.close()
sage: maple.read(filename) #optional -- requires Maple
sage: maple.get('xx').strip() #optional
'22'
| self, s) |
Tries to return the source code of a Maple function str as a string.
sage: print maple._source('curry').strip() #optional requires maple
p -> subs('_X' = args[2 .. nargs], () -> p(_X, args))
sage: maple._source('ZZZ') #optional requires maple
Traceback (most recent call last):
...
Exception: no source code could be found
| self) |
Returns the symbol used for truth in Maple.
sage: maple._true_symbol() 'true'
sage: maple(2) == maple(2) #optional -- requires Maples True
Class: MapleElement
Functions: trait_names
| self) |
sage: a = maple(2) #optional -- requires Maple sage: 'sin' in a.trait_names() #optional True
Special Functions: __cmp__,
__float__,
__repr__,
_latex_,
_mul_
| self, other) |
Compare equality between self and other, using maple.
These examples are optional, and require Maple to be installed. You don't need to install any Sage packages for this.
sage: a = maple(5) sage: b = maple(5) sage: a == b True sage: a == 5 True
sage: c = maple(3) sage: a == c False sage: a < c False sage: a < 6 True sage: c <= a True
sage: M = matrix(ZZ, 2, range(1,5)) sage: Mm = maple(M) sage: Mm == Mm True sage: Mm < 5 True sage: (Mm < 5) == (M < 5) True sage: 5 < Mm False
TESTS:
sage: x = var('x')
sage: t = maple((x+1)^2)
sage: u = maple(x^2+2*x+1)
sage: u == t # todo: not implemented
True # returns False, should use 'testeq' in maple
sage: maple.eval('testeq(%s = %s)'%(t.name(),u.name()))
'true'
| self) |
Returns a floating point version of self.
sage: float(maple(1/2)) #optional -- requires Maple 0.5 sage: type(_) #optional <type 'float'>
| self) |
Return a string representation of self.
These examples are optional, and require Maple to be installed. You don't need to install any Sage packages for this.
sage: x = var('x')
sage: maple(x)
x
sage: maple(5)
5
sage: M = matrix(QQ,2,range(4))
sage: maple(M)
Matrix(2, 2, [[0,1],[2,3]])
| self) |
You can output Maple expressions in latex.
sage: print latex(maple('(x^4 - y)/(y^2-3*x)')) # optional
{\frac {{x}^{4}-y}{{y}^{2}-3\,x}}
sage: print latex(maple(pi - e^3)) # optional
\pi - \left( {e^{1}} \right) ^{3}
Note:
Some expressions might require the Maple style file
maple2e.sty in order to latex correctly.
| self, right) |
These examples are optional, and require Maple to be installed. You don't need to install any Sage packages for this.
sage: t = maple(5); u = maple(3) sage: t*u 15 sage: M = matrix(ZZ,2,range(4)) sage: Mm = maple(M) sage: Mm*Mm Matrix(2, 2, [[2,3],[6,11]])
sage: v = vector(ZZ,2,[2,3]) sage: vm = maple(v) sage: vm*Mm Vector[row](2, [6,11])
sage: t*Mm Matrix(2, 2, [[0,5],[10,15]])
Class: MapleFunction
Special Functions: _sage_doc_,
_sage_src_
| self) |
Returns the Maple help for this function. This gets called when doing "?" on self.
sage: maple.gcd._sage_doc_() #optional -- requires Maple "gcd - greatest common divisor of polynomials...
| self) |
Returns the source code of self. This is the function that eventually gets called when doing maple.gcd?? for example.
sage: print maple.curry._sage_src_().strip() #optional requires maple
p -> subs('_X' = args[2 .. nargs], () -> p(_X, args))
sage: maple.ZZZ._sage_src_() #optional requires maple
Traceback (most recent call last):
...
Exception: no source code could be found
Class: MapleFunctionElement
Special Functions: _sage_doc_,
_sage_src_
| self) |
Returns the Maple help for this function. This gets called when doing "?" on self.
sage: two = maple(2) #optional -- requires Maple sage: two.gcd._sage_doc_() #optional "gcd - greatest common divisor of polynomials...
| self) |
Returns the source code of self.
sage: g = maple('gcd') #optional requires maple
sage: print g.curry._sage_src_().strip() #optional
p -> subs('_X' = args[2 .. nargs], () -> p(_X, args))
sage: m = maple('2') #optional
sage: m.ZZZ._sage_src_() #optional
Traceback (most recent call last):
...
Exception: no source code could be found
See About this document... for information on suggesting changes.