Accelerating the pace of engineering and science

# Documentation

## Programming Basics

### Conditional Control

#### Use if Statements

You can execute different groups of statements depending on particular conditions. Use if to define a condition, and use then to define the group of statements you want to execute when the condition is true:

```x := -3:
if x < 0 then
y := x + 2;
x := -x;
print(x, y)
end_if:```

You also can define the group of statements that you want to execute when the condition is false:

```x := 3:
if x < 0 then
y := x + 2;
x := -x;
print(x, y)
else
y := x + 2;
x := x;
print(x, y)
end_if```

MuPAD® does not require parentheses around conditions:

```x := 10:
if testtype(x, Type::Positive) = TRUE and
type(x) = DOM_INT then
print(Unquoted, "x = ".x." is a positive integer");
end_if```
```x = 10 is a positive integer
```

#### Apply Multiple Conditions

You can use multiple conditions in conditional statements. Combine multiple conditions by the logical operators:

```x := 5:
y := 6:
if x > 0 and 1 - y > 0 then
print(Unquoted, "the condition is true")
else
print(Unquoted, "the condition is false")
end_if:```
```the condition is false
```
```x := 5:
y := 6:
if x > 0 or 1 - y > 0 then
print(Unquoted, "the condition is true")
else
print(Unquoted, "the condition is false")
end_if:```
```the condition is true
```

#### Use Nested Conditional Statements

MuPAD supports the use of nested conditional statements. For example:

```x := 5:
if testtype(x, DOM_COMPLEX) = TRUE then
print("The Heaviside function is undefined for complex numbers")
else
if x = 0 then
heavisideX := 1/2
else
if x < 0 then
heavisideX := 0
else
heavisideX := 1
end_if:
end_if;
end_if```

For nested if ... else if, use the elif command as a shortcut:

```x := 0:
if (testtype(x, DOM_COMPLEX) = TRUE) then
print("The Heaviside function is undefined for complex numbers")
elif x = 0 then
heavisideX := 1/2
elif x < 0 then
heavisideX := 0
else
heavisideX := 1;
end_if```

#### Use case and otherwise Statements

To choose between several cases, use the case command. The case statement looks for the first valid condition. After that, it executes all the statements between this condition and the keyword end_if, without checking the conditions:

```x := 4:
case x
of 1 do
of 2 do
of 3 do print("three or less")
of 4 do print("four")
of 5 do print("five")
otherwise print("6 or more")
end_case:```

To exit the case statement after executing the statements written under the first valid condition, use the break command. See Exiting a Conditional Statement for more details.

 Note:   MuPAD executes the case statements differently from MATLAB®. MATLAB executes only the first matching case statement and skips the following case statements. In MuPAD, you must use the break command to stop execution of the following statements.

#### Exit a Conditional Statement

To exit a conditional statement after executing the statements written under the first valid condition, use the break command. For example, select the meaning of the traffic light signals:

```trafficLight := yellow:
case trafficLight
of red do print(Stop); break;
of yellow do print(Caution);  break;
of green do print(Go); break;
end_case```

#### Return Value of a Conditional Statement

All MuPAD commands produce some return values. Conditional statements return the result of the last executed command:

```mapColor := blue:
if mapColor = blue then
"water"
else
"land"
end_if```

Use the return value of a conditional statement like any other value. For example, assign the return value to a variable. By default, MuPAD does not allow conditional statements in assignments. To create a valid assignment, enclose conditional statements in parentheses. Suppress the output of the return value of a conditional statement with a colon:

```mapColor := blue:
terrain := (if mapColor = blue then "water" else "land" end_if):```

Write a sentence by concatenating the following string and the variable terrain:

`print(Unquoted, "Blue color on maps usually shows ".terrain)`
```Blue color on maps usually shows water
```

The following case statement also returns the result of the last assignment:

```palette := color:
case palette
of monochrome do
[color1, color2] := [black, white];
break;
of color do
[color1, color2, color3] := [red, green, blue];
break;
end_case```

#### Display Intermediate Results

By default, MuPAD does not display intermediate results obtained inside a conditional statement even if you use semicolons after statements. To see intermediate results, use the print command inside a conditional statement:

```Omega := 2:
if Omega > PI/2 and Omega < PI then
signSinOmega := 1;
signCosOmega := -1;
print(signSinOmega, signCosOmega)
end_if:```

### Loops

#### Use Loops with a Fixed Number of Iterations (for Loops)

The for loop repeats a group of statements for a fixed number of iterations. The loop starts with the command for and ends with end_for or just end. MuPAD executes all statements between these two words as many times as you specify. For example, compute the factorial of an integer using the loop:

