【问题标题】:What's an appropriate data structure for a matrix with random variable entries?对于具有随机变量条目的矩阵,什么是合适的数据结构?
【发布时间】:2011-06-05 20:37:23
【问题描述】:

我目前在与模拟相关的领域工作,并尝试设计一种可以在矩阵中包含随机变量的数据结构。为了激发这一点,让我说我有以下矩阵:

[a b; c d]

我想找到一个允许a, b, c, d 是实数或随机变量的数据结构。例如,假设a = 1b = -1c = 2,但让d 是一个均值为 0 标准差为 1 的正态分布随机变量。

我想到的数据结构不会给d 带来任何价值。不过,我也希望能够设计一个函数,可以接受结构,模拟uniform(0,1),使用逆CDF 获得d 的值,然后吐出一个实际矩阵。

我有几个想法可以做到这一点(都与 MATLAB icdf 函数有关),但想知道更有经验的程序员会如何做到这一点。在这个应用程序中,结构尽可能“精简”很重要,因为我将使用非常大的矩阵并且内存将是一个问题。

编辑#1:

感谢大家的反馈。我决定使用单元结构并将随机变量存储为函数句柄。为了为大规模应用节省一些处理时间,我决定在“评估”部分参考随机变量的位置以节省时间。

【问题讨论】:

  • 所有要支持的随机元素是否总是正态分布和独立的?或者您是否需要支持其他分布和/或协方差?
  • 更多关于这些大型矩阵的详细信息将帮助我们为您提供更具体的解决方案。特别是,随机值会被分组到较大矩阵中的子矩阵中,还是会分散在整个较大矩阵中?
  • @aschepler:我需要它来支持用户定义的随机变量,以及其他通用随机变量类型(即正常、测试、统一等)
  • @gnovice:它们将分散在更大的矩阵中,所以我相信我还将存储 RV 的索引,而不必遍历矩阵

标签: matlab matrix random data-structures simulation


【解决方案1】:

一种解决方案是最初将矩阵创建为包含数值的cell array 和用于为该条目生成值的函数的function handles。对于您的示例,您可以执行以下操作:

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

然后您可以创建一个函数,该函数采用上述形式的矩阵evaluates the cells containing function handles,然后将结果与数字单元格条目组合到create a numeric matrix 以用于进一步计算:

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

您可以做的其他一些事情是使用anonymous functions 使用内置函数执行更复杂的事情或创建不同大小的单元格条目。以下示例矩阵说明了这一点,该矩阵可用于创建一个矩阵,其中第一行包含 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 suggested 的变体可能会更好。您可以将矩阵数据存储在三个部分中:一个带有占位符的数字矩阵(例如NaN),其中随机生成的值将存储在其中,一个包含随机生成值位置的linear indices 的索引向量,以及一个与包含function handles 的索引向量长度相同的元胞数组,用于生成随机值的函数。为方便起见,您甚至可以将这三段数据存储在 structure 中。

作为示例,以下定义了一个 3×3 矩阵,其中 3 个随机值存储在索引 2、4 和 9 中,并分别从从 5 到 10 的normal distributionuniform distributionexponential distribution:

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

【讨论】:

  • 如果矩阵非常大并且随机变量数量相对较少,那么第一次调用cellfun 会浪费大量时间并消耗大量内存,因为元胞数组是指针数组,并且必须为 isa 调用取消引用每个指针。我建议的方法(使用两个数组,第二个稀疏)几乎肯定会执行得更好(因为稀疏数组上的find 几乎是无操作的),但会使代码更加不透明。
  • @user57368:这就是我添加第二个示例的原因。它说明了如何在单元格之间分解矩阵,使每个单元格包含一个数组,而不仅仅是一个标量值,这样您最终需要操作的单元格总数就更少了。
  • 好的。现在您已经添加了@(),我知道它是如何工作的。对于可以在几行中定义的矩阵,绝对是最简洁的处理方式。
  • 谢谢。我目前正在考虑按照您最初描述的方式前进。我决定对随机变量使用具有真实条目和函数句柄的元胞数组。我仍然有一些关于随机变量生成的问题 - 所以我会很感激任何关于这方面的意见。
  • @squall14414:根据您的 cmets 中的额外信息,我在我的答案中添加了一个替代解决方案,您可能想要查看。
【解决方案2】:

如果您使用的是 NumPy,那么掩码数组将是显而易见的起点,但我不知道 MATLAB 中有任何等价物。元胞数组可能不够紧凑,如果您确实使用了元胞数组,那么您必须想出一种有效的方法来查找非实数条目并用正确分布的样本替换它们。

尝试使用常规或稀疏矩阵来保存实际值,并在需要随机变量的任何地方将其保持为零。然后在旁边存储一个相同形状的稀疏矩阵,其非零条目对应于矩阵中的随机变量。如果需要,第二个矩阵中的条目值可用于指示哪个分布(即 1 表示均匀分布,2 表示正态分布等)。

当您想要获得一个纯实矩阵时,您可以遍历第二个矩阵中的非零值以将它们转换为样本,然后将该矩阵添加到您的第一个矩阵中。

【讨论】:

  • @user57368:你为什么要为#2 提供一个稀疏矩阵?您可以简单地将数据放入向量中,从而节省空间和时间。
  • 您需要存储随机变量的定义及其在第一个矩阵中的位置。稀疏矩阵和向量一样可以做到这一点,但是将稀疏矩阵转换为随机样本矩阵的代码应该更简洁,并且只需将结果添加到真实矩阵中。
  • @user57368:您可以通过将NaN 放置在以后想要随机变量的任何位置来定义第一个矩阵中的位置。
  • 我想是这样,但是您必须遍历整个矩阵才能找到并替换那些 NaN。对于带有r 随机变量的m by n 矩阵,这是转换过程中O(mn+r)O(r) 之间的区别。
猜你喜欢
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多