# Introductory Maple Tutorial

## Outline

This quick overview should get you started with the tools you'll need to use Maple effectively in this class. Many of you have probably used Maple in a calculus class to compute derivatives, integrals, and the like. Note that we will probably not be concentrating on such uses for this class, but rather writing more complicated programs in Maple, where each step is relatively simple so that we have a thorough understanding of what we are doing.

Note that we can't hope to cover every aspect of Maple programming, so you are encouraged to make use of Maple's help pages (in the program and online), as well as the course newsgroup, to answer any further questions you might have.

## Getting Started: Interactive Maple

### To GUI or not to GUI?

There are two ways to run Maple: with the pretty interface (command `xmaple`), and without it. The GUI is (probably) more intuitive to use, but can also create complications. It will also be difficult for you to use if you don't have a personal copy of Maple. So we'll just be using the command line version by default.

To run command line Maple, just type `maple` from the prompt of any of the "cpu" machines (e.g. `cpu02.student.cs.uwaterloo.ca` for undergrads, `cpu102.cs.uwaterloo.ca` for grads). Typing `maple -h` will give a list of all the command-line switches; the only one I find useful (sometimes) is `-q`.

### The Basics

Maple code is a series of expressions. Each expression must be explicitly terminated with a semicolon `;` (using a colon `:` instead suppresses output). Expressions will only be evaluated or simplified to a certain point automatically; further simplifications must be explicitly asked for.

Variables like `x`, `f`, `a`, `bar`, etc. are simply symbols by default. They can also be assigned values with the `:=` operator. Similar to functional programming languages like Scheme or Lisp, variables have no type, so they can refer to any expression (symbols, numbers, matrices, procedures...). However, every expression in Maple does have a type; check it with the `whattype` command.

