Dr. John May

## 2511 Reputation

15 years, 149 days
Maplesoft
Guru

## Social Networks and Content at Maplesoft.com

I am a Senior Developer in the Mathematical Software Group and have been with Maplesoft since 2007. I am also an Adjunct Assistant Professor in the School of Computer Science at the University of Waterloo.

I have a Ph.D in Mathematics from North Carolina State University as well as Masters and Bachelors degrees from the University of Oregon. I have been working on research in computational mathematics since 1997.

My main research interests in are computational linear and polynomial algebra, especially numerical polynomial algebra. I currently work on the exact algebraic solvers as well as other subsystems of Maple.

## Avoid Building things in Loops...

First, it is best to avoid building lists or any other immutable data structure incrementally in a list. Second, are you really trying to build tables?  If not, you should probably not assign to indexed names since those implicitly construct a hash table.

If a is supposed to be a nested list, and c should also be a nested list then you should use nested calls to seq:

(**) a := [[1], [2,3], [3,4,5], [6,7,8,9]]:
(**) c := [ seq( [seq(op(a[j]),j=1..i)], i=1..nops(a) )];

c := [[1], [1, 2, 3], [1, 2, 3, 3, 4, 5], [1, 2, 3, 3, 4, 5, 6, 7, 8, 9]]

It is okay to use a table or array to build things up in a loop, but there will be a small amount of construction and conversion overhead so something like the following will usually be a bit slower than the above.

(**) a := [[1], [2,3], [3,4,5], [6,7,8,9]]:
(**) c := table(); # or c := Array(1..nops(a));
(**) for i from 1 to nops(a) do
c[i] := [seq(op(a[j]),j=1..i)];
end do:
(**) c := convert(c,list);
c := [[1], [1, 2, 3], [1, 2, 3, 3, 4, 5], [1, 2, 3, 3, 4, 5, 6, 7, 8, 9]]

John

## Maple Manuals...

There are some good tips on this sort of thing to be found in both of the Maple programming manuals.  If you do not have printed copies, there are PDFs that can be download in the Maple Documentation Center. They can also be read in the online help at ?ProgrammingGuide and ?AdvancedProgrammingGuide,Contents .

John

## Cannot Replicate...

As written I cannot seem to replicate the problem either in Maple 14 or Maple 7:

for mm from 3 to 5 do print(mm); aaa:=combinat[permute]([e,l,i,z,a], mm); print(nops(aaa)); end do:

I would suspect the error has to do with bad assignment lurking around somewhere else.  Something like the following:

```> b := a;
b := a

> a := ['b', 'c', 'd'];
a := [b, c, d]

> e := a;
Error, too many levels of recursion
```

Where delayed evaluation of 'b' in the assignment to 'a' is preventing an "Error, recursive assignment" error, but then raising the "too many levels of recursion" error whenever a or b is subsequently evaluated.

John

## Plot Components...

I am not the inhouse plotting expert, but as far as I know, there is not a way to do this unless your plots were created initally as plot components (see ?PlotComponent ).

In that case, you can do something like:

`for p in [Plot0, Plot1] do     DocumentTools:-SetProperty(p, pixelHeight, 500);     DocumentTools:-SetProperty(p, pixelWidth, 500);end do;`

That probably doesn't help fix the problem in an existing worksheet, but it might make things easier in a future project.

## Application Centre...

I don't know of anything pre-built in the Maple Library itself, but perhaps this Protein Data Bank ( PDB ) Viewer in the Maple Application Centre might give you a place to start.

John

## Complex Numbers...

These are complex numeric values. Take a look at ?I and ?Complex . If you were expecting real numbers, perhaps there is something wrong with the construction of your matrix.

John

## It depends on the meaning of solve...

In Maple, "solve for q", (mostly) means "find an expression for q valid for essentially all values of the parameters in that expression".  In this case, if you use ?eliminate as suggested by pagan:

