我怎样才能以更动态的方式写这个?

时间:2017-11-25 17:47:58

标签: matlab

正如标题所说,我正在寻找制作这个版本的动态版本,但我无法弄清楚如何做到这一点。在这种情况下r = 30并且情况之间的差异是5(i <= 5,i <= 10,1 <= 15等)有人可以帮助我吗?

for i = 1:r
  if     i <= 5
    a_m_o(length(a_m_o)+1) = m_o(i) - m_o(1)
  elseif i <= 10
    a_m_o(length(a_m_o)+1) = m_o(i) - m_o(6)
  elseif i <= 15
    a_m_o(length(a_m_o)+1) = m_o(i) - m_o(11)
  elseif i <= 20
    a_m_o(length(a_m_o)+1) = m_o(i) - m_o(16);
  elseif i <= 25
    a_m_o(length(a_m_o)+1) = m_o(i) - m_o(21);  
  elseif i <= 30
    a_m_o(length(a_m_o)+1) = m_o(i) - m_o(26);
  end
  if a_m_o(i)<0
    a_m_o(i) = a_m_o(i) + 400;
  end
end

3 个答案:

答案 0 :(得分:3)

其他答案可指导您避免代码重复。但你需要做的另一件事是vectorize your code。向量化是一种避免循环的方法,这种循环在MATLAB中相对较慢(尽管它们现在比我开始使用MATLAB时要快得多)。

我们首先要创建一个以循环方式对m_o进行索引的数组:

I = floor(((1:r)-1)/5)*5+1;

这会创建一个数组[1,1,1,1,1,6,6,6,6,6,11,11,...]。您也可以按照其他答案中的建议使用repmatmod

使用m_oI)为m_o(I)编制索引与编写[m_o(1),m_o(1),m_o(1),m_o(1),m_o(1),m_o(6),m_o(6),m_o(6),...]相同。也就是说,我们将相同的元素索引5次,在输出数组中创建该元素的5个副本。所以现在你可以写:

a_m_o = a_m - a_m(I);

您对阴性结果的测试也可以进行矢量化:

J = a_m_o < 0;
a_m_o(J) = a_m_o(J) + 400;

除了矢量化代码更快,它通常也更容易阅读!

另请注意,您的代码a_m_o(length(a_m_o)+1) = ...效率非常低:每次循环迭代都会调整数组a_m_o的大小。较新的MATLAB实际上确定了这个用例并围绕它进行了优化,但它对pre-allocate the array的速度要快得多:

a_m_o = zeros(size(m_o));
for i = 1:r
  a_m_o(i) = a_m(i) - a_m(1);
end

对于r=30,您可能没有注意到差异,但对于较大的阵列,节省的费用可能很大。

答案 1 :(得分:2)

基本上,您将自然数(不为零)分组为5个(或setupCameraView)元素组,将组中的每个元素映射到其第一个元素。这种操作通常可以使用模数来完成:

n

这会将function k = map (i) n = 5; m = mod(i, n); if m == 0 m = 5; end k = i - m + 1; end 映射到1, 2, 3, 4 and 5; 16, 7, 8, 9 and 10; ...

答案 2 :(得分:0)

r_help=repmat([1:5:length(r)],[5,1]); %create a helper vector which got the indices in it which you need.
r_help=r_help(:);

for i = 1:r
    a_m_o(length(a_m_o)+1) = m_o(i) - m_o(r_help(i));
    if a_m_o(i)<0
        a_m_o(i) = a_m_o(i) + 400;
    end
end