Re: Set::setraw error
- To: mathgroup at smc.vnet.net
- Subject: [mg90358] Re: Set::setraw error
- From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
- Date: Mon, 7 Jul 2008 05:06:39 -0400 (EDT)
- Organization: The Open University, Milton Keynes, UK
- References: <g4q9kl$e6o$1@smc.vnet.net>
Steven Siew wrote:
> I have encountered this Set:setraw error for the code below.
>
> I'm stumped. Does anyone have any idea what went wrong?
>
> xgcd[a_,b_]:=Module[{xsign=1,ysign=1,x=1,y=0,r=0,s=1,c,q},
> If[a == 0 && b == 0,Return[{0,0,1}]];
> If[a == 0,Return[{Abs[b],0,b/Abs[b]}] ];
> If[b == 0,Return[{Abs[a],a/Abs[a],0}]];
> If[a<0,a=-a; xsign=-1];
> If[b<0,b=-b; ysign=-1];
> While[b\[NotEqual]0,
> {c,q}={Mod[a,b],Quotient[a,b]};
> {a,b,r,s,x,y}={b,c,x-q*r,y-q*s,r,s}
> ];
> Return[{a,x*xsign,y*ysign}]
> ]
>
> xgcd[2, 3]
>
> \!\(\*
> RowBox[{\(Set::"setraw"\), \(\(:\)\(\ \)\), "\<\"Cannot assign to
> raw \
> object \\!\\(2\\). \\!\\(\\*ButtonBox[\\\"More\[Ellipsis]\\\", \
> ButtonStyle->\\\"RefGuideLinkText\\\", ButtonFrame->None, \
> ButtonData:>\\\"Set::setraw\\\"]\\)\"\>"}]\)
Hi Steven,
Contrary to many programming languages, say of the Algol family
(C/C++,Java.c#, etc.), the names that appears on the LHS of the
definition of a function in Mathematica are *not* the declaration of
some local variables but are names given to some *patterns* [1, 2, 3];
patterns that are going to be replaced by their values *before*
evaluating the RHS of the function.
One can think of Mathematica as a rewriting engine that takes some
transformation rules as input and rewrite the code of a function
according to them, before evaluating/executing the desired function.
(That is why Mathematica excels as doing *symbolic* manipulation and
mathematics.)
So, when you ask Mathematica to evaluate xgcd[2, 3], Mathematica checks
whether the expression xgcd[2, 3] matches some rule in its global
database of transformation rules, and find that, indeed, the given
expression matches xgcd[_, _].
Since the first and second patterns are named 'a' and 'b', respectively,
Mathematica takes the RHS (or body) of the corresponding expression and
rewrite it as follows:
Module[{xsign = 1, ysign = 1, x = 1, y = 0, r = 0, s = 1, c, q},
If[2 == 0 && 3 == 0, Return[{0, 0, 1}]];
If[2 == 0, Return[{Abs[3], 0, 3/Abs[3]}]];
If[3 == 0, Return[{Abs[2], 2/Abs[2], 0}]];
If[2 < 0, 2 = -2; xsign = -1];
If[3 < 0, 3 = -3; ysign = -1];
While[3 != 0,
{c, q} = {Mod[2, 3], Quotient[2, 3]};
{2, 3, r, s, x, y} = {3, c, x - q*r, y - q*s, r, s}];
Return[{2, x*xsign, y*ysign}]]
Having done that, Mathematica executes the freshly rewritten code, and
of course, assignment such as 2 = -2, that is the attempt to change the
value of a number, is illegal. That is the meaning of the error messages
you get.
To avoid this issue, just change the name of the patterns on the LHS and
assign them to some local variables declared within the Module[]
construct. The following code works as expected.
In[1]:= xgcd[aval_, bval_] :=
Module[{a = aval, b = bval, xsign = 1, ysign = 1, x = 1, y = 0,
r = 0, s = 1, c, q}, If[a == 0 && b == 0, Return[{0, 0, 1}]];
If[a == 0, Return[{Abs[b], 0, b/Abs[b]}]];
If[b == 0, Return[{Abs[a], a/Abs[a], 0}]];
If[a < 0, a = -a; xsign = -1];
If[b < 0, b = -b; ysign = -1];
While[b != 0, {c, q} = {Mod[a, b], Quotient[a, b]};
{a, b, r, s, x, y} = {b, c, x - q*r, y - q*s, r, s}];
Return[{a, x*xsign, y*ysign}]]
xgcd[0, 0]
xgcd[0, -2]
xgcd[-2, 0]
xgcd[-2, 3]
xgcd[2, -3]
xgcd[2, 3]
Out[2]= {0, 0, 1}
Out[3]= {2, 0, -1}
Out[4]= {2, -1, 0}
Out[5]= {1, 1, 1}
Out[6]= {1, -1, -1}
Out[7]= {1, -1, 1}
Regards,
- Jean-Marc
[1] guide/Patterns
[2] "Introduction to Patterns", tutorial/Introduction-Patterns,
http://reference.wolfram.com/mathematica/tutorial/Introduction-Patterns.html
[3] "Patterns", tutorial/PatternsOverview,
http://reference.wolfram.com/mathematica/tutorial/PatternsOverview.html