```x := 1:
for i from 1 to 5 do
x := x * i;
end_for```

More Efficient Alternative to for Loops.  You often can speed up the execution of MuPAD code by replacing for loops with the sequence generator \$. For example, instead of the loop

```x := 1:
for i from 1 to 10 do
x := x * i;
end_for```

use the statement:

``*`(i \$ i = 1..10)`

Control Step Size and Count Up and Down.  By default, the loop increments the value of a counter by 1 in each step. You can change the step size:

```for i from 1 to 3 step 1/2 do
print(i)
end_for```

To count backwards decreasing the value of a counter with each step, instead of to, use the keyword downto:

```for i from 3 downto 1 do
print(i)
end_for```

Use Mathematical Structures in for Loops.  MuPAD supports the use of structures such as lists and matrices in for loops:

```for i in [1, -4, a, b] do
print(i^2)
end_for```

```s := 0:
for i in linalg::hilbert(3) do
s := s + i^2
end_for```

#### Use Loops with Conditions (while and repeat Loops)

Condition at the Beginning (while Loops).  MuPAD supports the use of loops with logical conditions. The while loop continues while the execution conditions are valid. The loop starts with while and ends with end_while or just end. MuPAD executes all the statements between these commands repeatedly as long as the execution conditions are true. In the while loop, MuPAD evaluates the conditions before each iteration. When the condition becomes false, the loop terminates without executing the statements of the current iteration:

```i := 2;
while i < 16 do
i := i^2;
print(i)
end_while:```

Termination Condition at the End (repeat Loops).  The repeat loop continues until the termination condition becomes valid. The loop starts with repeat and ends with end_repeat. MuPAD executes all the statements between these commands repeatedly while the conditions are false. The repeat loop tests a termination condition at the end of each iteration. When the condition becomes true, the loop terminates after executing the statements of the current iteration:

```i := 2;
repeat
i := i^2;
print(i)
until i >= 16 end_repeat:```

Avoid Infinite Loops: Set a Counter.  The while and repeat loops do not operate for a fixed number of steps. If the execution or termination conditions of such loops never become true, MuPAD can execute the statements within these loops infinitely. For example, if the termination condition is not valid during the first iteration, and it does not change inside the loop, the loop is infinite:

```i := 1;
repeat
print(i)
until i > 3 end_repeat:```

To avoid this infinite loop, use the additional statement to change it in each iteration:

```i := 1;
repeat
i := i + 1;
print(i)
until i > 3 end_repeat:```

Use Multiple Conditions.  You can use multiple conditions combining the expressions by and, or, xor, or other logical operators:

```i := 2:
j := 3:
repeat
i := i*j;
j := j^2;
print(i, j)
until i > 100 and j > 10 end_repeat:```

```i := 2:
j := 3:
repeat
i := i*j;
j := j^2;
print(i, j)
until i > 100 or j > 10 end_repeat:```

#### Use Nested Loops

You can place one or several loops inside another loop. Internal loops can be of the same or different types:

```s := 0:
for i from 1 to 3 do
for j from 1 to 2 do
s := s + i + j;
end_for
end_for:
print(s)```

```s := 0:
for i from 1 to 3 do
j := 1:
while j <= 2 do
s := s + i + j;
j := j + 1;
end_while
end_for:
print(s)```

#### Exit a Loop

To add a possibility to exit a loop, use the break command. Suppose you want to exit a loop if some condition is true:

```for i from 1 to 3 do
for j from 1 to 2 do
if i = j then
print(Unquoted, "i = j = ".expr2text(i));
break
end_if
end_for
end_for:```
```i = j = 1
```
```i = j = 2
```

The break command lets you exit the loop in which you place this command. If you create nested loops and use break inside an inner loop, MuPAD continues to execute the statements in the outer loops:

```for i from 1 to 3 do
for j from 1 to 2 do
if i = j then
print(Unquoted, "break with i = j = ".i);
break
end_if;
print(Unquoted, "i = ".i.", j = ".j);
end_for
end_for:```
```break with i = j = 1
```
```i = 2, j = 1
```
```break with i = j = 2
```
```i = 3, j = 1
```
```i = 3, j = 2
```

Suppose you want to stop executing the statements and exit the nested loops as soon as the condition i = j is true. Use the additional variable for the break state of the inner loop. Use this variable to exit the outer loop:

```breakAll := FALSE:
for i from 1 to 3 do
for j from 1 to 2 do
if i = j then
print(Unquoted, "break with i = j = ".i);
breakAll := TRUE;
break
end_if;
print(Unquoted, "i = ".i.", j = ".j);
end_for;
if breakAll then
break
end_if;
end_for:```
```break with i = j = 1
```

