Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

liptonlover

macrumors 6502a
Original poster
Mar 13, 2008
989
0
Hi everyone,

I'm having a hard time figuring out something and I'm hoping someone here can help.

When I picture an array, I see a group of cells. If it's a 1D array then it's simply a row. If it's a 2D array then it's a plane of cells. If it's a 3D array then it's a cube.

My problem starts at 4D arrays and moving onward from there. I just can't seem to comprehend how they work, and how one would look. Being able to picture this stuff is a big thing for me, because I can think about it better that way.

The only thing I understand for sure beyond 3D is that it still follows the basic rule of adding another dimension: You still multiply the size of each dimension to get the total number of cells in the array. So as I understand it, the following array

int myarray[1][2][3][4]

has 24 cells. I just don't know where the last 18 are or why I would ever need more than 3 dimensions.

Can anyone help?
Thanks, Nate
 
You can't picture 4 spatial dimensions. The only reason you can picture three or less is because you've had a lifetime to grok 3-D relationships. Don't try to picture groups of cells. The power of math is that it lets us abstract to levels of complexity which we cannot directly understand all at once.
 
A 4D array might be useful (for instance) if you wanted to record 3D motion. So you could store x, y and z coordinates, and a time value. Perhaps you want to measure the temperature at that point & time too, that would require a 5D array. etc..etc..

However, arrays could have any number of 'dimensions'; which is why you should probably stop thinking of arrays in terms of spatial dimensions as it'll only confuse you. :)

All arrays are just stored in flat, sequential memory. While a 3 dimensional array is useful for representing & storing real-world 3 dimensional data, it's just data stored in flat memory. Trying to envisage a 6D cube will only turn your head inside-up!
 
So there's absolutely no way to picture a 4D+ array?

Ok, that example makes sense I think.
 
As has been said previously. Thinking outside of 3 dimensional space is sure to make your head hurt (unless you are one of a few quantum physicists who love lots of dimensions). Anyway...

Best way is to imagine the fourth dimension as time. As you move through time the 3-D matrix changes in value. So at each step in the fourth dimension you essentially have a new 3-D matrix. So if they described a 3-D shape, the shape would change with time.

I know that’s a bit confusing but it works in my head!

Aly
 
Dimensions of an array are not like spatial dimensions. Just don't worry about it. Any array that's, say x[a][c][d][e][f] is laid out the same way as x[a*b*c*d*e*f]... it's just a big block of memory that you have a convenient way to navigate within using multiple subscripts... but really:
x[5][4][2] is just:
x[5*b*c + 4*c + 2]

Trying to reason out what an array "looks like" in space isn't going to get you anywhere... what it looks like in memory is one giant chunk.

-Lee
 
Ok thanks for all your help. Not sure I can grasp it still though; I'm not sure what I'm missing.

Nate
 
This may make things worse, but you may want to look in to how array offsets function, and it may help.

For example,
int x[20][10];

is just going to set aside sizeof(int)*20*10 bytes of memory, and the memory address to the first byte of that memory is what's going to be stored in x. When you use offsets on x, some math is done to calculate what actual piece of memory will be used. So:
x[5][4] will take the base address, we'll say it's:
0x1
Then it's going to work out the offsets. Every "step" of the first offset is going to jump 10*sizeof(int) bytes, and each step of the second offset will move sizeof(int) bytes. We'll assume on your platform, sizeof(int) is 4 bytes. So the address will be:
Code:
0x1   + 5   *            10                *  4            +  4      *    4
base    step   size of 2nd dimension  sizeof(int)     step       sizeof(int)

Which would give you:
217
or
0xD9

This simply extends to additional dimensions. There's just one giant block of memory, and the offsets are just shortcuts to certain points in the block. You could do all of that math yourself, but the array offsets are just an easy way for you to save the work.

-Lee
 
You could look at a 4D array as a row of cubes, and a 5D one as a plane of cubes. It's really not useful to do so, though.
 
Lee I'll have to read your more indepth when I get a chance but Cinder that's very helpful! Thanks :)
 
Again, I don't know if more details will make this better or worse, but here's some code (there's an assumption that a pointer is the same size as a long int... this might not be a good assumption on your platform, but it's just an example):

Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  int x[10][10][10][10];
  int *z = NULL;
  int posA=0,posB=0,posC=0,posD=0;
  z = (int *)&x;
  for(posA = 0; posA < 10; posA++)
    for(posB = 0; posB < 10; posB++)
      for(posC = 0; posC < 10; posC++)
        for(posD = 0; posD < 10; posD++)
          x[posA][posB][posC][posD] = posA*1000 + posB*100 + posC*10 + posD;

  printf("x[4][3][2][1] = %d, at address %p, offset %ld bytes (%ld ints) from base %p\n",
      x[4][3][2][1],
      &x[4][3][2][1],
      (long int)&x[4][3][2][1] - (long int)&x,
      ((long int)&x[4][3][2][1] - (long int)&x) / sizeof(int),
      &x);

  printf("z[4321] = %d, at address %p, offset %ld bytes (%ld ints) from base %p\n",
      z[4321],
      &z[4321],
      (long int)&z[4321] - (long int)z,
      ((long int)&z[4321] - (long int)z) / sizeof(int),
      z);

  return 0;
}

On my machine i get:
x[4][3][2][1] = 4321, at address 0xbfffa380, offset 17284 bytes (4321 ints) from base 0xbfff5ffc
z[4321] = 4321, at address 0xbfffa380, offset 17284 bytes (4321 ints) from base 0xbfff5ffc

The idea here is that, while there is a 4-dimensional array, it's really just a shortcut for calculating the offsets into a 1-dimensional array. To demonstrate I cast the 4D array to a 1D array, and showed how to get at the same element in each. In this case, when accessing x[4][3][2][1], 4 is multiplied by 1000 (as x[4] is an int[10][10][10], so 1000 total elements), 3 is multiplied by 100, 2 is multiplied by 10, and 1 is multiplied by 1.

Basically, you don't ever NEED to define a multidimensional array. You could just use a single dimension, and calculate your own offsets to emulate the behavior of a multidimensional array. The compiler is going to end up doing the calculations under the covers, anyway. It's just a matter of whether you'd rather do it yourself or let the compiler handle it.

-Lee
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.