By default, all the simplifications Maple does are exact and symbolic. Rational, complex, and algebraic numbers are all supported. To find an approximation, use `evalf` (probably won't be used in this class). To evaluate an expression, substituting a specific value for one variable, use `eval`.

### Other Miscellany

Sometimes a group of functions is grouped into a package or module. To access these, you can use the long form of the command, such as `LinearAlgebra[CharacteristicPolynomial]`, or use the `with` command, as in `with(LinearAlgebra)`, to lift those functions to the top namespace.

When you're running big computations, you can prevent those pesky "bytes used" messages with `kernelopts(printbytes=false)`. For timing your programs, use the `time()` command to get the total CPU time used so far in the execution.

## Maple Programming

### Programming Environment

For this course, we'll be asking you to write your Maple programs in plaintext. You can use any text editor you like; some good ones like VIM or Emacs might even recognize Maple syntax. You can write any Maple expressions (such as procedure definitions) into your program file, and then read it into the interactive Maple session with `read`. Alternatively, you can pass in your file on the command line with a statement such as `maple -q < myprogram.mpl`.

### Maple Procedures

A procedure in Maple is written with as `proc(arg1,arg2,...) <expressions> end proc`. Unlike the interactive Maple session, every variable you use must be declared either as an argument or a local or global variable (with the `local` and `global` keywords, respectively). These variable declarations should come first in your program; you probably won't use `global` as often as `local`.

The value returned from your procedure will either be the last statement that gets executed, or the explicit value passed with a `return` statement.

### Ifs and Loops

Maple supports if/then/else and while/for loops. The basic structure of each of these is as follows (type e.g. `?if` for more information):

```if <condition> then <expressions> fi;
for <var> from <start> to <end> do <expressions> od;
while <condition> do <expressions> od;```

### An Example

Here's a procedure that takes an integer n and a number k, and determines whether n can be expressed as the sum of 2 positive k'th powers, and if so returns them.

```# Tells whether n can be expressed as a sum of 2 positive k'th powers,
# and if so computes and returns them.
sumKthPows := proc(n,k)
local a1,a2,success;
a1 := 0;
while a1^k <= n/2 do
a2 := iroot(n-a1^k, k, 'success');
if success then
return a1,a2;
fi;
a1 := a1 + 1;
od;
return false;
end proc;```

Some things to note:

• `sumKthPows` is the name of the procedure, and we'll call it by writing e.g. `sumKthPows(5,2)`. Since a procedure definition is an expression, we assign it just like anything else.
• `#`'s are used for comments.
• We don't usually need parentheses around conditions, etc. as in C.
• Whitespace doesn't matter, but proper indentation makes it easy to read.
• We can return multiple values (more on this in the next section).
• `iroot` is a built-in Maple function. The optional third argument (`'success'` here) is an unevaluated name (more on this under "Number Theory").

### More Programming Stuff

Maple is an interpreted language, so we can do fun things like write recursive programs, programs that return programs, etc., all though these are not necessarily recommended as they will probably be slow.

Programs can take an arbitrary number of arguments, assign default values, etc., which can sometimes be useful. See the help pages under `?parameter` for more details.

`print` statements (and their variants) can be quite handy when writing procedures, especially ones that can take a long time.

## Data Structures

### Expression trees

Any expression that doesn't get completely evaluated to a numbre or some other type of value is actually stored in a linked list, with a single operator describing how the list elements are to be combined.

You can get at this by experimenting with `whattype`, `nops`, and `op`. For example, the expression `5*x + 20^n + 3` is of type "`+`" with three `op`s: `5*x` (of type `*`), `20^n` (of type `^`), and `3` (of type `integer`).

### Sequences

Some basic data structures provided by Maple can be very useful. First, a sequence is just a series of expressions, separated by commas. This is, for example, what we returned from the `sumKthPows` procedure above, in the case of success.

The `seq` command makes it easy to create most kinds of sequences which can be indexed. For example, we can write the first 50 perfect squares as `seq(i^2,i=1..50)`. Here note the range notation `1..50` (in general `a..b`) which is very common in Maple.

### Lists and Sets

A list and a set in Maple are pretty much exactly what we would expect them to be: a list of expressions, and a group of distinct expressions, respectively. A list is formed by putting `[...]` around a sequence, and a set is formed by putting `{,,,}` around a sequence. Lists are especially useful as grouping a sequence into a single expression, which can then be passed to functions and handled with greater ease.

We can access the `i`'th element (starting from 1) of a list or set `A` with `A[i]`. To convert a list or set back to a plain sequence, use empty brackets, e.g. `A[]`.

## Number Theory

### Basic Integer Computations

Most of the basic integer computations such as gcd, lcm, etc. are built-in Maple commands listed in the appendix of this document. We'll talk about how to use one here: `igcdex` (stands for extended GCD over integers).

The format of this function call is `igcdex(a, b, 's', 't')`, where the last two arguments are optional. The return value is the actual greatest common divisor of `a` and `b`. The optional arguments `'s'` and `'t'` are unevaluated names (that's what the quotes are for), and the variables with those names will then be set to the multipliers computed in the Extended Euclidean Scheme. There are quite a few Maple functions that look like this; one we saw above is `iroot`, which takes an optional third argument which will be set to `true` or `false` depending on whether the computed root is exact.

Note that `igcdex` is the preferred way to compute inverses mod a prime `p`. Can you think of how?

### Prime Numbers

A few functions on prime numbers will be very useful to us. `isprime` performs a probabilistic test (which we can just assume works all of the time) to determine whether the given integer is prime. `nextprime` and `prevprime` compute the next integer greater than (resp. less than) the given one which is a prime number. These are especially useful when iterating loops over all prime numbers in some range, for example.

### Factorization

Maple can also factor integers. Of course, we know that there's no known polynomial-time method to do this, so don't expect these methods to be very fast. `ifactor` does what you would expect; all prime factors and their multiplicities are returned. The similarly-named `ifactors` is much more useful when programming; it returns a list of lists with a very specific and well-defined form. Other related functions are `isqrfree`, `numtheory[issqrfree]`, `iroot`, etc.

### Modular Arithmetic

Very often we will perform computations over some small finite field (i.e. mod a prime) instead of over the integers, to avoid intermediate expression swell and greatly speed up computations. The tools to do this are scattered throughout Maple, but the standard ones are `mod`, `modp`, and `mods`. `mod` is used e.g. as in `12 mod 7` in the natural way we would generally write it. `modp` and `mods` are function calls; the difference is the range. `modp(a,p)` returns the unique integer congruent to `a` modulo `p` in the range `0..p-1`, whereas `mods(a,p)` returns the image in the range `-(p-1)/2..(p+1)/2` (here I'm assuming `p` is an odd prime).

Actually, the behaviour of `mod` can be set to either `modp` or `mods` with a statement such as ``mod` := mods` (here the accent quotes must be used). The default behaviour is `modp`.

Many "inert forms" of functions exist which expect to be followed by a `mod`. For example, there is an equivalent to the `eval` function, called `Eval`, which performs evaluation mod a prime. Note that using this form: `Eval(f,x=1) mod p` is much faster than doing `eval(f,x=1) mod p`; although they both return the same final result, the first form will be reducing modulo `p` at each step, greatly increasing the efficiency of the computation.

## Polynomials

### Representation and Access

Polynomials are simply stored in Maple as ordinary expression trees; what makes them polynomials is their mathematical structure. Note that our polynomials can be in any variable or variables, so many of the functions on polynomials will take an argument (usually called `x`), which is the indeterminate we want the function to work over. The useful function `indets` will return a set of all the indeterminates in the given expression.

The `degree` function returns (as we would expect) the degree of the given polynomial. Note that polynomials are by default stored in the sparse representation where only the nonzero terms are written down, We can get all the coefficients of a polynomial with the `coeffs` command. Note that these will be returned in no particular order. You can pass an optional argument to get a list of the monomial corresponding to the coefficients. For greater control, try the `CoefficientVector` command in the `PolynomialTools` package. It might also be convenient to use the `sort` function, which makes sure the terms of a polynomial are printed in order.

### Arithmetic

Basic arithmetic can be performed with the normal operators `+`, `-`, `*`, etc. However, note that products and powers are not expanded by default; to force this, use the `expand` command. For multivariate polynomials, it might be convenient to treat the polynomial as univariate with coefficients in the other indeterminates; for this, `collect` can be used.

The functions `gcd`, `lcm`, `gcdex`, etc. correspond to the normal integer functions, but now working over polynomials. Even more useful will be the inert forms `Gcd`, `Lcm`, etc., which again expect a `mod` to follow. For example, to find the gcd of polynomials `f` and `g` in `x` over the field Z7[x], write `Gcd(f,g,x) mod 7`.

### Polynomial Factorization

Many tools are available to factor polynomials. The functions `factor`, `irreduc`, `roots`, and `sqrfree` all have intert forms (with a capital letter) as well. Note that polynomial factorization actually can be performed in polynomial time, although some of these routines will take some time.

### Efficient Modular Computation

To compute much more efficiently with dense univariate polynomials over a finite field, we will use `modp1`. This works similarly to `modp` and `mods` on the surface, but actually it is doing much more. In fact, a whole different representation is used in this case. To convert to and from this, use the `ConvertIn` and `ConvertOut` functions.

The `modp1` function takes any one of the polynomial operations we've mentioned (and more) in their inert form (i.e. with a capital letter), and a modulus. So, for example, to compute the GCD of `f` and `g` as above over Z7[x] even more efficiently, write `modp1(ConvertIn(f,x),ConvertIn(g,x),7)`. (Of course, the conversion takes some time, so it's best not to keep going back and forth).

## Linear Algebra

### Representation and Access

Matrices have gone through a few historical eras in Maple. We will be using the current preferred representation, from the `LinearAlgebra` package. Note that this is not the same as the old `linalg` package. Our matrices and vectors will be of type `Matrix` and `Vector` resp., not `matrix` and `vector`. This is important.

When you type `with(LinearAlgebra);`, you'll see a whole mess of routines that are getting imported into the namespace. Most of the routines you'll want to use come from these; the most useful ones are listed below.

To create a Matrix or a Vector, you can use the functions `Matrix` and `Vector`, which give many options for instantiating the structures. For small, fixed Matrices and Vectors, you can use the shortcuts `<...>`, with `,` separating the entries of a column vector, and `|` separating the entries of a row vector. A Matrix is just a row vector of column vectors, or a column vector of row vectors. For example, the code `<<1,2>|<3,4>|<5,6>>` produces the matrix

```[1    3    5]
[           ]
[2    4    6]```

To access the entries of a Matrix or Vector, use the subscript brackets `[]` just as with lists or sets. Of course, Matrices will need two indices. Note that the entries of a Matrix by default are indexed in row-major order; that is, the first index selects the row, and the second index selects the column within that row. And again the indices start at 1. You can get the dimensions with the `Dimensions` command.

### Arithmetic

The functions for arithmetic on Matrices and Vectors are all in the `LinearAlgebra` package; type `?LinearAlgebra` or `with(LinearAlgebra);` to see a listing of them. Note that this includes basic arithmetic such as `Multiply` and `Add`, as well as matrix invariant computations such as `Determinant` and `Rank`. Another computation that will be useful is `LinearSolve`, which gives a finds a solution vector x to the system Ax=b, for a given matrix A and vector b.

### Fast Modular Computation

Just as with `modp1` for univariate polynomials, there is a framework for efficient computation with matrices over finite fields. This is in the `LinearAlgebra[Modular]` subpackage (type `?Modular` to see Maple's help page). Again, we need to convert to the special representation; this time we will use `Modular:-Create`, `Modular:-Mod`, and/or `Modular:-Copy` to convert. Then there is a Modular counterpart of just about every standard Matrix computation, e.g. `Modular:-Determinant` and `Modular:-LinearSolve`.

## Where to Get Help

Undoubtedly you will run into little problems, etc. when programming. Luckily, there are many resources available to you:

• This page has a ton of information, much more than I have time to cover during the actual tutorial time. Especially useful will be (I hope) the appendix of commands below, along with Maple's online help.
• There are lots of resources online under maplesoft.com, although most of these require a (totally free!) registration.
• The course newsgroup `uw.cs.cs487` is the ideal place to post programming questions and problems that you encounter (without sharing any solutions!), so that anyone may respond with a solution. This is likely to be much faster than a personal email to the TA or professor, and will allow everyone to benefit (it's likely that your problem is not unique).

## Appendix: Useful Maple Commands

Just type `?command` for any of these to get a synopsis of how they work.

#### Basic Arithmetic

`+`, `-`, `*`, `/`, `^`, `min`, `max`, `abs`, `I`, `eval`, `subs`, `solve`, `expand`, `simplify`, `sum`, `product`, `numer`, `denom`, `normal`,

#### Floating Point

`evalf`, `Digits`, `sqrt`, `log`, `log[b]`, `floor`, `ceil`, `Pi`

#### Integers

`igcd`, `igcdex`, `ilcm`, `iquo`, `irem`, `isprime`, `nextprime`, `ifactor`, `rand`, `factorial`, `binomial`

#### Modular Arithmetic

`mod`, `mods`, `modp`, `&^`

#### Programming

`proc`, `return`, `if`, `for`, `while`, `do`, `local`, `global`, `nargs`, `error`, `print`, `lprint`

#### Comparison

`=`, `<`, `>`, `<=`, `>=`, `<>`

#### Data

`:=`, `''`, `""`, ````, `whattype`, `type`

#### Lists, Sets, Sequences

`[]`, `{}`, `seq`, `nops`, `op`, `union`, `intersect`, `minus`, `subset`

#### Polynomials

`degree`, `sort`, `coeffs`, `lcoeff`, `tcoeff`, `indets`, `collect`, `content`, `primpart`, `with(PolynomialTools)`

#### Polynomial Arithmetic

`gcd`, `gcdex`, `lcm`, `+`, `-`, `*`, `^`, `quo`, `rem`, `randpoly`, `factor`, `factors`, `irreduc`, `sqrfree`, `roots`, `modp1`, `ConvertIn`, `ConvertOut`

#### Inert Commands

`Gcd`, `Gcdex`, `Lcm`, `Eval`, `Quo`, `Rem`, `Factor`, `Factors`, `Roots`, ...

#### Linear Algebra

`<<...>>`, `with(LinearAlgebra)`, `Matrix`, `Vector`, `Dimension`, `RowDimension`, `ColumnDimension`, `Determinant`, `Add`, `Multiply`, `MatrixInverse`, `RandomMatrix`, `LinearAlgebra[Modular]`, `Modular:-Copy`, `Modular:-Mod`, `Modular:-Create`

#### Miscellaneous

`kernelopts(printbytes=false)`, `time`, `showtime`, `quit`, `read`, `save`, `unwith`, `restart`