eliminate({mu = (1-q)/q, sigma^2 = (1-q)/q^2}, {q});

[{q = 1/(mu+1)}, {sigma^2-mu^2-mu}]

this gives a formula "solving" for q with the proviso that: sigma^2-mu^2-mu=0.  Since this is not "essentially all" values of mu, solve returns no solutions.

Eventually, it would be nice to extend the model of solve to allow for this sort of provisional parametric solution, but there are a lot of practical and theoretical hurdles to doing this for all the cases that solve currently supports.

John

## printf...

If you are in the worksheet and printing lots of things or you need more control, you might prefer a loop and ?printf:

printf("%-15s %-15s %-15s \n", `First heading` , `Second heading` , `Third heading`); for i to nops([entries(A)]) do printf("%-15a %-15a %-15a\n",A(i), B(i), C(i)) end do;

`First heading   Second heading  Third heading   a1              b1              c1             a2              b2              c2             a3              b3              c3             `

If you are using a Maple document, you'd do something a little different with ?cat and ?sprintf instead of printf and assign the result to a ?TextArea using ?DocumentTools.

mytableoutput := cat( sprintf("%-15s %-15s %-15s \n", `First heading` , `Second heading` , `Third heading`), seq(sprintf("%-15a %-15a %-15a\n",A(i), B(i), C(i)), i = 1..nops([entries(A)])));
DocumentTools:-Do(%TextArea0=mytableoutput);

John

## thin option avoids unnecessary work...

@herclau without the thin option, U and V are padded out to be square.  The thin option is useful if your input is has dimensions, say, 10000 by 100.  Without option thin, U would be 10000 by 10000 (with only the first 100 columns being meaningful since there are only 100 non-zero singular values).  With option thin, U would be returned as a 10000 by 100 matrix and its 100 columns will be identical to the first 100 columns of the non-thin U.

Here is a small 3x2 example.

LinearAlgebra:-SingularValues(<1.0,2.0;1.0,2.1;2.0,4.1>, output='U');

vs.

LinearAlgebra:-SingularValues(<1.0,2.0;1.0,2.1;2.0,4.1>, output='U', 'thin');

## RootOfs...

solve writes answers using RootOf to give a compact representation for solutions to (sometimes) simpler problems without expanding them.  In this case, the RootOfs represent roots of quadratic polynomials (the _Z is part of the RootOf representation).  The allvalues command can be used to rewrite the solutions explicitly in terms of radicals in this case:

sol := solve({Wy,Wz},[q3,q4]);
map(allvalues, sol);

Since the case:

solve({Wx,Wy,Wz},[q3,q4]);

is a parametric problem with more equations than variables, I suspect that a solution like 'sol' is computed, but then Maple is unable to guarantee that that solution satisfies the third equation.

John

## ListTools...

The ListTools package has a routine for doing just this: ListTools:-MakeUnique

```(**) L := [1,2,3,4,3,2,3,4,5,4,3,4,5,6];

L := [1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6]

(**) ListTools:-MakeUnique(L);

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

```

John

## f?...

Are you also evaluating "f" or do you want it as a parameter to appear in the solutions?

John

## Maple 13...

Maple 13 solves these over 1 period:

```> solve({cos(x)<1});
{x < 0, -2 Pi < x}, {0 < x, x < 2 Pi}

> solve({cos(x)>=1});
{x = -2 Pi}, {x = 0}, {x = 2 Pi}

```

John

## RootFinding...

Since the equations are polynomials, another option here is to use some of the various RootFinding package commands.

# All isolated solutions:

RootFinding:-Homotopy({e1,e2,e3});

# All isolated Real Solutions:

RootFinding:-Isolate({e1,e2,e3},[x,y,a]);

John

## cat...

`for i from 1 to 5 do cat(`f_`,i) := x -> i; end do;`

John

 5 6 7 8 9 10 Page 7 of 10
﻿