векторв mxArray с использованием memcpy - PullRequest
0 голосов
/ 22 октября 2018

У меня есть корреляционная матрица данных, и я хочу использовать pca для преобразования их в некоррелированный набор.

, поэтому я решил использовать механизм MATLAB (c ++ mex API) для выполнения pca

Мой вопрос заключается в том, как эффективно скопировать содержимое матрицы в mxArray. Я использовал циклы для выделения каждого элемента матрицы ... С другой стороны, я искал memcpy, и он кажется подверженным ошибкам.

хотя я проверил следующее, и он просто копирует первый столбец!

memcpy((double *)mxGetPr(T), &rho_mat[0][0], rows * sizeof(double));

Каков наилучший способ копирования данных (матрица -> mxArray и mxArray -> matrix)?

void pca(vector<vector<double>>& rho_mat)
{
    Engine *ep;
    mxArray *T = NULL, *result = NULL;

    if (!(ep = engOpen(""))) {
        fprintf(stderr, "\nCan't start MATLAB engine\n");
        return;
    }

    size_t rows = rho_mat.size();
    size_t cols = rho_mat[0].size();

    T = mxCreateDoubleMatrix(rows, cols, mxREAL);

   double * buf = (double *)mxGetPr(T);

   for (int i = 0; i<rows; i++) {
       for (int j = 0; j<cols; j++) {
           buf[i*(cols)+j] = rho_mat[i][j];
       }
   }

    engPutVariable(ep, "T", T);


    engEvalString(ep, "PC = pcacov(T);");
    result = engGetVariable(ep, "PC");   
}

Спасибо
С уважением

1 Ответ

0 голосов
/ 22 октября 2018

Вы можете попробовать использовать std::memcpy в цикле для каждой строки.

for (int i = 0; i<rows; i++)
{
    std::memcpy(buf + i*cols, &rho_mat[i][0], cols * sizeof(double));
}

Обратите внимание, что вы должны использовать cols в вашем memcpy, чтобы обеспечить копирование каждой строки.В вашем примере это могло бы быть совпадением, если бы ваша матрица была квадратной.

Вы можете обратиться к этому ответу о том, как скопировать 1-й вектор, используя memcpy.

Редактировать:

Для копирования из двумерного массива в двумерный вектор (при условии, что вектор уже имеет размерные строки * столбцы)

for (int i = 0; i<rows; i++)
{
    std::memcpy(&rho_mat[i][0], buf + i*cols, cols * sizeof(double));
}

Обратите внимание насделанное предположение

ИЛИ

Гораздо чище было бы использовать std::assign или конструктор для std::vector

if(rho_mat.size() == 0)
{
    for (int i = 0; i<rows; i++)
    {
         rho_mat.push_back(vector<int>(buf + i*cols, buf + i*cols + cols));
         //OR
         //rho_mat.push_back(vector<int>());
         //rho_mat[i].assign(buf + i*cols, buf + i*cols + cols);
    }
}
...