Какова подходящая структура данных для матрицы со случайными переменными? - PullRequest
3 голосов
/ 08 января 2011

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

[a b; c d]

Я хочу найти структуру данных, которая позволит a, b, c, d быть либо действительными числами, либо случайными переменными.В качестве примера, скажем, что a = 1, b = -1, c = 2, но пусть d будет нормально распределенной случайной величиной со средним 0 и стандартным отклонением 1.

Структура данных, которую я имею вум не примет значения d.Однако я также хочу иметь возможность разработать функцию, которая может принимать структуру, моделировать uniform(0,1), получать значение для d с использованием обратного CDF, а затем выплевывать фактическую матрицу.

У меня есть несколько идей для этого (все они связаны с функцией MATLAB icdf), но я хотел бы знать, как это делают более опытные программисты.В этом приложении важно, чтобы структура была как можно более «обедненной», поскольку я буду работать с очень очень большими матрицами, и память будет проблемой.

РЕДАКТИРОВАТЬ # 1:

Спасибо всем за отзывы.Я решил использовать структуру ячеек и хранить случайные переменные в качестве дескрипторов функций.Чтобы сэкономить время обработки для крупномасштабных приложений, я решил сослаться на расположение случайных переменных, чтобы сэкономить время во время части «оценки».

Ответы [ 2 ]

3 голосов
/ 09 января 2011

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

generatorMatrix = {1 -1; 2 @randn};

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

function numMatrix = create_matrix(generatorMatrix)
  index = cellfun(@(c) isa(c,'function_handle'),...  %# Find function handles
                  generatorMatrix);
  generatorMatrix(index) = cellfun(@feval,...        %# Evaluate functions
                                   generatorMatrix(index),...
                                   'UniformOutput',false);
  numMatrix = cell2mat(generatorMatrix);  %# Change from cell to numeric matrix
end

Некоторые дополнительные действия, которые вы можете сделать, это использование анонимных функций делать более сложные вещи со встроенными функциями или создавать записи в ячейках различного размера.Это показано на следующем примере матрицы, которую можно использовать для создания матрицы, в которой первая строка содержит 5, затем 9, а остальные 9 строк содержат 1, а затем 9 чисел, взятых из равномерного распределения между 5 и 10:

generatorMatrix = {5 ones(1,9); ones(9,1) @() 5*rand(9)+5};

И каждый раз, когда эта матрица передается в create_matrix, она создает новую матрицу 10 на 10, где подматрица 9 на 9 будет содержать различный набор случайных значений.


Альтернативное решение ...

Если ваша матрица может быть легко разбита на блоки подматриц (как во втором примере выше), тогда используйте массив ячеек дляХранить числовые значения и дескрипторы функций может быть вашим лучшим вариантом.

Однако, если случайные значения представляют собой отдельные элементы, разбросанные по всей матрице, тогда может сработать вариант, аналогичный тому, что user57368 предложил лучше.Вы можете хранить ваши данные матрицы в трех частях: числовая матрица с заполнителями (например, NaN ), куда будут попадать случайно сгенерированные значения, вектор индекса, содержащий линейных индексов позицийсгенерированных случайным образом значений и массив ячеек той же длины, что и индексный вектор, содержащий функцию, обрабатывает для функций, которые будут использоваться для генерации случайных значений.Чтобы упростить задачу, вы даже можете сохранить эти три фрагмента данных в структуре .

. В качестве примера ниже определяется матрица 3 на 3 с 3 случайными значениями, хранящимися виндексы 2, 4 и 9 и взяты соответственно из нормального распределения , равномерного распределения от 5 до 10 и экспоненциального распределения :

matData = struct('numMatrix',[1 nan 3; nan 2 4; 0 5 nan],...
                 'randIndex',[2 4 9],...
                 'randFcns',{{@randn , @() 5*rand+5 , @() -log(rand)/2}});

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

function numMatrix = create_matrix(matData)
  numMatrix = matData.numMatrix;
  numMatrix(matData.randIndex) = cellfun(@feval,matData.randFcns);
end
1 голос
/ 08 января 2011

Если бы вы использовали NumPy, то замаскированные массивы были бы очевидным местом для начала, но я не знаю ни одного эквивалента в MATLAB.Массивы ячеек могут быть недостаточно компактными, и если бы вы использовали массив ячеек, вам пришлось бы придумать эффективный способ найти нереальные записи и заменить их образцом из правильного распределения.

Попробуйте использовать регулярную или разреженную матрицу для хранения реальных значений и оставьте ее равной нулю везде, где вы хотите случайную переменную.Затем вместе с этим храните разреженную матрицу той же формы, ненулевые элементы которой соответствуют случайным переменным в вашей матрице.При желании значение записи во второй матрице можно использовать для указания, какое распределение (т. Е. 1 для равномерного, 2 для нормального и т. Д.).

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

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