Thread: Accessing column data in multi-dimentional arrays

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    2

    Accessing column data in multi-dimentional arrays

    Hi Everyone,

    I am new to the forum and was hoping someone could help me with what I hope i a relatively simple problem. I couldn't find my problem described in an existing topic, but I may have overlooked it. If so, I apologize.

    Anyway - my problem is the following.

    I am currently working on a simple program and am using multi-dimentional arrays since I have a lot of data to process for different variables.
    An example of one of my arrays is the following:
    Code:
    double Solution[3][20][20]
    When I use this declaration, it is relatively easy for me to access the underlying 20x20 arrays, if I pass the array to a function as
    Code:
    Solution[0]
    However, now for a different part of my code, I would like to get all the entries(as a vector) in the first column for a specific orientation in the underlying 20 x 20 array.

    An example:
    Code:
    Solution[*all three values*][10][10] = {entry 1, entry 2, entry 3}
    But I have been unsuccessful to do so. Is there a simple way of doing this?

    Thanks to anyone who can find the time to reply.

  2. #2
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    So you want to enter values to all three at once? Is this correct?
    Fact - Beethoven wrote his first symphony in C

  3. #3
    Registered User
    Join Date
    Nov 2012
    Posts
    2
    Quote Originally Posted by Click_here View Post
    So you want to enter values to all three at once? Is this correct?
    Not, that is not what I want to do.

    I want to access all the three values in the first dimension as a vector, for a given specific position for the remaining two dimensions.

    Here is how I am working around the problem at the moment:
    Code:
    double Uij[3] = {DeltaU[0][i][j],   DeltaU[1][i][j],   DeltaU[2][i][j]};
    Thus, I am defining a vector manually, and the resulting vector has the following entries:

    Code:
     Uij = {DeltaU[0][i][j], DeltaU[1][i][j], DeltaU[2][i][j]}
    What I was hoping was, that I could somehow select the three entries in (using point 10,10 as example):
    Code:
    DeltaU[k][10][10]
    (Where k is the index for my for-loop, running from 0-2)
    And have the output as a vector with the following values:
    Code:
     Uij = {DeltaU[k=0][10][10], DeltaU[k=1][10][10], DeltaU[k=2][10][10] }
    Does it make sense ?
    Last edited by Darkmentor; 11-30-2012 at 01:56 AM.

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    As I understand it you want this:
    Code:
    double Uij[3];  
    for (i = 0; i < 3; i++)
        Uij[i] = DeltaU[i][10][10];
    Correct?

    You need a for-loop if you don't want to use the "initializer" version.

    Or, do you want to achieve that the values in "Uij" are references to the corresponding values of "DeltaU" (i.e. if the values change in "DeltaU" the values in "Uij" change too and vice versa)? Then you need pointers:
    Code:
    double *Uij[] = { &DeltaU[0][10][10], &DeltaU[1][10][10], &DeltaU[2][10][10] };
    (or the corresponding for-loop version) and you can access the values in "Uij" by dereferencing:
    Code:
    double x = *Uij[0];  // "x" has now the value of DeltaU[0][10][10]
    Bye, Andreas

  5. #5
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by Darkmentor View Post
    the first column for a specific orientation in the underlying 20 x 20 array.
    Simple: Just do not assume the vector is consecutive in memory.

    Instead of a simple linear array, specify the data as a pointer, number of data items between consecutive elements (stride), and vector size (element count):
    Code:
    double my_function(double *const vector, const long stride, const long size)
    {
        /* Element i (0 <= i < size), is (vector[i * stride]). */
    }
    The strides you can trivially compute:
    • (long)(&Solution[0][0][1] - &Solution[0][0][0]) for a row vector -- I do believe this is defined to be 1 in C
    • (long)(&Solution[0][1][0] - &Solution[0][0][0]) for a column vector
    • (long)(&Solution[1][0][0] - &Solution[0][0][0]) for a plane vector

    Note that the stride is not in units of bytes or chars, but the data units, here doubles, so the data types matter. If you use the actual data array to compute the (three) strides, it will be correct every time. You could use for example
    Code:
    #define  PLANES 3
    #define  ROWS 20
    #define  COLUMNS 20
    
    double  Solution[PLANES][ROWS][COLUMNS];
    
    const long  Solution_row = 1L;
    const long  Solution_column = &Solution[0][1][0] - &Solution[0][0][0];
    const long  Solution_plane = &Solution[1][0][0] - &Solution[0][0][0];
    
    /* Third column vector (column 2): */
    result = my_function(&Solution[0][0][2], Solution_column, ROWS);
    If you supply the pointer to the final element, and negate the stride, you can reverse the vector component order, too. It is sometimes very useful.

    There are also two-dimensional and higher-dimensional equivalents, of course: just specify the size and stride for each dimension separately. In 2D, for example:
    Code:
    double my_function(double *const plane, const long rowstride, const long colstride, const long rows, const long cols)
    {
        /* Element (r,c), (0 <= r < rows, 0 <= c < cols) is
         *      plane[r * rowstride + c * colstride]
        */
    }
    but I personally prefer to define structures (with the size and stride fields, and a pointer to the data origin). Let me know if you want examples.

  6. #6
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Not quite sure what you mean by getting column elements as a vector. I believe you mean you want elements to be consecutive in single dimension arrays.
    You can transpose the Solution[3][20][20] into Solution_T[20][20][3] so that the last axis can be referenced using a [20][20] index and its 3 elements are consecutive.
    You could also generate vectors of addresses to the column oriented elements and then reference these by consecutively dereferencing these addresses. But that's just like making a loop like AndiPersti suggested with additional address arrays.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multi-Column List Box
    By Dark Dude in forum Windows Programming
    Replies: 2
    Last Post: 11-15-2008, 10:03 AM
  2. Multi column Listbox
    By Gravedigga in forum Windows Programming
    Replies: 1
    Last Post: 10-12-2003, 12:20 PM
  3. Multi-Column Listbox :: C#
    By kuphryn in forum C# Programming
    Replies: 2
    Last Post: 11-20-2002, 01:15 AM
  4. Replies: 10
    Last Post: 10-27-2002, 01:45 AM
  5. Multi-Column ListBox
    By bonkey in forum Windows Programming
    Replies: 2
    Last Post: 10-18-2002, 07:49 AM