Re: acting on a matrix
- To: mathgroup at yoda.physics.unc.edu
- Subject: Re: acting on a matrix
- From: TODD GAYLEY <TGAYLEY at ccit.arizona.edu>
- Date: 17 Sep 1992 00:00:01 -0700 (MST)
Riccardo Rigon (rigon at itnux2.cineca.it) asks: > I would like to define functions acting on a list ( really a matrix ) > defined outside them. I found it is possible to do something like this: > > ( it modify the list "list" in some suitable specified location > assigning to it the value {1,1} ) > > list=Table[{i,j},{i,10},{j,10}]; > > MyFunction[position_list]:=Module[{vaule={1,1}}, > list[[position[[1]],position[[2]] ]=vaule; > ] > > The example works but I would like to specify in the arguments of > the function the name of the matrix. > > Something like: > MyFunction[position_list,nameofthelist_]:=Module[{value={1,1}}, > nameofthelist[[position[[1]],position[[2]] ]]=value > ] > This last code indeed does not works. What is wrong and/or lacking? > > The final scope is to have some matrix (rappresenting a physical system) > on which different operations can act changing its internal values > but without reallocating each time the whole matrix or part of it except > for the values changed. (First, I want to note that there must be a capital L in position_list. I assume this is just a typo, since both functions behave really screwy without it.) The problem here is that by default, functions evaluate all of their arguments before passing them into the body of the function. Look at what happens with your second version: MyFunction[position_list,nameofthelist_]:=Module[{value={1,1}}, nameofthelist[[position[[1]],position[[2]] ]]=value ], when you evaluate thelist = {{a,b},{c,d}}; MyFunction[{2,2}, thelist] You want MyFunction to execute thelist[[2,2]] = {1,1} but what happens is that thelist is evaluated to {{a,b},{c,d}} and then passed into the function. Therefore, it tries to execute {{a,b},{c,d}}[[2,2]] = {1,1} You get the error message "Part::setps: {{a, b}, {c, d}} in assignment of part is not a symbol.", because Mma can't assign back into a list this way. (And even if it could, the value of the variable thelist would not be affected). You need to give MyFunction the Attribute HoldRest (or HoldAll) to prevent it from evaluating thelist: SetAttributes[MyFunction, HoldRest] Now it will work as expected. Another way to get the desired behavior is to leave MyFunction as it is, but call it with Unevaluated wrapped around the list variable: MyFunction[{2,2}, Unevaluated[thelist] ] This also overrides the default evaluation. Mma has a built-in function, ReplacePart, that makes it easy to modify pieces of lists. I don't know if this method would be any less efficient, but it has the advantage that it will work without modification for any dimension of list: SetAttributes[MyFunction2, HoldRest]; MyFunction2[position_List,nameofthelist_]:=Module[{value={1,1}}, nameofthelist = ReplacePart[nameofthelist, value, position]; ] ----------------------------------------------------------------- Todd Gayley Department of Ecology and Evolutionary Biology University of Arizona tgayley at ccit.arizona.edu -or- tgayley at cs.arizona.edu