# Documentation

## Programming Basics

 Note:   Use only in the MuPAD Notebook Interface. This functionality does not run in MATLAB.

### 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 ```