Allocating Four Dimensional Dynamic Arrays...

F

fivelitermustang

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)
 
J

John Harrison

fivelitermustang said:
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
 
F

fivelitermustang

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.
 
J

John Harrison

fivelitermustang said:
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
 
F

fivelitermustang

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
 
J

John Harrison

fivelitermustang said:
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
 
C

Chris \( Val \)

|
| | > 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
 
D

Daniel T.

fivelitermustang said:
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 );
 
J

JKop

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
 
F

fivelitermustang

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.
 
F

fivelitermustang

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.
 
J

John Harrison

fivelitermustang said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top