Documentation |
Assign variables
This functionality does not run in MATLAB.
x := value _assign(x, value) [x_{1}, x_{2}, …] := [value_{1}, value_{2}, …] _assign([x1, x2, …], [value1, value2, …]) f( X1, X2, … ) := value _assign(f(X1, X2, …), value)
x := value assigns the variable x a value.
[x1, x2, ...] := [value1, value2, ...] assigns the variables x1, x2 etc. the corresponding values value1, value2 etc.
f(X1, X2, ...) := value adds an entry to the remember table of the procedure f.
_assign(x, value) is equivalent to x := value.
_assign([x1, x2, ...], [value1, value2, ...]) is equivalent to [x1, x2, ...] := [value1, value2, ...]. Both lists must have the same number of elements.
Note: If x is neither a list, nor a table, nor an array, nor an hfarray, nor a matrix, nor an element of a domain with a slot "set_index", then an indexed assignment such as x[i] := value implicitly turns the identifier x into a table with a single entry (i = value). See Example 2. |
The assignment f(X1, X2, ...) := value adds an entry to the remember table of the procedure f.
Note: If f is neither procedure nor a function environment, then f is implicitly turned into a (trivial) procedure with a single entry (X1, X2, ...) = value in its remember table. See Example 4. |
Identifiers on the left hand side of an assignment are not evaluated (use evalassign if this is not desired). I.e., in x := value, the previous value of x, if any, is deleted and replaced by the new value. Note, however, that the index of an indexed identifier is evaluated. I.e., in x[i] := value, the index i is replaced by its current value before the corresponding entry of x is assigned the value. See Example 5.
The assignment operator := can be applied to a single identifier as well as to a list of identifiers:
x := 42: [x1, x2, x3] := [43, 44, 45]: x, x1, x2, x3
In case of lists, all variables of the left-hand side are assigned their values simultaneously:
[x1, x2] := [3, 4]: [x1, x2] := [x2, x1]: x1, x2
The functional equivalent of the assign operator := is the function _assign:
_assign(x, 13): _assign([x1, x2], [14, 15]): x, x1, x2
Assigned values are deleted via the keyword delete:
delete x, x1, x2: x, x1, x2
Assigning a value to an indexed identifier, a corresponding table (table, DOM_TABLE) is generated implicitly, if the identifier was not assigned a list, a table, an array, an hfarray, or a matrix before:
delete x: x[1] := 7: x
If x is a list, a table, an array, an hfarray, or a matrix, then an indexed assignment adds a further entry or changes an existing entry:
x[abc] := 8: x
x := [a, b, c, d]: x[3] := new: x
x := array(1..2, 1..2): x[2, 1] := value: x
delete x:
For efficient use of indexed assignments (see Example 2 for an overview), programmers should note the following rules:
MuPAD^{®} uses reference counting and thereby allows multiple references to identical data structures. Changing one of these logically distinct values means that the internal structure must be copied, which takes time:
n := 10^4: L := [0$n]: time((for i from 1 to n do L_old := L: L[i] := i: end_for))
Compare this with the situation where only one variable or identifier refers to the internal structure:
n := 10^4: L := [0$n]: time((for i from 1 to n do L[i] := i: end_for))
For lists, there is another situation that requires copying the list structure: Changing the length of the list. The most frequently encountered example is appending to a list with _concat (.) or append:
n := 10^4: L := []: time((for i from 1 to n do L := L . [i]: end_for))
A loop written as above takes running time roughly proportional to the square of the number of elements. It is advisable to rewrite such loops. In the case where you know the length of the final list in advance, you can construct such a list and replace its entries inside the loop:
n := 10^4: L := [NIL$n]: time((for i from 1 to n do L[i] := i: end_for))
If you don't know the final length, you can gain linear running time by first collecting the elements into a table:
n := 10^4: T := table() time((for i from 1 to n do T[nops(T)+1] := i; end_for; L := [T[i] $ i = 1..nops(T)]))
Consider a simple procedure:
f := x -> sin(x)/x: f(0)
Error: Division by zero. Evaluating: f
The following assignment adds an entry to the remember table:
f(0) := 1: f(0)
If f does not evaluate to a function, then a trivial procedure with a remember table is created implicitly:
delete f: f(x) := x^2: expose(f)
proc() name f; option remember; begin procname(args()) end_proc
Note that the remember table only provides a result for the input x:
f(x), f(1.0*x), f(y)
delete f:
The left hand side of an assignment is not evaluated. In the following, x := 3 assigns a new value to x, not to y:
x := y: x := 3: x, y
Consequently, the following is not a multiple assignment to the identifiers in the list, but a single assignment to the list L:
L := [x1, x2]: L := [21, 22]: L, x1, x2
However, indices are evaluated in indexed assignments:
i := 2: x[i] := value: x
for i from 1 to 3 do x[i] := i^2; end_for: x
delete x, L, i:
Since an assignment has a return value (the assigned value), the following command assigns values to several identifiers simultaneously:
a := b := c := 42: a, b, c
For syntactical reasons, the inner assignment has to be enclosed by additional brackets in the following command:
a := sin((b := 3)): a, b
delete a, b, c:
x, x1, x2, … |
Identifiers or indexed identifiers |
value, value1, value2, … |
Arbitrary MuPAD objects |
f |
A procedure or a function environment |
X1, X2, … |
Arbitrary MuPAD objects |