### The Maxima on-line user's manual

Algebra Calculator

#### Do

-- Special operator: do The `do` statement is used for performing iteration. Due to its great generality the `do` statement will be described in two parts. First the usual form will be given which is analogous to that used in several other programming languages (Fortran, Algol, PL/I, etc.); then the other features will be mentioned.

There are three variants of this form that differ only in their terminating conditions. They are:

* `for <variable>: <initial_value> step <increment> thru <limit> do <body>`

* `for <variable>: <initial_value> step <increment> while <condition> do <body>`

* `for <variable>: <initial_value> step <increment> unless <condition> do <body>`

(Alternatively, the `step` may be given after the termination condition or limit.)

<initial_value>, <increment>, <limit>, and <body> can be any expressions. If the increment is 1 then "`step 1`" may be omitted.

The execution of the `do` statement proceeds by first assigning the <initial_value> to the <variable> (henceforth called the control-variable). Then: (1) If the control-variable has exceeded the limit of a `thru` specification, or if the condition of the `unless` is `true`, or if the condition of the `while` is `false` then the `do` terminates. (2) The <body> is evaluated. (3) The increment is added to the control-variable. The process from (1) to (3) is performed repeatedly until the termination condition is satisfied. One may also give several termination conditions in which case the `do` terminates when any of them is satisfied.

In general the `thru` test is satisfied when the control-variable is greater than the <limit> if the <increment> was non-negative, or when the control-variable is less than the <limit> if the <increment> was negative. The <increment> and <limit> may be non-numeric expressions as long as this inequality can be determined. However, unless the <increment> is syntactically negative (e.g. is a negative number) at the time the `do` statement is input, Maxima assumes it will be positive when the `do` is executed. If it is not positive, then the `do` may not terminate properly.

Note that the <limit>, <increment>, and termination condition are evaluated each time through the loop. Thus if any of these involve much computation, and yield a result that does not change during all the executions of the <body>, then it is more efficient to set a variable to their value prior to the `do` and use this variable in the `do` form.

The value normally returned by a `do` statement is the atom `done`. However, the function `return` may be used inside the <body> to exit the `do` prematurely and give it any desired value. Note however that a `return` within a `do` that occurs in a `block` will exit only the `do` and not the `block`. Note also that the `go` function may not be used to exit from a `do` into a surrounding `block`.

The control-variable is always local to the `do` and thus any variable may be used without affecting the value of a variable with the same name outside of the `do`. The control-variable is unbound after the `do` terminates.

```          (%i1) for a:-3 thru 26 step 7 do display(a)\$
a = - 3```

a = 4

a = 11

a = 18

a = 25

```          (%i1) s: 0\$
(%i2) for i: 1 while i <= 10 do s: s+i;
(%o2)                         done
(%i3) s;
(%o3)                          55```

Note that the condition `while i <= 10` is equivalent to `unless i > 10` and also `thru 10`.

```          (%i1) series: 1\$
(%i2) term: exp (sin (x))\$
(%i3) for p: 1 unless p > 7 do
(term: diff (term, x)/p,
series: series + subst (x=0, term)*x^p)\$
(%i4) series;
7    6     5    4    2
x    x     x    x    x
(%o4)            -- - --- - -- - -- + -- + x + 1
90   240   15   8    2```

which gives 8 terms of the Taylor series for `e^sin(x)`.

```          (%i1) poly: 0\$
(%i2) for i: 1 thru 5 do
for j: i step -1 thru 1 do
poly: poly + i*x^j\$
(%i3) poly;
5      4       3       2
(%o3)          5 x  + 9 x  + 12 x  + 14 x  + 15 x
(%i4) guess: -3.0\$
(%i5) for i: 1 thru 10 do
(guess: subst (guess, x, 0.5*(x + 10/x)),
if abs (guess^2 - 10) < 0.00005 then return (guess));
(%o5)                  - 3.162280701754386```

This example computes the negative square root of 10 using the Newton- Raphson iteration a maximum of 10 times. Had the convergence criterion not been met the value returned would have been `done`.

