After many years, I have still kept caught up on Maple’s assignment and unassignment rules.
What follows makes perfectly good sense to me.
> a := 7; a := 7 > x := a; x := 7 > x := x; x := 7 > a :=5; a := 5 > x; 7
What follows does not!
A := matrix(2,2,[0,0,0,0]); [0 0] A := [ ] [0 0] > X := A; X := A > X := X; X := A > A := matrix(2,2,[1,1,1,1]); [1 1] A := [ ] [1 1] > evalm(X); [1 1] [ ] [1 1]
It’s "last name evaluation". See "Last name evaluation" in my Maple Advisor Database, http://www.math.ubc.ca/~israel/advisor:
"Normally, when you enter an expression it is evaluated completely. If your expression contains a variable that has a value, the variable is replaced by that value; if it contains a function call such as f(x), where f is a procedure or function, then this is replaced by the value returned by f with argument x. And if those values in turn contain variables or function calls, they are also evaluated.
Eventually (we hope) Maple obtains a form that does not require any further evaluation, and this is what it returns to us. However, certain types of object have special evaluation rules. In particular, tables, arrays (including vectors and matrices, but not Vectors or Matrices) and procedures use last name evaluation. This means that if the result of one level of evaluation of a name would be a table, array or procedure, then the chain of evaluation stops with that name."
This occurs when you say "X:= A;":
the right side is only evaluated as far as the name A,
because another level of evaluation would yield an array. So X is assigned the name
A, rather than the actual matrix. The result is that when you change A, X is
affected.
If by getting around this problem you mean that you want to assign X the matrix rather than the name, you could say
> X:= eval(A);
This evaluates A fully (to a matrix) before assigning the value to X. Note that X and A
now point to the same structure. If you reassign A by "A:= ...",
X will not be
affected. However, any changes to the matrix will affect both A and X, e.g. if you
say "A[1,2]:= 3;"
it will make X[1,2]
be 3 also. On the other hand, you could
say
> X:= copy(A);
which will assign X a new matrix that has the same entries as A, but changes in one will not affect the other.
Use copyinto:
> with(linalg): > A := matrix(2,2,[0,0,0,0]); > X:=matrix(2,2); > copyinto(A,X,1,1); > A:=matrix(2,2,[1,1,1,1]); > evalm(X); [0 0] [ ] [0 0] > evalm(A); [1 1] [ ] [1 1]
By using rtable-based matrices instead of table-based matrices, i.e. use Matrix instead of matrix (and then don’t use evalm). This only applies to Maple 6 and later.
Alternatively, use eval (or evalm) to force full evaluation, e.g.
X := eval(X);
would give what I assume you wanted.
The reason is to do with Maple’s evaluation rules rather than how it handles assignment. A variable whose value is a table-based data structure or a procedure evaluates by default to itself rather than its value, as you see above. This does not apply to rtable-based values, which behave more like algebraic values.
This way, only a pointer is copied (sometimes called a "shallow copy"). For copying the actual data structure (a "deep copy"), use
X:=evalm(X); or (more general, works for arrays, tables and rtables): \begin{MAPLEinline} X:=copy(X);