I love Mathematica, but I find it oddly lacking when it comes to how matrices are handled. Here is an example of code that works but seems like it should be a lot shorter (and minus the loop).

I'm a super-newbie though so maybe one of you smart people has an idea for making this nicer. The point is to take all elements of the matrix that evaluate as True for some criterion (here, being less than 7) and re-assign them to a new value.

testmat = {{-1, 1, -3}, {10, 11, 5}, {15, -2, 7}};
badpos = Position[testmat, _?(# < 7 &)];
{nend, trash} = Dimensions[badpos];
For[i = 1, i <= nend, i++,
  selpos = badpos[[i]];
  p1 = selpos[[1]];
  p2 = selpos[[2]];
  testmat[[p1, p2]] = 0;
  • $\begingroup$ Are you familiar with ReplacePart? Using it would eliminate all your code starting at line 4. (I found a reference to it in the help system by searching for "Part", knowing this is the basic function involved in accessing matrix elements.) $\endgroup$ – whuber Mar 18 '13 at 17:15
  • 3
    $\begingroup$ Is this what you want? newmat = testmat /. x_ /; x < 7 -> 0 $\endgroup$ – Dr. belisarius Mar 18 '13 at 17:16
  • $\begingroup$ Hello and welcome to Mathematica Stack Exchange! Your question was asked before and has several excellent answers with detailed methods to perform select and replace operations, including Szabolcs' answer below. I recommend you look through that in detail for solutions :) $\endgroup$ – rm -rf Mar 18 '13 at 17:39

You can Replace at level 2:

Replace[testmat, x_ /; x < 7 -> 0, {2}]

An alternative, MATLAB-style vectorized solution is

UnitStep[testmat - 7] testmat

This second approach is beneficial for performance in certain cases (but not always). In this case it is going to be considerably faster for very large matrices.

It can be simplified to

BoolEval[testmat >= 7] testmat

using this package.

| improve this answer | |
  • $\begingroup$ Thanks everyone. I'm very impressed with the terseness possible if you know the commands! I apologize for the duplicate, I DID search but a lot of times when you are very ignorant it's hard just to hit the right terms, I guess. $\endgroup$ – ETM Mar 18 '13 at 18:47
  • $\begingroup$ @ETM Don't worry, sometimes I remember that there is a duplicate but I still cannot find it easily ... this time I didn't even remember even though I posted a answer in the duplicate question as well. $\endgroup$ – Szabolcs Mar 18 '13 at 18:51
  • $\begingroup$ @Szabolcs In any case, it's better to post an answer twice than a question ... twice $\endgroup$ – Dr. belisarius Mar 18 '13 at 19:41

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