Как получить доступ к матрице в поле структуры matlab из функции mex? - PullRequest
6 голосов
/ 11 мая 2010

Я пытаюсь выяснить, как получить доступ к матрице, которая хранится в поле в структуре matlab из функции mex.

Это ужасно затянуто ... Позвольте мне объяснить:

У меня есть структура matlab, которая была определена следующим образом:

matrixStruct = struct('matrix', {4, 4, 4; 5, 5, 5; 6, 6 ,6})

У меня есть функция mex, в которой я хотел бы получить указатель на первый элемент в матрице (matrix [0] [0], в терминах c), но мне не удалось выяснить, как это сделать.

Я пробовал следующее:

/* Pointer to the first element in the matrix (supposedly)... */
double *ptr = mxGetPr(mxGetField(prhs[0], 0, "matrix");  

/* Incrementing the pointer to access all values in the matrix */
for(i = 0; i < 3; i++){  
    printf("%f\n", *(ptr + (i * 3)));
    printf("%f\n", *(ptr + 1 + (i * 3)));
    printf("%f\n", *(ptr + 2 + (i * 3)));
}

Что в итоге печатает, так это:

4.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000

Я также попробовал варианты следующего, думая, что, возможно, это было что-то странное с вызовами вложенных функций, но безрезультатно:

/* Pointer to the first location of the mxArray */
mxArray *fieldValuePtr = mxGetField(prhs[0], 0, "matrix");

/* Get the double pointer to the first location in the matrix */
double *ptr = mxGetPr(fieldValuePtr);

/* Same for loop code here as written above */

Кто-нибудь имеет представление о том, как я могу добиться того, что я пытаюсь, или что я потенциально делаю неправильно?

Спасибо!

Редактировать: Согласно комментарию Юка, я попытался выполнить аналогичные операции над структурой, которая имеет поле под названием массив, который является одномерным массивом значений типа double.

Структура, содержащая массив, определяется следующим образом:

arrayStruct = struct('array', {4.44, 5.55, 6.66})

Я попробовал следующее в arrayStruct из функции mex:

mptr = mxGetPr(mxGetField(prhs[0], 0, "array"));

printf("%f\n", *(mptr));
printf("%f\n", *(mptr + 1));
printf("%f\n", *(mptr + 2));

... но вывод следовал тому, что было напечатано ранее:

4.440000
0.000000
0.000000

Ответы [ 3 ]

5 голосов
/ 12 мая 2010

struct('field', {a b c}) - это специальная форма конструктора структуры, которая создает структуру массив того же размера, что и массив ячеек, помещая каждый элемент ячейки в поле 'поле' соответствующего элемента. структуры. То есть это:

s = struct('field', {a b c});

дает тот же результат, что и этот:

s(1).field = a;
s(2).field = b;
s(3).field = c;

Решением вашей проблемы является использование квадратных скобок для формирования регулярного (не ячейки) массива, например:

matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6]);
1 голос
/ 12 мая 2010

Вы пытаетесь получить доступ к переменной, которая является массивом ячеек в MATLAB. Вы уверены, что данные хранятся последовательно? Что произойдет, если вы поместите двойной массив в структуру?

matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6])

Мне кажется, проблема в том, как MATLAB хранит данные в массиве ячеек. Попробуйте запустить это:

double1 = 1;
double2 = 1:2;
cellempty = {[]};
celldouble1 = {1};
celldouble2 = {1:2};
cell2doubles = {1,2};
whos

Выход:

Name              Size            Bytes  Class     Attributes
  cell2doubles      1x2               136  cell                
  celldouble1       1x1                68  cell                
  celldouble2       1x1                76  cell                
  cellempty         1x1                60  cell                
  double1           1x1                 8  double              
  double2           1x2                16  double              

Вы можете видеть, что каждый элемент массива ячеек занимает дополнительные 60 байтов к размеру чисел.

0 голосов
/ 13 ноября 2014

Я прошел через это: у меня есть структура с полем, которое является матрицей. В C ++ соответствующей структурой является, например, double**. Попытка получить доступ к полю с engGetVariable(engine,MyStruct.theField) не удалась. Я использую временную переменную для хранения MyStruct.theField, а затем использую engGetVariable(engine, tempVar) и код для получения поля матрицы из структуры выглядит так

// Fetch struct field using a temp variable
std::string tempName = std::string(field_name) + "_temp";
std::string fetchField = tempName + " = " + std::string(struct_name) 
        + "." + std::string(field_name) + "; ";
matlabExecute(ep, fetchField);
mxArray *matlabArray = engGetVariable(ep, tempName.c_str());

// Get variable elements
const int count = mxGetNumberOfElements(matlabArray);
T *data = (T*) mxGetData(matlabArray);
for (int i = 0; i < count; i++)
    vector[i] = _isnan(data[i]) ? (T) (int) -9999 : (T) data[i];

// Clear temp variable
std::string clearTempVar = "clear " + tempName + "; ";
matlabExecute(ep, clearTempVar);

// Destroy mx object
mxDestroyArray(matlabArray);

Очень похоже для установки поля матрицы на структуру Я сделал это

// Create temp variable
mxArray* array = convertVectorToMxArray(mat, nb_rows, nb_cols);  
const std::string temp_name = array_name + "_temp";
int ret = engPutVariable(ep, temp_name.c_str(), array);

// Set variable to struct field
const std::string cmd = std::string(array_name + " = " + temp_name + "; ");
matlabExecute(ep, cmd);

// Delete array
mxDestroyArray(array);
...