#### Skip Part of Iteration

To skip the commands from a particular point to the end of a loop and start the next iteration, use the next command:

```for i from 1 to 3 do
for j from 1 to 2 do
if i = j then
print(Unquoted, "i = j = ".expr2text(i));
next
end_if;
print(Unquoted, "i = ".expr2text(i), "j = ".expr2text(j))
end_for
end_for:```
```i = j = 1
```
```i = 1, j = 2
```
```i = 2, j = 1
```
```i = j = 2
```
```i = 3, j = 1
```
```i = 3, j = 2
```

#### Return Value of a Loop

All MuPAD commands produce some return values. Loops in MuPAD return the result of the last executed statement:

```for i from 1 to 3 do
x := 2*i;
y := 3*i
end_for```

Suppress the output of the return value with a colon:

```for i from 1 to 3 do
x := 2*i;
y := 3*i
end_for:```

#### Display Intermediate Results

By default, MuPAD does not display intermediate results obtained inside a loop even if you use semicolons after commands. To see intermediate results, use the print command inside a loop:

```i := 1;
while i < 3 do
i := i + 1;
print(i)
end_while:```

To display results of each iteration in a for loop, also use the print command:

```for i from 1 to 5 do
x := i!;
print(Unquoted, expr2text(i)."! = ".expr2text(x))
end_for```
```1! = 1
```
```2! = 2
```
```3! = 6
```
```4! = 24
```
```5! = 120
```

### Procedures

#### Create a Procedure

If you want to execute a piece of code repeatedly, create and use a procedure. Define a procedure with the proc command. Enclose your code in the begin and end_proc commands:

```myProc:= proc(n)
begin
if n = 1 or n = 0 then
1
else
n * myProc(n - 1)
end_if;
end_proc:```

Use end as a shortcut for end_proc.

#### Call a Procedure

Now call the procedure:

`myProc(5)`

#### Control Return Values

By default, a procedure returns the result of the last executed command. If you want to return other results, use the return command. For example, create a procedure that computes the factorials of integer numbers:

```myProcReturn := proc(n)
begin
if n = 0 or n = 1 then
return(1);
end_if;
n * myProcReturn(n - 1);
end_proc:```

Call the procedure:

`myProcReturn(5)`

To display the results on your screen without returning them, use the print command:

```myProcPrint:= proc(n)
begin
print(n);
if n = 0 or n = 1 then
return(1);
end_if;
n * myProcPrint(n - 1);
end_proc:```

Call the procedure:

`myProcPrint(5);`

#### Return Multiple Results

To return several results from a procedure, use such structures as lists or matrices as return values:

```myProcSort:= proc(a, b)
begin
if a < b then
[a, b]
else
[b, a]
end_if;
end_proc:```
`myProcSort(4/5, 5/7)`

#### Return Symbolic Calls

Many built-in MuPAD procedures can return symbolic calls to themselves when they cannot compute results as exact values. For example, when you compute sin(PI/2), the sin function returns the exact value 1. At the same time, when you compute sin(x/2), the sin function returns the symbolic call to itself:

`sin(x/2)`

To enable your custom procedure to return symbolic calls, use the special syntax procname(args()). For example, create the procedure that computes a factorial of its argument:

```f := proc(x)
begin
if testtype(x, Type::PosInt) then
return(x!)
else
return(procname(args()))
end_if:
end_proc:```

If its argument is a positive integer, this procedure returns an exact number:

`f(5), f(10)`

Otherwise, it does not error, but returns a symbolic call to itself:

`f(1/3), f(1.1), f(x), f(x + 1)`

#### Use Global and Local Variables

Inside a procedure, all variables fall into two categories: global and local. Global variables are accessible from everywhere inside a notebook. Local variables are accessible only from within a procedure.

Global Variables.  Suppose you want to create a procedure gProc and use the global variable gVar inside the procedure:

```gProc := proc(x)
begin
gVar := gVar^2 + x^2 + 1
end_proc:```

When you call this procedure, the value of the variable gVar changes:

```gVar := 10;
gProc(5):
gVar```

Multiple calls change the value of the global variable further:

```gProc(5):
gVar```

 Note:   Avoid using unnecessary global variables.

Global variables reduce code readability, occupy the global namespace, and often lead to errors. When you use global variables inside a procedure, always verify that each call to the procedure changes global variables as intended.

Local Variables.  You can access and modify local variables only inside a procedure. Suppose, you use a variable lVar in your notebook:

`lVar := 10`

To declare a local variable, use the local command inside a procedure:

```lProc := proc(x)
local lVar;
begin
lVar := 10;
lVar := lVar^2 + x^2 + 1
end_proc:```

