I have a matrix whose dimensions are 26x26x3. For my assignment I have written a program which is using a Do loop (maxx=maxy=10,maxz=2):

  n = 0;
  k = Table[
         If[a <= #1 <= a + h && b <= #2 <= b + h && c <= #3 <= c + h & @@ pts[[w, t]], 1, 0], 
         {w, 1, Length[pts]}, 
         {t, 1, Length[pts[[w]]]}
  pls = Plus @@@ k;
  For[i = 1, i <= Length[pls], i++, If[pls[[i]] > 0, n++]];
  {a, 1, maxx, h}, {b, 1, maxy, h}, {c, 1, maxz, h}

At every iteration I get a new value for n and I have to assign it to the correct position of my matrix as efficiently and fast as possible. I don't have a counter. So, I am a bit confused. How can I solve this issue?

On the other hand, can I create a matrix by saving n at the end of the Do loop?

Any help is appreciated.

  • $\begingroup$ What would the correct position be? $\endgroup$ – ssch Jan 6 '13 at 16:06
  • $\begingroup$ @ssch Correct position : For example, first n will be positioned in the matrix at {1,1,1}; second n at {1,1,2} third n at {1,1,3} then y axes will change and fourth n will be positioned at {1,2,1} and so on.. $\endgroup$ – cesm Jan 6 '13 at 16:19
  • $\begingroup$ Well with those values of h and maxx,maxy,maxz you'll just get 1587 values of n, so at best your result will be a 23*23*3 matrix. I'm not sure I understand what you are doing. Are you for each interval $[a,a+h] \times [b,b+h] \times [c,c+h]$ counting how many rows have at least one element inside? What dimensions do you expect for the resulting matrix? $\endgroup$ – ssch Jan 6 '13 at 16:42
  • $\begingroup$ Could you make a small example matrix and the result you expect from that? $\endgroup$ – ssch Jan 6 '13 at 16:43
  • $\begingroup$ @ssch Yes, you are right. The dimensions will be 23x23x3. Thanks. Is it possible to write a program that the values of n when c change will be assigned to values of z dimensions on that matrix? And the same for y and x axes. $\endgroup$ – cesm Jan 6 '13 at 19:20

I think this does what you require:

Total[Unitize[BinCounts[#, {1, maxx + h, h}, {1, maxy + h, h}, {1, maxz + h, h}]] & /@ pts]
  • $\begingroup$ Ah BinCounts, I knew there was some command I was forgetting :) $\endgroup$ – ssch Jan 6 '13 at 18:27
  • $\begingroup$ Ohh, thanks! This does what I want at one line :) $\endgroup$ – cesm Jan 6 '13 at 20:05

I'm still not quite sure what output you expect, but at least this might be a way forward:

maxx = 10;
maxy = 10;
maxz = 2;
h = 0.4;
pts = RandomReal[{1, 10}, {26, 26, 3}];

You can start by replacing Do with Table to store your calculated n values

AbsoluteTiming[out=Table[(* Same stuff as in your Do *)];]
(* 8.5 seconds *)
(* {23,23,3} *)

You can replace the whole thing with:

AbsoluteTiming[out = Table[
    , {a, 1, maxx, h}, {b, 1, maxy, h}, {c, 1, maxz, h}];]
(* 5.2 s *)

That counts (Count[...,True]) how many rows have at least one (MemberQ) good element.

Some speed increase can be gained by compiling the pattern test for MemberQ

inInterval = Compile[{a, b, c, h, {pt, _Real, 1}},
  a <= pt[[1]] <= a + h && b <= pt[[2]] <= b + h && c <= pt[[3]] <= c + h
AbsoluteTiming[out2 = Table[
  Count[MemberQ[#, _?(inInterval[a, b, c, h, #] &)] & /@ pts, True]
   ,{a, 1, maxx, h}, {b, 1, maxy, h}, {c, 1, maxz, h}];]
(* 3.5 s *)

check Count and MemberQ

3.5s still seems quite slow for this problem I expect someone to come up with a quicker solution :)


Here a illustrative example of assigning values, retaining your Do loop structure. It just has an incrementing count at the place where you could add your own calculation:-

maxx = 4; maxy = 3; maxz = 2;
k = Table[{a, b, c}, {a, 1, maxx}, {b, 1, maxy}, {c, 1, maxz}];
count = 1;
Do[k[[a, b, c]] = count++, {a, 1, maxx}, {b, 1, maxy}, {c, 1, maxz}]

enter image description here

  • $\begingroup$ But then you're disregarding the stepsize h, you could also just replace the Do with Table in the original code and get a matrix $\endgroup$ – ssch Jan 6 '13 at 16:45
  • $\begingroup$ I assumed the OP specifically wanted to use Do. However, Do doesn't seem to support step size for multiple dimensions. Also, I couldn't see how a step size of 0.4 would work for stepping through a matrix. $\endgroup$ – Chris Degnen Jan 6 '13 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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