[Solved] Change two different parts in a table according to the same random value


This answer has the “I did it at work without Mathematica to check my syntax” advisory on it

@belisarius’ answer works perfectly well, is more elegant, and is almost certainly more efficient than mine. But you might find an alternative that is easier for you to understand using the ArrayFlatten command (documentation) or the Join command (documentation).

The first option assumes you want something like what the CODE in your question asks for, rather than what is stated in the text. You would then use something like:

nonisFunction[mylist_List,firstrowsub_?VectorQ, 
secondrowsub_?VectorQ,cutoff_Real]/; Length[Dimensions[mylist]]==4  :=
Table[
If[RandomReal[]>cutoff, 
    Join[{firstrowsub},{secondrowsub},Drop[mylist[[i,j]],2] ],
    mylist[[i,j]] ], 
    {i,Dimensions[mylist][[1]]}, {j,Dimensions[mylist][[2]]} ]

This effectively takes each submatrix and stitches it back together again, substiting each time the two rows to be substituted if the cutoff if exceeded, but leaving the submatrix alone if it is not.

If what you want is to increment and decrement the two rows (ie your text question rather than the code you provided), then a similar solution would simply need addition, not Join. Because Plus is Listable, it should thread the vector to be added over the rows of each submatrix.

nonisFunction[mylist_List,cutoff_Real]/; Length[Dimensions[mylist]]==4  :=
Table[
mylist[[i,j]] +
 If[RandomReal[]>cutoff, {1,-1,0,0}, {0,0,0,0} ],
    {i,Dimensions[mylist][[1]]}, {j,Dimensions[mylist][[2]]} ]

This table-based programming style is much more like the procedural programming style you are used to (quadruply nested For loops), but it is still more efficient, and I have come to the conclusion that you are more likely to understand the code.

EDIT: additional material in response to noni’s question in comments
To run this code (taking the second example function above as the example for this process), you would first define the function by copying and pasting the above code into a Mathematica notebook. You would then define your input matrix and give it some name. e.g.

myinputmatrix = RandomInteger[{10,100},{4,4,4,4}];

And finally, call the nonisFunction with the appropriate arguments.

nonisFunction[myinputmatrix,0.4]

And if that doesn’t help, I recommend the video tutorials http://www.wolfram.com/support/learn/get-started-with-mathematica/.

9

solved Change two different parts in a table according to the same random value