【问题标题】:How to plot normal distribution along a line?如何沿着一条线绘制正态分布?
【发布时间】:2017-03-28 13:21:45
【问题描述】:

我正在编写 matlab 代码以沿一条线绘制正态分布样本。 为了让这个问题保持简单,我使用y=10 这一行。

A=randn(300,2);
x=A(:,1)';
y=A(:,2)';
x=[1.5*x(1:100)+5 1.5*x(101:200)+10 1.5*x(201:300)+15];
y=[1.5*y(1:100)+10 1.5*y(101:200)+10 1.5*y(201:300)+10];
plot(x,y,'Marker','.','LineStyle','none')
axis ( [ 1 20 1 20 ] ) ;

目标是这样的:

我的问题是,这段代码似乎效率很低,尤其是这两行:

x=[1.5*x(1:100)+5 1.5*x(101:200)+10 1.5*x(201:300)+15];
y=[1.5*y(1:100)+10 1.5*y(101:200)+10 1.5*y(201:300)+10];

然而,在我的实际代码中,这将扩展为类似

x=[1.5*x(1:100)+5 1.5*x(101:200)+10 1.5*x(201:300)+15 1.5*x(301:400)+20 1.5*x(401:500)+25 ................];

有没有一种方法可以通过使用循环或矢量化来提高效率?我试图了解如何做到这一点,但我只能找到简单的例子。我无法理解如何使用两个变量进行迭代,一个在范围部分 x(201:300)....x(301:400) 中,一个在附加部分 +15...+20

另外,我用来沿着一条线绘制正态分布样本的这种技术是正确的技术,还是有更好/更简单的方法?

【问题讨论】:

  • 为什么你认为这些行效率低下?这是一个小范围的矢量化代码,所以它应该非常快。
  • @SembeiNorimaki:这只是一个示例代码,在我的实际代码中,范围可能会超过数千。

标签: matlab loops iteration


【解决方案1】:

您通过将 A 乘以一个常数值 (1.5) 来构建 x 和 y,然后将其拆分为几个部分(1:100、101:200、201:300...)并对每个范围应用不同的偏移量。

您可以直接对 A 执行此操作。为了便于阅读,我将其分成两行,但您可以在一行中执行。

% Build offsets:
n = 10;                 % number of parts with 100 samples each
step = 5;               % offset step: 5 -> 5, 10, 15, ... 
Offset = ones(100,n);  
Offset = bsxfun(@times,step:step:step*n,Offset);
Offset = Offset(:);

% Multiply by 1.5
A = 1.5 * randn(n*100,2);  

% Add offset to both X and Y
%A = bsxfun(@plus,A,Offset); 

% or add offset only to X and leave Y without offset:
A(:,1) = A(:,1) + Offset;


plot(A(:,1), A(:,2), 'Marker', '.', 'LineStyle', 'none')
%axis ([ 1 20 1 20 ]) ;

将偏移量应用于 X 和 Y 的结果

【讨论】:

  • 谢谢,但它给了我错误Non-singleton dimensions of the two input arrays must match each other. Error in testtest (line 45) A = bsxfun(@plus,Offset,A);
  • 谢谢!我还有一个疑问,如果我想要不同的偏移量怎么办,就像在我原来的问题中我有y=x,所以我需要 x-offset 为 5 或 10,y-offset 为 0。我该怎么做?
  • 谢谢!我只是想知道如何做相反的对角线。我尝试将偏移量添加到 x,并从 y 中减去,但无济于事!
  • A(:,1) = A(:,1) + Offset; A(:,2) = A(:,2) - Offset;
【解决方案2】:

你想要的可以用bsxfun来完成:在不同的维度上对齐每种类型的变化,并让单例扩展计算所有“组合”:

A = randn(300,2);
offsets_x = [5 10 15]; % Or offsets_x = (1:size(A,1)/chunk_size)*5
offsets_y = [10 10 10];
chunk_size = 100;
x = bsxfun(@plus, 1.5*reshape(A(:,1), chunk_size, []), offsets_x);
y = bsxfun(@plus, 1.5*reshape(A(:,2), chunk_size, []), offsets_y);
x = x(:).';
y = y(:).';

从 Matlab R2016 开始,感谢 implicit expansion,您可以用更简单的方式替换 bsxfun

x = 1.5*reshape(A(:,1), chunk_size, []) +  offsets_x;
y = 1.5*reshape(A(:,2), chunk_size, []) +  offsets_y;

【讨论】:

  • 谢谢!但它给了我两种方式矩阵尺寸不匹配的错误。
  • 不适合我。不知道问题可能是什么。我刚刚编辑添加了A = 行。你能做到clear然后按原样粘贴我的代码吗?
  • 它正在工作。有没有办法offsets_x = [5 10 15]; 这可以自动化而不是硬编码?这就是我在最初的问题中遇到的问题,在实际代码中我必须写offset_x=[5 10 15 20 25 30...]
  • 好吧,你总是可以写像offset_x = (1:size(A,1)/chunk_size)*5这样的东西。已编辑。我认为这或多或少是另一个答案的作用
猜你喜欢
  • 2020-10-12
  • 2016-08-06
  • 1970-01-01
  • 2012-04-25
  • 2018-09-10
  • 1970-01-01
  • 2017-03-30
  • 2013-06-10
  • 1970-01-01
相关资源
最近更新 更多