Allocating Four Dimensional Dynamic Arrays...

Discussion in 'C++' started by fivelitermustang, May 21, 2004.

  1. Actually, how would I go about allocating a four-dimensional dynamic
    array?

    I only know how to make two dimensional dynamic arrays:
    double **v;
    v = new double*[C];
    for (int i=0; i<C; i++)
    {
    v = new double[n];
    }

    Well my plans have changed a bit and I need to make an array to store
    matrices "v" (like the one I allocated above with dynamic dimensions C*n).
    I'm not going to use the code above... I want to allocate all four
    dimensions in one snippet. It needs to be done in a similar manner because
    I'm not sure that the memory will be contiguous.

    What I want to do is have an array going a variable number of levels deep,
    and the row after the previous will have "n" times the amount of matrices
    "v".

    For example... if n was 3:

    On the first row there would contain 1 matrix "v".
    On the second row there would contain 3 matrix "v".
    On the third row there would contain 9 matrix "v".

    In the program I am writing it would be convenient to access these members
    like this:

    example:
    [1, 2, 1, 2]
    This would correlate to the matrix v found on the second row and third
    column of this matrix. It would access the second row and third column of
    the member v that was seleced by the first two parameters)
     
    fivelitermustang, May 21, 2004
    #1
    1. Advertising

  2. "fivelitermustang" <> wrote in message
    news:...
    > Actually, how would I go about allocating a four-dimensional dynamic
    > array?
    >
    > I only know how to make two dimensional dynamic arrays:
    > double **v;
    > v = new double*[C];
    > for (int i=0; i<C; i++)
    > {
    > v = new double[n];
    > }
    >
    > Well my plans have changed a bit and I need to make an array to store
    > matrices "v" (like the one I allocated above with dynamic dimensions C*n).
    > I'm not going to use the code above... I want to allocate all four
    > dimensions in one snippet. It needs to be done in a similar manner because
    > I'm not sure that the memory will be contiguous.
    >
    > What I want to do is have an array going a variable number of levels deep,
    > and the row after the previous will have "n" times the amount of matrices
    > "v".
    >
    > For example... if n was 3:
    >
    > On the first row there would contain 1 matrix "v".
    > On the second row there would contain 3 matrix "v".
    > On the third row there would contain 9 matrix "v".
    >


    > In the program I am writing it would be convenient to access these members
    > like this:
    >
    > example:
    > [1, 2, 1, 2]
    > This would correlate to the matrix v found on the second row and third
    > column of this matrix. It would access the second row and third column of
    > the member v that was seleced by the first two parameters)
    >



    A big issue is whether the number of dimensions is a constant known at
    compile time, or whether you want to vary that at run time. Most of the time
    you say four dimensions but then you say 'a variable number of levels deep'.

    If the former then look at multi_array from boost,
    http://www.boost.org/libs/multi_array/doc/index.html.

    If the later then its not easy. One problem is how you access the
    multi-dimensional array when you need a variable number integers to specify
    an element. You would have to overload operator() with a variable number of
    parameters I think.

    In any case it sounds a very unwieldy data structure, I doubt that you
    really need to do this, but then I don't know what problem you are actually
    trying to solve.

    john
     
    John Harrison, May 21, 2004
    #2
    1. Advertising

  3. The amount of levels is specified at run time by the user. Instead of
    variable, I meant to say dynamic as the memory would be allocated at
    run-time when the user specifies it.

    Actually, I've looked at the problem and I've already coded out my
    pseudo-code for this problem to work with this type of strucutre. This
    "pyramid"-like structure would be the best option to use in my case.

    I was wondering what the syntax would be to make this and how would I go
    about deallocating the memory and so forth.
     
    fivelitermustang, May 21, 2004
    #3
  4. "fivelitermustang" <> wrote in message
    news:...
    > The amount of levels is specified at run time by the user. Instead of
    > variable, I meant to say dynamic as the memory would be allocated at
    > run-time when the user specifies it.
    >
    > Actually, I've looked at the problem and I've already coded out my
    > pseudo-code for this problem to work with this type of strucutre. This
    > "pyramid"-like structure would be the best option to use in my case.
    >
    > I was wondering what the syntax would be to make this and how would I go
    > about deallocating the memory and so forth.
    >


    I'm not sure exactly what you requirements are, maybe if you showed me the
    pseudo code.

    But in any case the answer is the usual one, you write a class that defines
    the interface you need and then you go about writing the implementation. The
    big issue seems to be that you require variable numbers of arguments in the
    constructor and in some sort of element access method.

    class MultiArray
    {
    public:
    MultiArray(int rank, ...);
    double& operator()(int first_index, ...);
    };

    rank is the number of dimensions of your array, and it is expected to be
    followed by the size of each dimension (also int's). operator() is expected
    to be called with an int for each dimension to access an individual element.

    Note there is no safety here, there is no way for C++ or you to check that
    the constructor or the operator() is called with the correct number of
    arguments. This is why this sort of thing is rarely done.

    To access the variable number of parameter you need to use the macros in
    <stdarg.h>. Here's a snippet of what the constructor might look like

    #include <stdarg.h>

    MultiArray::MultiArray(int rank, ...) : my_rank(rank)
    {
    va_list arg_ptr;
    va_begin(arg_ptr, rank);

    // calculate total size
    int size = 1;
    for (int i = 0; i < rank; ++i)
    size *= va_arg(arg_ptr, int);
    ...
    va_end(arg_ptr);
    }

    That's just to give you an idea. I think you have quite a lot of work to do
    to make this work.

    john
     
    John Harrison, May 22, 2004
    #4
  5. I haven't covered classes yet so I'm not quite familiar with the workings
    of the code snippet you have posted.

    I have the code written to iterate through a static four-dimensional
    array. The array is initialized in the pyramid structure and the remaining
    values are zero. It works properly and moves through them and I get the
    proper results. I just need to get this dynamically allocated.

    Since I'm not really that familiar with classes isn't it possible to
    initialize this array with loops and making pointers?

    If that is possible could you just show me the proper syntax to make a 4D
    square/rectangular array using the method that I was using to make that 2D
    dynamic array?

    Thanks for your patience.

    Adam
     
    fivelitermustang, May 22, 2004
    #5
  6. "fivelitermustang" <> wrote in message
    news:...
    > I haven't covered classes yet so I'm not quite familiar with the workings
    > of the code snippet you have posted.
    >
    > I have the code written to iterate through a static four-dimensional
    > array. The array is initialized in the pyramid structure and the remaining
    > values are zero. It works properly and moves through them and I get the
    > proper results. I just need to get this dynamically allocated.
    >
    > Since I'm not really that familiar with classes isn't it possible to
    > initialize this array with loops and making pointers?
    >
    > If that is possible could you just show me the proper syntax to make a 4D
    > square/rectangular array using the method that I was using to make that 2D
    > dynamic array?
    >


    I'm confused about what you want, but here some code that allocates a 4D
    array. It's the same as your 2D code but expanded to 4 dimensions. I'm not
    sure what dimensions you actually want (some combination of C and n in your
    original post I think) so I've used D1, D2, D3 and D4 for the dimensions,
    you can substitute the values you want.

    double**** v;
    v = new double***[D1];
    for (int i = 0; i < D1; ++i)
    {
    v = new double**[D2];
    for (int j = 0; j < D2; ++j)
    {
    v[j] = new double*[D3];
    for (int k = 0; k < D3; ++k)
    {
    v[j][k] = new double[D4];
    }
    }
    }

    But this doesn't work if you want a variable number of dimensions, which is
    what I thought you wanted. Nor does it allocate memory in a single block,
    which is another thing I thought you wanted. So I'm a bit confused.

    There's nothing special about classes, anything you can do inside a class
    you can also do outside a class. What classes do however is wrap up all your
    code in an easy to use package, something that might be quite useful here.

    john
     
    John Harrison, May 22, 2004
    #6
  7. "John Harrison" <> wrote in message
    news:...
    |
    | "fivelitermustang" <> wrote in message
    | news:...
    | > I haven't covered classes yet so I'm not quite familiar with the workings
    | > of the code snippet you have posted.
    | >
    | > I have the code written to iterate through a static four-dimensional
    | > array. The array is initialized in the pyramid structure and the remaining
    | > values are zero. It works properly and moves through them and I get the
    | > proper results. I just need to get this dynamically allocated.
    | >
    | > Since I'm not really that familiar with classes isn't it possible to
    | > initialize this array with loops and making pointers?
    | >
    | > If that is possible could you just show me the proper syntax to make a 4D
    | > square/rectangular array using the method that I was using to make that 2D
    | > dynamic array?
    | >
    |
    | I'm confused about what you want, but here some code that allocates a 4D
    | array. It's the same as your 2D code but expanded to 4 dimensions. I'm not
    | sure what dimensions you actually want (some combination of C and n in your
    | original post I think) so I've used D1, D2, D3 and D4 for the dimensions,
    | you can substitute the values you want.
    |
    | double**** v;
    | v = new double***[D1];
    | for (int i = 0; i < D1; ++i)
    | {
    | v = new double**[D2];
    | for (int j = 0; j < D2; ++j)
    | {
    | v[j] = new double*[D3];
    | for (int k = 0; k < D3; ++k)
    | {
    | v[j][k] = new double[D4];
    | }
    | }
    | }
    |
    | But this doesn't work if you want a variable number of dimensions, which is
    | what I thought you wanted. Nor does it allocate memory in a single block,
    | which is another thing I thought you wanted. So I'm a bit confused.
    |
    | There's nothing special about classes, anything you can do inside a class
    | you can also do outside a class. What classes do however is wrap up all your
    | code in an easy to use package, something that might be quite useful here.

    The OP may be much better off with nested vectors, wrapped
    up in an class that provides suitable accessors. This would
    allow for a variable number of dimensions, not to mention
    ease the pain and danger of memory management on your own.

    Cheers.
    Chris Val
     
    Chris \( Val \), May 22, 2004
    #7
  8. fivelitermustang

    Daniel T. Guest

    "fivelitermustang" <> wrote:

    >Actually, how would I go about allocating a four-dimensional dynamic
    >array?


    class Matrix4
    {
    std::vector<double> storage;
    int bb;
    int cc;
    int dd;
    public:
    Matrix4( int a, int b, int c, int d ):
    storage( a*b*c*d ), bb( b ), cc( c ), dd( d ) { }
    double& operator()( int a, int b, int c, int d ) {
    return storage.at( bb*cc*dd*a + cc*dd*b + dd*c + d );
    }
    };

    You use it like this:

    Matrix4 m( 1, 2, 3, 5 );

    m( 0, 1, 0, 4 ) = 5.0;
    assert( m( 0, 1, 0, 4 ) == 5.0 );
     
    Daniel T., May 22, 2004
    #8
  9. fivelitermustang

    JKop Guest

    Daniel T. posted:


    > class Matrix4
    > {
    > std::vector<double> storage;
    > int bb;
    > int cc;
    > int dd;
    > public:
    > Matrix4( int a, int b, int c, int d ):
    > storage( a*b*c*d ), bb( b ), cc( c ), dd( d ) { }
    > double& operator()( int a, int b, int c, int d ) {
    > return storage.at( bb*cc*dd*a + cc*dd*b + dd*c + d );
    > }
    > };
    >
    > You use it like this:
    >
    > Matrix4 m( 1, 2, 3, 5 );
    >
    > m( 0, 1, 0, 4 ) = 5.0;
    > assert( m( 0, 1, 0, 4 ) == 5.0 );



    genius


    -JKop
     
    JKop, May 22, 2004
    #9
  10. Thanks John... I tailored that snippet of code to suit my needs a little
    bit better.

    double**** highv;
    v = new double***[n];
    for (int i = 0; i < n; ++i)
    {
    v = new double**[(i+1)*n];
    for (int j = 0; j < (i+1)*n; ++j)
    {
    v[j] = new double*[C];
    for (int k = 0; k < C; ++k)
    {
    v[j][k] = new double[n];
    }
    }
    }

    That above snippet should allocate a tree of matrices "v" which have a
    dimension C*n. The tree will be n rows and each proceding row will have n
    times what the row before had. Is my code correct?

    How do I deallocate that memory too?

    Thanks a lot for the ample help here... I'm gonna save this information
    about classes. I'll then read up on that after I get the whole program
    with my current method of allocating matrice. Then I'll attempt to clean
    up the code with these classes.

    I'm reading "C++ Programming: From Problem Analysis to Program Design" by
    D.S. Malik by the way... seems to have some good information on classes.
     
    fivelitermustang, May 23, 2004
    #10
  11. Thanks John... I tailored that snippet of code to suit my needs a little
    bit better.

    double**** highv;
    v = new double***[n];
    for (int i = 0; i < n; ++i)
    {
    v = new double**[(i+1)*n];
    for (int j = 0; j < (i+1)*n; ++j)
    {
    v[j] = new double*[C];
    for (int k = 0; k < C; ++k)
    {
    v[j][k] = new double[n];
    }
    }
    }

    That above snippet should allocate a tree of matrices "v" which have a
    dimension C*n. The tree will be n rows and each proceding row will have n
    times what the row before had. Is my code correct?

    How do I deallocate that memory too?

    Thanks a lot for the ample help here... I'm gonna save this information
    about classes. I'll then read up on that after I get the whole program
    with my current method of allocating matrice. Then I'll attempt to clean
    up the code with these classes.

    I'm reading "C++ Programming: From Problem Analysis to Program Design" by
    D.S. Malik by the way... seems to have some good information on classes.
     
    fivelitermustang, May 23, 2004
    #11
  12. "fivelitermustang" <> wrote in message
    news:...
    > Thanks John... I tailored that snippet of code to suit my needs a little
    > bit better.
    >
    > double**** highv;
    > v = new double***[n];
    > for (int i = 0; i < n; ++i)
    > {
    > v = new double**[(i+1)*n];
    > for (int j = 0; j < (i+1)*n; ++j)
    > {
    > v[j] = new double*[C];
    > for (int k = 0; k < C; ++k)
    > {
    > v[j][k] = new double[n];
    > }
    > }
    > }
    >
    > That above snippet should allocate a tree of matrices "v" which have a
    > dimension C*n. The tree will be n rows and each proceding row will have n
    > times what the row before had. Is my code correct?


    I don't see why you have (i + 1)*n, just this I think.

    v = new double**[n];
    for (int j = 0; j < n; ++j)

    >
    > How do I deallocate that memory too?
    >


    Just reverse the order of the new's, make sure the loop limits are the same
    as when you allocated.

    for (int i = 0; i < n; ++i)
    {
    for (int j = 0; j < n; ++j)
    {
    for (int k = 0; k < C; ++k)
    {
    delete[] v[j][k];
    }
    delete[] v[j];
    }
    delete[] v;
    }
    delete[] v;

    > Thanks a lot for the ample help here... I'm gonna save this information
    > about classes. I'll then read up on that after I get the whole program
    > with my current method of allocating matrice. Then I'll attempt to clean
    > up the code with these classes.


    Sounds reasonable.

    john
     
    John Harrison, May 23, 2004
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alf P. Steinbach
    Replies:
    0
    Views:
    454
    Alf P. Steinbach
    Aug 18, 2003
  2. John Harrison
    Replies:
    4
    Views:
    6,957
    Default User
    Aug 19, 2003
  3. Icosahedron
    Replies:
    8
    Views:
    688
    Vivek
    Aug 21, 2003
  4. kak3012
    Replies:
    4
    Views:
    3,558
    kak3012
    Jan 23, 2005
  5. Wirianto Djunaidi
    Replies:
    2
    Views:
    228
    Wirianto Djunaidi
    Apr 29, 2008
Loading...

Share This Page