Re: what is wrong here?
- To: mathgroup@smc.vnet.net
- Subject: [mg12227] Re: [mg12103] what is wrong here?
- From: David Withoff <withoff@wolfram.com>
- Date: Fri, 1 May 1998 03:09:14 -0400
> I am having a lot of difficulty in trying to use commands on a matrix as
> follows:
>
> matrix[[{i,j,k},{i,j,k}]] = matrix[[{i,j,k},{i,j,k}]] + some 3x3 matrix.
>
> See the example below. When i,j,k areconsecutive indices, there seems
> to be no problem. When the indices are, say {3,4,7,8}, the program
> always crashes with a bus error.
>
> In[3]:= temp=Table[b, {i,4},{j,4}]
>
> Out[3]= {{b, b, b, b}, {b, b, b, b}, {b, b, b, b}, {b, b, b, b}}
>
> In[6]:= matrix = Table[a , {i,8},{j,8}]
>
> Out[6]= {{a, a, a, a, a, a, a, a}, {a, a, a, a, a, a, a, a},
>
> > {a, a, a, a, a, a, a, a}, {a, a, a, a, a, a, a, a},
>
> > {a, a, a, a, a, a, a, a}, {a, a, a, a, a, a, a, a},
>
> > {a, a, a, a, a, a, a, a}, {a, a, a, a, a, a, a, a}}
>
> In[7]:= matrix[[{3,4,7,8},{3,4,7,8}]]= \ matrix[[{3,4,7,8},{3,4,7,8}]] +
> temp Bus error
This is caused by an error in listable Part assignments, which affects
some releases of Mathematica Version 3.0. This error has been
corrected for the next version.
Listable part assignment is a new feature in Version 3.0. In all
previous versions, this input would have generated a warning message
and would have been rejected. In Version 2.2, for example, or if you
are using a copy of Version 3.0 where the case that you want to use
doesn't work, it is necessary to separate this assignment into
individual assignments. This can be done in a variety of ways, such as
In[1]:= matrix = Table[a , {8},{8}] ;
In[2]:= temp=Table[b, {i,4},{j,4}] ;
In[3]:= Module[{p = {3,4,7,8}, q = {3,4,7,8}},
Do[matrix[[p[[i]], q[[j]]]] += temp[[i,j]], {i, 4}, {j, 4}]]
In[4]:= MatrixForm[matrix]
Out[4]//MatrixForm=
> a a a a a a a a
a a a a a a a a
a a a + b a + b a a a + b a + b
a a a + b a + b a a a + b a + b
a a a a a a a a
a a a a a a a a
a a a + b a + b a a a + b a + b
a a a + b a + b a a a + b a + b
or
In[5]:= matrix = Table[a , {8},{8}] ;
In[6]:= MapThread[(matrix[[#1[[1]], #1[[2]]]] += #2) &,
{Outer[List, {3,4,7,8}, {3,4,7,8}], temp}, 2]
Out[6]= {{a + b, a + b, a + b, a + b}, {a + b, a + b, a + b, a + b},
> {a + b, a + b, a + b, a + b}, {a + b, a + b, a + b, a + b}}
which has the same effect on the value of matrix.
If you want this to be done automatically you can add a rule for part
assignment:
In[7]:= Unprotect[Part] ;
In[8]:= Part /: (Part[p_, q__List] = rhs_) :=
With[{qs = Outer[Hold, q]},
Print["using Part assignment rule"];
SetPart[p, qs, rhs] /; Dimensions[qs] ==
Dimensions[rhs]]
In[9]:= SetAttributes[SetPart, {Listable, HoldFirst}]
In[10]:= SetPart[p_, Hold[q__Integer], r_] := (Part[p, q] = r)
In[11]:= matrix = Table[a , {8},{8}] ;
In[12]:= matrix[[{3,4,7,8},{3,4,7,8}]] =
matrix[[{3,4,7,8},{3,4,7,8}]] + temp using Part assignment
rule
Out[12]= {{a + b, a + b, a + b, a + b}, {a + b, a + b, a + b, a + b},
> {a + b, a + b, a + b, a + b}, {a + b, a + b, a + b, a + b}}
Dave Withoff
Wolfram Research