Note: Use only in the MuPAD Notebook Interface. This functionality does not run in MATLAB. |
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
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
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
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 |
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
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
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:
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
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:
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)
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
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
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:
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
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
.
Now call the procedure:
myProc(5)
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);
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)
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)
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.
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.
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)
To define your own functions in MuPAD, use the arrow operator:
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)
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)
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.
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