What is the best way to represent a 2D matrix? I work with Eigen3 in C ++ 11 or more recent for an application involving a matrix-matrix multiplication operating on a single machine. I am open to code review on Eigen3 is not the best way to get the job done.

The size of the 2d matrix should be determined during runtime for matrices of different sizes. It therefore cannot be hard-coded as a global variable as in the following example. For the moment, I am using static allocation `int(m)(n)`

as an input, then break the Eigen matrix when necessary.

Here is a list of potential options I can think of:

```
1. std::array
2. std::vector
3. statically-allocated array on stack
4. dynamically-allocated array on heap(with new?)
5. use Eigen built-in matrix representation from the beginning(avoid casting back and forth when using option 1- option 4 )
```

Follow-up: what if the size of the matrices can be adjusted in a stack? I am thinking of option 3 because it is faster than option 4 when multiple memory allocations are required.

Here is an example of code that I'm trying to optimize, which doesn't work if I try to allow the size of the matrix in gemm to be variable:

```
#include
#include
//n = (7,64)
//k = (1,11), odd
const int n = 64;
const int k = 11;
using namespace Eigen;
using namespace std;
int cross_correlation(int G(n)(n), int n, int F(k)(k), int k, int x, int y) {
int sum = 0;
for (int i = 0; i < k; i++) {
for (int j = 0; j < k; j++) {
int xx = x + i - floor(k / 2);
int yy = y + j - floor(k / 2);
if (0 <= xx && xx < n && 0 <= yy && yy < n) {
sum += F(i)(j) * G(xx)(yy);
}
}
}
return sum;
}
MatrixXi gemm(const int G_(n)(n), const int F_(k)(k)) {
const int F = k;
const int P = (F - 1) / 2;
const int S = 1;
const int W = n;
const int t = (W - F + 2 * P) / S + 1;
const int length = n + 2 * P;
int padded_arr(length)(length);
memset(padded_arr, 0, length * length * sizeof(int));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
padded_arr(i + P)(j + P) = G_(i)(j);
}
}
Matrix m;
for (int i = 0; i < length; ++i)
m.row(i) = Eigen::VectorXi::Map(&padded_arr(i)(0), length);
Eigen::MatrixXi mat(F * F, 0);
for (int i = 0; i < t; i++)
for (int j = 0; j < t; j++) {
Matrix M1;
M1 = m.block(S * i, S * j);
Matrix M2(M1);
Map v2(M2.data(), M2.size());
mat.conservativeResize(mat.rows(), mat.cols() + 1);
mat.col(mat.cols() - 1) = v2;
}
Matrix filter;
for (int i = 0; i < F; ++i)
filter.row(i) = Eigen::VectorXi::Map(&F_(i)(0), F);
Matrix M2(filter);
Map v2(M2.data(), M2.size());
Matrix res(v2 * mat);
Map res_reshaped(res.data(), t, t);
return res_reshaped;
}
int main() {
MatrixXi G = MatrixXi::Random(n, n);
int GG(n)(n);
Map(&GG(0)(0), n, n) = G;
MatrixXi F = MatrixXi::Random(k, k);
int FF(k)(k);
Map(&FF(0)(0), k, k) = F;
int res(n)(n);
Map(&res(0)(0), n, n) = gemm(GG, FF);
/*verification*/
bool is_correct = true;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (res(i)(j) != cross_correlation(GG, n, FF, k, i, j))
throw new runtime_error("incorrect");
is_correct &= (res(i)(j) == cross_correlation(GG, n, FF, k, i, j));
}
}
cout << "is_correct: " << is_correct << endl;
}
```
```