Instead of always adding a quantity to the control-variable one may sometimes wish to change it in some other way for each iteration. In this case one may use `next <expression>` instead of `step <increment>`. This will cause the control-variable to be set to the result of evaluating <expression> each time through the loop.

```          (%i6) for count: 2 next 3*count thru 20 do display (count)\$
count = 2```

count = 6

count = 18

As an alternative to `for <variable>: <value> ...do...` the syntax `for <variable> from <value> ...do...` may be used. This permits the `from <value>` to be placed after the `step` or `next` value or after the termination condition. If `from <value>` is omitted then 1 is used as the initial value.

Sometimes one may be interested in performing an iteration where the control-variable is never actually used. It is thus permissible to give only the termination conditions omitting the initialization and updating information as in the following example to compute the square-root of 5 using a poor initial guess.

```          (%i1) x: 1000\$
(%i2) thru 20 do x: 0.5*(x + 5.0/x)\$
(%i3) x;
(%o3)                   2.23606797749979
(%i4) sqrt(5), numer;
(%o4)                   2.23606797749979```

If it is desired one may even omit the termination conditions entirely and just give `do <body>` which will continue to evaluate the <body> indefinitely. In this case the function `return` should be used to terminate execution of the `do`.

```          (%i1) newton (f, x):= ([y, df, dfx], df: diff (f (x), x),
do (y: ev(df), x: x - f(x)/y,
if abs (f (x)) < 5e-6 then return (x)))\$
(%i2) sqr (x) := x^2 - 5.0\$
(%i3) newton (sqr, 1000);
(%o3)                   2.236068027062195```

(Note that `return`, when executed, causes the current value of `x` to be returned as the value of the `do`. The `block` is exited and this value of the `do` is returned as the value of the `block` because the `do` is the last statement in the block.)

One other form of the `do` is available in Maxima. The syntax is:

for <variable> in <list> <end_tests> do <body>

The elements of <list> are any expressions which will successively be assigned to the `variable` on each iteration of the <body>. The optional termination tests <end_tests> can be used to terminate execution of the `do`; otherwise it will terminate when the <list> is exhausted or when a `return` is executed in the <body>. (In fact, `list` may be any non-atomic expression, and successive parts are taken.)

```          (%i1)  for f in [log, rho, atan] do ldisp(f(1))\$
(%t1)                                  0
(%t2)                                rho(1)
%pi
(%t3)                                 ---
4
(%i4) ev(%t3,numer);
(%o4)                             0.78539816```

There are also some inexact matches for `do`. Try `?? do` to see them.

```(%o1)                                true
(%i2) ```

### Related Examples

##### do-kill-mod

kill(all);

v:[4,8,2,0,0,1,8,7,3,...

s1:(v[1]+v[3]+v[5]+v[...

Calculate

##### do-ratsimp

P(k) := k + 1;

Q(k) := 2*k+3;

R(k) := P(k)/Q(k);

Calculate

##### do-float

x:2^39;

x/1000/1000;

float(x/1000/1000);

Calculate

##### do-if-lambda-let-or-values

:lisp (defun split-if...

:lisp (defvar *my-lis...

:lisp (let* ((result)...

Calculate

##### do-if-integerp

a:0.12345*10*10*10*10...

integerp(a);

truncate(a);

Calculate

##### do-matrix-row-rowop

A:matrix([1,1,1,1],[1...

row(A,2) - row(A,1);

A:rowop(A,2,1,1);

Calculate

##### do-matrix

Question1:matrix([1,1...

for col:1 thru 4 do (...

a;

Calculate

##### do-plot2d-print

plot2d(x^2,[x,-5,5]);

for i from 1 thru 10 ...

Calculate

##### do-matrix

a:matrix([1,1,1,1],[1...

for k:1 thru 4 do (a[...

a;

Calculate

##### do-matrix

a:matrix([1,1,1,1],[1...

for k:1 thru 4 do (a[...

a;

Calculate