NLopt с данными броненосца - PullRequest
       12

NLopt с данными броненосца

3 голосов
/ 08 декабря 2011

Целевая функция NLopt выглядит следующим образом:

double myfunc(const std::vector<double> &x, std::vector<double> &grad, void *my_func_data)

x - это данные, которые оптимизируются, grad - это вектор градиентов, а my_func_data содержит дополнительные данные.

IЯ заинтересован в поставке матриц Армадилло А и В для аннулирования * my_func_data .

Я возился с функциями-членами Армадилло

mat A(5,5);
mat B(5,5);
double* A_mem = A.memptr();
double* B_mem = B.memptr();

, что дает мне указатели на матрицы А и В.Я думал о том, чтобы определить еще один указатель на эти указатели:

double** CombineMat;
int* Arow = A.n_rows; int* Acols = A.n_cols; //obtain dimensions of A
int* Brows = B.n_rows; int* Bcols = B.n_cols; // dim(B)
CombineMat[0] = A_mem; CombineMat[1] = Arows; CombineMat[2] = Acols;
CombineMat[3] = B_mem; CombineMat[4] = Brows; CombineMat[5] = Bcols;

и затем передать * CombineMat как my_func_data.

  1. Это способ сделать это?Это кажется неуклюжим ...
  2. После того, как CombineMat пройден, как преобразовать тип void в нечто пригодное для использования, когда я нахожусь внутри myfunc?

ОТВЕТ

Я ответил на свой вопрос с помощью здесь .

mat A(2,2);
A << 1 << 2 << endr << 3 << 4;

mat B(2,2);
B << 5 << 6 << endr << 7 << 8;

mat C[2];
C[0] = A;
C[1] = B;

opt.set_min_objective(myfunc, &C);

Оказавшись внутри myfunc, данные в C могут быть преобразованы обратно в матрицы Armadillo, например так:

mat* pC = (mat*)(my_func_data);
mat A = pC[0];
mat B = pC[1];

1 Ответ

2 голосов
/ 15 февраля 2012

Вы также можете использовать класс Cube от Armadillo («матрица 3D» или тензор 3-го порядка).

Каждый фрагмент куба - это просто матрица. Например:

cube X(4,5,2);

mat A(4,5);
mat B(4,5);

X.slice(0) = A;  // set the individual slices
X.slice(1) = B;

mat& C = X.slice(1); // get the reference to a matrix stored in a cube
...