Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

In MATLAB I have the following series of nested for loops that update a matrix. (It's not my code, but someone else's that I'm trying to replicate - I don't know why i starts at 0, for example, and I don't think it needs to, since k can be specified by the user.)

[n,d] = size(var1);
for i = 0:k
    for j = 0:k
        var1(i+1,d-j) = var1(i+2,j+2);
    end
end

for i = 0:k
    for j = 0:k
        var1(n-i,j+1) = var1(i+2,j+2);
    end
end

for i = 0:k
    for j = 0:k
        var1(n-i,d-j) = var1(i+2,j+2);
    end
end

k is some variable that is less than both n and d. In terms of size, k is about 100 and n and d are about 1000.

I've had a look over the Q&A - Alternatives to procedural loops and iterating over lists in Mathematica - for avoiding/rewriting nested loops.

However, I'm not sure what to do to apply that guidance here. I think I'm being confused by the reference to (i+1,d-j). The non-Mathematica part of me wants to use nested For[]s and Part[]s, but that can't be the best/fastest/most efficient way, certainly with the sequence of them shown above.

Here's a basic example...

var1 = RandomInteger[{0, 5}, {1000, 1000}];
{n,d} = Dimensions[var1];
k = 100;
share|improve this question
1  
Never use For unless you know you need For. Do gives you the same in a more readable and safer (localized iteraror) manner. As a first step, I'd translate the code as is using Do and would only think about using alternatives later. –  Szabolcs Jul 26 at 20:20
1  
No need to abstain from Do/For if you're in the mood. If you're after a serious optimization, some more background/motivation may be useful. –  Yves Klett Jul 26 at 20:22
    
Ah yes Do is a first step. In terms of size, n and d are probably ~1000, and k ~100, so the matrix isn't huge. I'll update the question a bit. –  blochwave Jul 26 at 20:25

1 Answer 1

up vote 5 down vote accepted

First step: convert the code without modifications. This is the safest (we don't want to accidentally break the algorithm):

{n, d} = Dimensions[var1];

k = ...

Do[
 var1[[i + 1, d - j]] = var1[[i + 2, j + 2]],
 {i, 0, k}, {j, 0, k}
]

Next step: It looks weird to me that the iteration starts from 0, as both Mathematica and MATLAB index from 1. (Understanding the problems the code solves would help here...)

Do[
 var1[[i, d - j + 1]] = var1[[i + 1, j + 1]],
 {i, k + 1}, {j, k + 1}
]

Next step: figure out whether any element of var1 that has already been modified by the loop is being used for calculating another element. This will tell us whether we can use Table.

It looks like row $i$ of the modified var1 is computed based on row $i+1$ of the original var1 (so we don't even have to think about $j$ any more). An already modified value is never used in the computation of a new value. This means we can use Table or other things that operate on immutable data.

If we look carefully, this code takes the square matrix var1[[2 ;; k + 2, 2 ;; k + 2]], then flips it around horizontally and puts it back in a different position in var1. We can do it like this:

var1[[1 ;; k+1,   d ;; d-k ;; -1]] = var1[[2 ;; k+2,   2 ;; k+2]]

I think this could have been written in the same way in MATLAB too ... so at this point just choose whatever you find more readable.


Note: try to avoid For in favour of Do (and possibly While) unless it is clear that For is really the better solution.

For[i=1, i <= n, i++, doThis; doThat; makeResult]

is not very readable due to all those commas and semicolons and the possibility to mix them up. (When you see ; in C code and you're tired it's all too easy to accidentally write ; in Mathematica too, even if you know very well that Mathematica requires , there.) Also, it operates with a variable i that is global.

Do[doThis; doThat; makeResult, {i, n}]

is much more readable, can be trivially extended to multiple iterators, can easily be replaced by Table if that turns out to be better (while trying to make the code more Mathematica-like), and the iterator i is localized.

share|improve this answer
    
Yeah, I'm not sure why the iteration starts at 0 either, it doesn't need to. –  blochwave Jul 26 at 20:44
3  
@blochwave That's why I don't like to translate code I don't understand. For relatively simple code like this it's usually easier to understand the problem first, then re-implement it, than to blindly translate an algorithm when we don't know where it comes from. Maybe the starting index of 0 makes sense for the physics (?) problem the code is solving. –  Szabolcs Jul 26 at 20:45
    
I think it might indeed make sense as you say - I'm working through the code and the problem behind it myself at the moment, I was just getting stuck at the nested for loops and didn't know what to do next! –  blochwave Jul 26 at 20:47
2  
@Szabolcs I'm sure someone blindly translated it from C to MATLAB ;) ... and now to mma. –  rm -rf Jul 26 at 21:01
    
@rm-rf if they did, that's annoying (for the rest of the code) - I can do C ok, but not MATLAB! –  blochwave Jul 26 at 21:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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