2

This thread in SO is about multidimensional array in c++.

I have to port some code from c# to cpp. i have code like this:

private double[,] B;
...
this.B = new double[states, symbols];
double[][, ,] epsilon = new double[N][, ,]; 
double[][,] gamma = new double[N][,];
...
s += gamma[i][t, k] = ...

i have thought to use plain double array of array but it's quite pain. another solution could be vector of vector of double, or a custom Matrix2D and Matrix3D classes?

what is the best way for each of those cases?



WHAT I LEARNED:

  • multidimensional array in c++ is a great topic, and internet is full of resources. it could be handled in various ways, some of them really tricky, some others more faster to write.

  • i think that the best way is to deal with it is to use some libraries that takes in account this topic. there are a lot of them: Armadillo (nice MATLAB syntax conversion), Eigen i think is one of the better one, easy to install, easy to use, powerfull. Boost::multi_array is anotherone, and Boost is really a famous lib that is important just to take a look at how it handle the topic. As Konrad Rudolph answer STD with nested vectors or this could be another solution but, after a little search, i think the less elegant even the more easy and fast to code without external libs.

  • write a custom class. mayebe such a good exercice. peter answer or this or this are a good start point and also this post is interesting but expecially this great post blog from martin moene (one of the best essay on this topic i've read today). I mention also this answer for sparse array.

  • here is a nice tutorial direct from stroustrup

  • have a nice time with multidimensional array :-)

Community
  • 1
  • 1
nkint
  • 11,513
  • 31
  • 103
  • 174

4 Answers4

3

C++ has no direct equivalent of T[,] (although you could of course implement one by encapsulating the following code in a class. This is left as an exercise to the reader.

All C++ supports is nesting arrays/vectors (the equivalent of [][] in C#). So your first code would correspond to

vector<vector<double> > B(states, vector<double>(symbols));

… which initialises a vector of vectors, initialising the outer vector with states copies of an appropriately initialised inner vector.

Of course this can be taken to arbitrary complexity but at this point a few typedefs are in order to make the code more understandable.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • your answer seems to be a good advice. just 2 things: 1 - possibility of templating for abstract from double? 2 - so i have to completly discard matrix (double[][] or double[][][]) ? i thought it was a good and simple solution! – nkint Jan 26 '12 at 08:54
  • 1
    @nkint 1– you can of course abstract by using templates, yes. However, C++ prior to C++0x doesn’t know anything like templated typedefs. In order to simulate them you need to resort to [template metafunctions](http://stackoverflow.com/a/26162/1968). 2– If you are working heavily with matrices it makes sense (in my opinion) to write a class wrapper around the nested vectors in order to make usage more intuitive. But if you encapsulate it anyway, see also Peter Wood’s answer which is then superior to nested vectors in terms of memory consumption / performance. – Konrad Rudolph Jan 26 '12 at 10:00
2
class StateSymbols
{
public:
    StateSymbols(unsigned int states, unsigned int symbols) :
    m_states(states),
    m_stateSymbols(states * symbols)
    {
    }

    double get(unsigned int state, unsigned int symbol) const
    {
        return m_stateSymbols[(m_states * symbol) + state];
    }

private:
    const unsigned int m_states;
    std::vector<double> m_stateSymbols; 
};
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
  • +1 this is also a very good solution. Mapping a multi-dimensional matrix into a one-dimensional vector makes a lot of sense when encapsulated in a class. – Konrad Rudolph Jan 26 '12 at 10:01
  • ok this is matrix2D class. but what for matrix3D ? i.e. double[, ,] – nkint Jan 26 '12 at 10:33
1

Check out my answer on:

C++ Multi-dimensional Arrays on the Heap

It defines a basic function Create3D to allocate a 3D (generalizes to other dimensions) array in contiguous memory on the heap in a way that allows A[i][j][k] access operator syntax.

Community
  • 1
  • 1
v.chaplin
  • 617
  • 6
  • 8
0

I would say dynamic array:

double* *list;
list = new double*[3]; //dimension1=3=row
for(int i=0;i<3;i++)
    list[i] = new double[2];  //dimension2 =2 =col
list[0][0] = 1;

//...

for(int i=0;i<3;i++)
    delete [] list[i];
delete [] list;
haberdar
  • 501
  • 5
  • 6