【问题标题】:Changing numbers for given indices between matrices更改矩阵之间给定索引的数字
【发布时间】:2014-12-09 17:30:00
【问题描述】:

我正在为我的一项 matlab 作业而苦苦挣扎。我想创建 10 个不同的模型。它们中的每一个都基于相同的原始数组,尺寸为 1x100 m_est。然后使用 for 循环,我从原始模型中选择 5 个随机值,并希望向它们中的每一个添加相同的随机值。循环重复 10 次,每次选择不同的值并添加不同的随机数。这是我的代码的一部分:

steps=10;

for s=1:steps

    for i=1:1:5
        rl(s,i)=m_est(randi(numel(m_est))); 
        rl_nr(s,i)=find(rl(s,i)==m_est);
        a=-1;
        b=1;
        r(s)=(b-a)*rand(1,1)+a; 
    end
    pert_layers(s,:)=rl(s,:)+r(s); 
    M=repmat(m_est',s,1); 

end

for k=steps
    for m=1:1:5
        M_pert=M;
        M_pert(1:k,rl_nr(k,1:m))=pert_layers(1:k,1:m);
    end
end 

在矩阵 M 中,我存储了 10 个初始模型,并希望用 rl_nr 矩阵中的索引替换随机数到存储在 pert_layers 矩阵中的那些。但是,负责将值从 pert_layers 分配给 rl_nr 索引的最后一个循环无法正常工作。

有人知道怎么解决吗?

最好的问候

【问题讨论】:

  • 嗯,最后一个循环导致了问题。我无法弄清楚如何正确编写这一行: M_pert(1:k,rl_nr(k,1:m))=pert_layers(1:k,1:m);因为 matlab 似乎要么仅从 rl_nr 的第一个数组更改索引,要么随机选择它们。我希望程序将 pert_layers 中的值分配给 rl_nr 索引并将其放入 M_pert 矩阵。我希望这能清楚地解释我的意图。
  • 小注。在您的最后一个 for 循环中,M_pert 不断重新初始化,因此它只会记住在该循环的最后一次迭代中所做的更改。但是,我正在写一个更加矢量化的答案,敬请期待。

标签: matlab


【解决方案1】:

您的代码使用了很多循环,在这种特殊情况下,它的效率非常低。如果你真的矢量化你的代码会更好。因此,让我一次过一遍您的问题描述,然后让我们编写每个部分的代码(如果适用):

我想创建 10 个不同的模型。它们中的每一个都基于相同的原始数组,尺寸为 1x100 m_est。

我将此解释为您有一个包含 100 个元素的数组 m_est,并且您希望使用该数组创建 10 个不同的“模型”,其中每个模型是从 m_est 采样的 5 个元素。 rl 将存储来自m_est 的这些值,而rl_nr 将存储这些值源自的索引/位置。此外,对于每个模型,您希望为该模型的每个元素添加一个随机值。

然后使用 for 循环,我从原始模型中选择 5 个随机值,并希望为每个随机值添加相同的随机值。

不要使用for 循环执行此操作,而是一次性生成所有随机索引。由于您有 10 个步骤,并且我们希望每步骤采样 5 个点,因此您总共有 10*5 = 50 个点。因此,您为什么不改用randperm 呢? randperm 正是您正在寻找的,我们可以使用它来生成唯一的随机索引,以便我们最终可以使用它从 m_est 中采样。 randperm 生成从 1N 的向量,但返回这些元素的随机排列。这样,您只会得到从1N 枚举的数字,并且我们将确保不会重复。因此,只需使用randperm 生成 50 个元素,然后将该数组重新整形为大小为10 x 5 的矩阵,其中行数告诉您您想要的步数,而列数是总数每个模型的分数。因此,请执行以下操作:

num_steps = 10;
num_points_model = 5;
ind = randperm(numel(m_est));
ind = ind(1:num_steps*num_points_model);
rl_nr = reshape(ind, num_steps, num_points_model);
rl = m_est(rl_nr);

前两行非常简单。我们只是声明了您要采取的总步数,以及每个模型的总点数。接下来,我们要做的是生成长度为 100 的随机排列,其中元素从 1 到 100 枚举,但它们是随机顺序的。您会注意到,这个随机向量只恰好使用了 1 到 100 范围内的一个值。因为您只想获得总共 50 个点,所以只需对该向量进行子集化,以便我们仅获得从 randperm 生成的前 50 个随机索引。这些随机索引存储在ind

接下来,我们简单地将ind 重塑为10 x 5 矩阵以得到rl_nrrl_nr 将包含用于从大小为 10 x 5m_est 中选择这些条目的索引。最后,rl 将是一个与rl_nr 大小相同的矩阵,但它将包含从m_est 采样的实际随机值。这些随机值对应于从rl_nr 生成的那些索引。

现在,最后一步是为每个模型添加相同的随机数。您当然可以使用repmat 复制一个包含 10 个元素长的随机列向量,并将它们复制 5 次,这样我们就有 5 列,然后将此矩阵与 rl.... 相加,如下所示:

a = -1;
b = 1;
r = (b-a)*rand(num_steps, 1) + a;
r = repmat(r, 1, num_points_model);
M_pert = rl + r;

现在M_pert 是您想要的最终结果,我们获取存储在rl 中的每个模型,并将相同的随机值添加到矩阵中的每个对应模型。但是,如果我可以提出更有效的建议,我建议您改用 bsxfun,它会在后台执行此复制。本质上,上面的代码将被替换为:

a = -1;
b = 1;
r = (b-a)*rand(num_steps, 1) + a;
M_pert = bsxfun(@plus, rl, r);

更容易阅读,代码更少。 M_pert 将在每一行中包含您的模型,并为每个特定模型添加相同的随机值。

循环重复10次,每次选择不同的值并添加不同的随机数。

以上步骤已经完成。


我希望您不会觉得完全重写代码以使其更加矢量化是一种强迫,但我认为这是向您展示 MATLAB 必须提供的一些更高级功能以及生成随机值的更有效方法,而不是一次循环和生成一个值。

希望这能让您入门。祝你好运!

【讨论】:

  • 我很高兴听到这个详细的答案。我知道我的编码有点过时,因为我有一段时间没有使用 matlab。但我的主要问题是模型创建的最后阶段(最后一个for 循环)。所以主要的想法是创建 10 个基于原始 m_est 的模型,我通过创建看起来像 M=repmat(m_est',num_steps,1) 的 M 矩阵。现在棘手的部分是将rl_nr 位置下的M 中的值替换为存储在rl 中的值。所以一般来说,将矩阵rl 放入M 的位置rl_nr。再次感谢您的回复。
  • @Pawel - 我不太明白那行代码中发生了什么,所以我无法真正提供答案。我很抱歉。
  • 好吧,假设我们有一个模型m_est=(1,100) 有一些测量数据。我的任务是在矩阵中选择随机位置并将相同数字添加到这些位置的值(在这种情况下它也是随机的)。因此,这就是在我的模型m_est 中的随机位置添加一个常数/相同的数字。我知道这听起来可能很奇怪。我想过M(rl_nr)=rl,但它不起作用......
  • @Pawel - 好吧,在我对你的回答中,我确实这样做了......但是,为了让它与你的最后一个 for 循环一起工作......我有点的麻烦。我会考虑的,但您可能应该考虑采用矢量化方式,而不是坚持使用多个 for 循环恕我直言。
  • 我已经创建了这样的东西来生成最后一步:M=repmat(m_est',num_steps,1); M(1,(rl_nr(1,:)))=M_pert(1,:); 当然它只适用于 M 的第一行,在这里我会使用for 循环,但正如你之前提到的那样不断重新初始化,我只将rl 的最后一行放入矩阵M。你知道如何解决吗?至于矢量化方法,我可能不得不以某种方式将num_steps 合并到M(1,(rl_nr(1,:)))=M_pert(1,:); 中,但我必须说我不知道​​如何。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多