In his book The C++ Programming Language, Bjarne Stroustrup mentions (C.7.2; p. 838 of the Special Edition, 2000):
... We can initialize ma like this:
void int_ma() {
    for(int i=0; i<3; i++)
        for(int j=0; j<5; j++) ma[i][j] = 10 * i + j; }
...
The array ma is simply 15 ints that we access as if it were 3
  arrays of 5 ints. In particular, there is no single object in memory
  that is the matrix ma - only the elements are stored. The dimensions 3
  and 5 exist in the compiler source only.
(emphasis mine).
In other words, the notation [][]...[] is a compiler construction; syntactical sugar if you will.
For entertainment purposes, I wrote the following code:
#include<cstdlib>
#include<iostream>
#include<iterator>
#include<algorithm>
int main() {
  double ma[5][3]; double *beg = &ma[0][0]; // case 1
  //double ma[3][5]; double *beg = &ma[0][0]; // case 2
  //double ma[15]; double *beg = &ma[0]; // case 3
  double *end = beg + 15;
  // fill array with random numbers
  std::generate(beg, end, std::rand);
  // display array contents
  std::copy(beg, end, std::ostream_iterator<double>(std::cout, " "));
  std::cout<<std::endl;  
  return 0;
}
And compared the assembly generated for the three cases using the compilation command (GCC 4.7.2):
g++ test.cpp -O3 -S -oc1.s 
The cases are called c1.s, c2.s, and c3.s. The output of the command shasum *.s is:
5360e2438aebea682d88277da69c88a3f4af10f3  c1.s
5360e2438aebea682d88277da69c88a3f4af10f3  c2.s
5360e2438aebea682d88277da69c88a3f4af10f3  c3.s
Now, I must mention that the most natural construction seems to be the one-dimensional declaration of ma, that is: double ma[N], because then the initial position is simply ma, and the final position is simply ma + N (this is as opposed to taking the address of the first element of the array).
I find that the algorithms provided by the <algorithm> C++ Standard Library header fit much more snuggly in this case.
Finally, I must encourage you to consider using std::array or std::vector if at all possible.
Cheers.