Представление массивов ячеек (от MATLAB) в C - PullRequest
1 голос
/ 24 февраля 2012

Вопрос: Как мне спроектировать лучший интерфейс между массивами Cell и независимыми объектами Matrix?

Я конвертирую код MATLAB, который использует массивы ячеек и массивы ячеек, в C. Я создал тип данных Matrix.и тип данных Cell.Они проиллюстрированы ниже.

Тип данных Matrix

typedef struct{
  double * array; // row major format
  int rows;
  int cols;
} Matrix;

и тип данных Cell

typedef struct{
  Matrix * array; // row major format
  int rows;
  int cols;
} Cell;

К счастью, массив ячеек массивов ячеек в коде является простымодномерный массив ячеек, который я могу представить как массив ячеек.

В исходном коде независимые матричные объекты и элементы массива ячеек (другая матрица) появляются вместе в выражениях.Например:

a = rand(10);
% say, b is a cell array containing other matrices
% c = some expression involving an element of the cell array b and a
c = a + b{1,2};
% assuming dimensions agree

Теперь, в моем представлении, когда я создаю объект ячейки, я выделил строки * столбцы объектов Matrix и назначил указатель на массив объектов Matrix для массива (внутри ячейки),Предположим, что объекты Matrix соответствующим образом инициализируются позже в коде (перед их использованием)

Доступ к независимым объектам матрицы, которые я выделяю динамически, осуществляется путем разыменования указателей, указывающих на них, и процедуры доступа для массивов ячеек возвращают объекты Matrix.вместо указателя на объект Matrix.

// Function signature for accessor routine of cell object 
Matrix get_mat_from_cell(Cell * cell, int row, int col);

// Independent Matrix object - dynamically allocated as size is known
// at run-time
Matrix * matrixA = (Matrix *) malloc(sizeof(Matrix));

Matrix matrixB = get_mat_from_cell(someCell, 1, 2);

add(matrixA, &matrixB, matrixC); // adds matrixA, matrixB and stores in a matrixC

То, что щекочет меня, заключается в функции добавления (например), чтобы получить единый интерфейс, который принимает указатели на матрицы для всех 3 аргументов, у меня естьпередать адрес матрицыB.Он либо выглядит одинаковым на уровне интерфейса функции - например, add (Matrix *, Matrix *, Matrix *), либо равномерным на уровне вызова функции - add (Matrix *, Matrix, Matrix *), но не в обоих направлениях.

Я мог бы достичь единообразия, объявив массив внутри объекта Cell как двойной указатель, но мне нужно дважды отменить ссылку, прежде чем я смогу добраться до объекта Matrix и подумать, не будет ли это узким местом в производительности, поскольку эти ячейкидействительно большие и часто доступны.

Как мне лучше спроектировать этот интерфейс?

Спасибо.

1 Ответ

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

Похоже, вы уже поняли это, но я все равно попытаюсь протянуть руку.Во-первых, я думаю, что ваша Cell структура нуждается в настройке, если только вы не знаете, что ваша реализация очень специфична

/* small set of types as example */
typedef union matlab_fundamental_types_u
{
  CELL,
  MATRIX
} matlab_fundamental_types_t;

typedef struct Cell_s
{
  struct Cell_s * array; // row major format
  matlab_fundamental_types_t fundamental_type; /* what this cell holds, is it a cell of cells, arrays, etc? */
  int rows;
  int cols;
} Cell;

Поскольку Cell является супер контейнером и может содержать что угодно, включая Cell, имеет смысл реализовать это таким образом, хотя я думаю, что он все еще может использовать некоторую полировкуКроме того, вы упомянули, что узким местом является разыменование двойного указателя.Я не думаю, что я буду беспокоиться об этом.Мой опыт показывает, что malloc, бесплатные файловые операции являются настоящим узким местом, но единственный способ узнать наверняка - это профилировщик.Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...