When you call this procedure, the value of the variable lVar changes only inside a procedure. Outside the procedure, the variable does not change its value:

```lProc(5):
lVar```

If you declare a local variable, it does not inherit the value of a global variable with the same name. Local variables are not identifiers of type DOM_IDENT. They belong to a special domain type DOM_VAR. Therefore, you cannot use a local variable as a symbolic variable. Before performing computations with a local variable, you must assign a value to that variable. For example, without the assignment lVar:= 10, the procedure call lProc returns an error message:

```lProc := proc(x)
local lVar;
begin
lVar := lVar^2 + x^2 + 1
end_proc:```
`lProc(5)`
```Warning: Uninitialized variable 'lVar' is used.
Evaluating: lProc
```
```Error: The operand is invalid. [_power]
Evaluating: lProc
```

Local variables cannot have assumptions.

#### Restore Values and Properties of Global Variables Modified in Procedures

When you use global variables inside a procedure, you can save their original values and properties, and recover them after the procedure. Suppose, you want to use more decimal digits for calculations with floating-point numbers inside a procedure. By default, the number of digits is 10:

`DIGITS`

To save this default value, use the save command at the beginning of the procedure:

```myProcSave := proc(newDigits, x)
save DIGITS;
begin
DIGITS := newDigits;
print(float(x));
end_proc:```

After you call the procedure myProcSave, MuPAD restores the value of the global variable DIGITS:

```myProcSave(20, PI);
DIGITS```

The combination of save and delete lets you temporarily free the variable for the use inside a procedure. For example, the procedure cannot use the variable x because the variable has a value assigned to it:

```x := 10:
proc()
begin
solve(x^2 + x = 1, x)
end_proc();```
```Error: Invalid variable to solve for. [solve]
```

Use the save command to save the original value 10. Then, free the variable x using the delete command:

```x := 10:
proc()
save x;
begin
delete x;
solve(x^2 + x = 1, x)
end_proc()```

After the procedure call, MuPAD restores the original value of x:

`x`

The save and delete combination is helpful when you want to use a symbolic variable (without any value assigned to it) inside a procedure. You cannot use local variables for that purpose because a local variable in MuPAD is not an identifier. A local variable must have a value assigned to it. Also, you cannot specify assumptions on local variables, and you cannot integrate with respect to local variables.

### Functions

#### Call Existing Functions

If you want to execute the same code repeatedly, create a procedure and use it. As a shortcut for simple procedures, create and use functions. Compared to procedures, functions require less complicated syntax. Like procedures, functions let you use the same code for different arguments as many times as you need. For example, you can always calculate sine and cosine of a particular value:

```sin(30.0), sin(-1.0), sin(0.5);
cos(10.0), cos(-0.8), cos(3.0)```

#### Create Functions

`f := x -> x^2`

After defining a function, call it in the same way you call system functions:

`f(1), f(x), f(sin(x))`

The arrow operator also can create a multivariate function:

`g := (x, y) -> x^2 + y^3`

Call the multivariate function with numeric or symbolic parameters:

`g(5, 2); g(x, 2*x); g(a, b)`

#### Evaluate Expressions While Creating Functions

If you use an arrow operator to define a function, MuPAD does not evaluate the right-side expression:

`f1 := x -> int(x^2, x)`

To evaluate the right-side expression when defining a function, use the double arrow operator:

`f2 := x --> int(x^2, x)`

#### Use Functions with Parameters

Besides symbolic variables, functions can contain symbolic parameters. To evaluate such a function for particular values of symbolic parameters, use evalAt or the vertical bar | as a shortcut:

```fa := x -> x^2 + a:
fa(2);
fa(2) | a = 10```

Functions with symbolic parameters serve best for interactive use in a notebook. In your regular code, avoid unnecessary creation of such functions. When using a symbolic parameter, you use a global variable even though you do not explicitly declare it. See Global Variables for information on global variables and recommendations on their use.

### Shortcut for Closing Statements

As a shortcut for a closing statement, use the end command. This command closes:

• Conditional structures if ... then ... else (a shortcut for end_if)

• Case Selection Structures case ... of (a shortcut for end_case)

• Loops (a shortcut for end_for, end_repeat, and end_while)

• Procedures (a shortcut for end_proc)

For example, the following two loops are equivalent:

```for i in [0, 1, 0, 0] do
if i = 1 then
print(Unquoted, "True")
else
print(Unquoted, "False")
end_if
end_for```
```False
```
```True
```
```False
```
```False
```
```for i in [0, 1, 0, 0] do
if i = 1 then
print(Unquoted, "True")
else
print(Unquoted, "False")
end
end```
```False
```
```True
```
```False
```
```False
```