14.8.1 Tutorial

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.

  1. If you have a maple expression such as
    factor( (x^5-1));
    
    We can write that in sage as

    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.

  2. Since Sage is written in Python, we can also import maple commands and write our scripts in a pythonic way. For example, 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;
In SAGE, we write

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

maple_console( )

reduce_load_Maple( )

Class: Maple

class Maple
Interface to the Maple interpreter.

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).

Maple( self, [maxread=100], [script_subdirectory=], [server=None], [server_tmpdir=None], [logfile=None])

Create an instance of the Maple interpreter.

Functions: completions,$ \,$ console,$ \,$ cputime,$ \,$ expect,$ \,$ get,$ \,$ get_using_file,$ \,$ help,$ \,$ load,$ \,$ set,$ \,$ source,$ \,$ trait_names,$ \,$ with_package

completions( 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.

get( self, var)

Get the value of the variable var.

get_using_file( self, var)

Get the value of the variable var using a file.

(I would make this the default for values that are bigger than a few thousand characters. However, it's not at all obvious how to figure out if the string representation of an object is big ahead of time! We assume it is for now, if the string used to create the object was big.)

help( self, str)

Display Maple help about str. This is the same as typing "?str" in the Maple console.

Input:

str
- a string to search for in the maple help system

load( self, package)

Make a package of Maple procedures available in the interpreter.

Input:

package
- string

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

set( self, var, value)

Set the variable var to the given value.

source( 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:

s
- a string representing the function whose source code you want

with_package( self, package)

Make a package of Maple procedures available in the interpreter.

Input:

package
- string

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,$ \,$ _help,$ \,$ _install_hints,$ \,$ _keyboard_interrupt,$ \,$ _object_class,$ \,$ _quit_string,$ \,$ _read_in_file_command,$ \,$ _source,$ \,$ _true_symbol

_commands( self)

Return list of all commands defined in maple.

_install_hints( self)

Hints for installing Maple on your computer.

Author: William Stein and Justin Walker (2006-02-12).

_source( 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

Class: MapleElement

class MapleElement

Functions: trait_names

Special Functions: __cmp__,$ \,$ __float__,$ \,$ __repr__,$ \,$ _latex_,$ \,$ _mul_

__cmp__( 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'

__repr__( 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]])

_latex_( 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.

_mul_( 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

class MapleFunction

Special Functions: _sage_doc_,$ \,$ _sage_src_

_sage_src_( 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

class MapleFunctionElement

Special Functions: _sage_doc_,$ \,$ _sage_src_

_sage_src_( self)

Returns the source code of self.

sage: g = maple('gcd')                   #optional requires maple
sage: print g.curry._sage_src_().strip() #optional requires maple
p -> subs('_X' = args[2 .. nargs], () -> p(_X, args))
sage: m = maple('2')                     #optional requires maple
sage: m.ZZZ._sage_src_()                 #optional requires maple
Traceback (most recent call last):
...
Exception: no source code could be found

See About this document... for information on suggesting changes.