3
$\begingroup$

I'd simply like to replace the value x at index [[j,i]] in a two dimensional table with the value -x. There doesn't seem to be an intuitive way to do this. So far I've tried:

Flip[table_, i_, j_] := (table[[j, i]] = -table[[j, i]]; Return[table])

However I get the error:

Set::setps: <my table> in the part assignment is not a symbol.

Any suggestions?

$\endgroup$
2
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory Tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Commented Jun 6, 2015 at 2:11
  • $\begingroup$ Thanks for the responses. I managed to figure out my own solution: flip[table_,j_,i_]:=MapAt[(-1*#)&,table,{{j,i}}]. However I think ReplacePart fits my situation better seeing as the "flip" only needs to be done at one location in the table rather than at many. Thanks @Nasser. $\endgroup$ Commented Jun 16, 2015 at 17:29

6 Answers 6

5
$\begingroup$

You can use ReplacePart

 data = RandomReal[{}, {2, 2}]

Mathematica graphics

data = ReplacePart[data, {1, 2} -> -data[[1, 2]]]

Mathematica graphics

You need to reassign the result back to data

You can make the above into a function if needed.

 flip[data_, i_, j_] := ReplacePart[data, {i, j} -> -data[[i, j]]];
 data = flip[data, 1, 2]

In your function, you also did something wrong. You can't assign to an input. So your statement table[[j, i]] = -table[[j, i]] is writing to the input argument table. If you really wanted to do as you show, then:

flip[table_, i_, j_] := 
 Module[{myTable = table}, myTable[[i, j]] = -myTable[[i, j]]; 
  myTable]

Now the local variable myTable is used to modify, then it is returned back at the end. No need to use Return since by default, the last expression is the result of the function. (do not use ; at the end, else Null is returned instead)

$\endgroup$
5
$\begingroup$

Others have shown you ways to do what you want in ways which are more common to Mathematica. But I think what you really ask for (though it might not necessarily the best solution for your problem) is "pass by reference" which as such does not exist in Mathematica. But there is the possibility to use Attributes for functions and using e.g. HoldFirst will make your example work as intended:

SetAttributes[flip, HoldFirst]
flip[table_, i_, j_] := (table[[j, i]] = -table[[j, i]]; table)

note that I did change the function name to start with lower case which is good practice to avoid name conflicts with Mathematica owns symbol, including future versions. It is also hardly ever necessary to use a Return as the last expression of a CompoundExpression will be returned anyway.

The Hold*-attribute trick will also be the solution whenever you want to make changes to an existing symbol within a function, but as such must be used with care as it will make your functions have side effects which in general make your programs much harder to understand.

$\endgroup$
4
$\begingroup$

Wouldn't it be easier to use Part?

a = {{2, 3}, {4, 5}};
a[[1, 2]] = -a[[1, 2]];
a

{{2, -3}, {4, 5}}
$\endgroup$
3
$\begingroup$
a = {{2, 3}, {4, 5}};

Using MapAt and Minus

MapAt[Minus, {1, 2}] @ a

{{2, -3}, {4, 5}}

$\endgroup$
2
$\begingroup$

For in-place modification:

a = {{2, 3}, {4, 5}};

ApplyTo[a[[2, 1]], -# &]; a

(* {{2, 3}, {-4, 5}} *)

Or,

a = {{2, 3}, {4, 5}};


a[[2, 1]] //= -# &; a


(* {{2, 3}, {-4, 5}} *)
$\endgroup$
2
$\begingroup$
a = {{2, 3}, {4, 5}};

Another way using SubsetMap and Minus:

SubsetMap[Minus, a, {{1, 2}}]

{{2, -3}, {4, 5}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.