Ocatave While循环

时间:2016-11-22 12:24:13

标签: while-loop octave

我正在开发一个八度音程的程序,我将在解释代码时进行解释。所以我在一个名为matprec.m的文件中有这个矩阵:

function [res1] = matprec()
   res1 = [
1,2001,1,2,0.00;
1,2001,1,5,5.33;
2,2001,1,5,4.57;
3,2001,1,5,5.33;
4,2001,1,5,5.59;
5,2001,1,5,4.32;
2,2001,1,13,0.00;
3,2001,1,13,0.00;
4,2001,1,13,0.00;
3,2001,1,30,30.73;
2,2001,2,1,1.02;
3,2001,2,1,1.52;
4,2001,2,1,1.78;
5,2001,2,1,1.27;
1,2001,2,2,1.78;
2,2001,2,2,1.27;
3,2001,2,2,1.78;
4,2001,2,2,2.03;
5,2001,2,2,1.78;
1,2001,3,4,18.03;
3,2001,3,4,15.75;
5,2001,3,4,17.53;
1,2001,3,5,13.46;
2,2001,3,5,12.19;
3,2001,3,5,11.94;
4,2001,3,5,9.65;
5,2001,3,5,10.92;
2,2001,4,30,0.00;
4,2001,4,30,0.00];
format short g
return
endfunction

所以在这个矩阵中,第一列只是我们测量降水量的站,第二列是年,第三列是月,第四列是日,第五列是降水量。我想在另一个文件中做的是调用这个矩阵并进行以下微积分,在第1个月我想做所有日子的平均值,例如:

在第1天第5天我有5个值5.33,4.57,5.33,5.59,4.32,所以我会这样做

(5.33 + 4.57 + 5.33 + 5.59 + 4.32)/ 5 = 5.028

而且我想在所有的日子里这样做,当我有所有的日子时,我会把它们全部加在一起,以了解当月的降水量,并在4个月内完成。

这就是程序应该如何运作,我已经用这段代码完成了这个:

Result        = matprec();
month1Indices = Result(:,3) == 1;
month1Rows    = Result(month1Indices, :);
day5Indices   = month1Rows(:,4) == 5;
day5Rows      = month1Rows(day5Indices , :);
  mean(day5Rows(:,5));

Result2        = matprec();
month1Indices2 = Result2(:,3) == 1;
month1Rows2    = Result2(month1Indices2, :);
day5Indices2  = month1Rows2(:,4) == 30;
day5Rows2      = month1Rows2(day5Indices2 , :);
  mean(day5Rows2(:,5));

  mes1 = mean(day5Rows(:,5)) + mean(day5Rows2(:,5));

lol = [mes1, mes2, mes3, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
  plot(x,lol);

但这只适用于第一个月,所以我正在尝试做一个循环来完成所有月份和所有的一天并绘制它,我有这个,但它只是永远地继续:

a = 1
b = 1
while (a <= 4 && b <= 30)
Result        = matprec();
month1Indices = Result(:,3) == a;
month1Rows    = Result(month1Indices, :);
day5Indices   = month1Rows(:,4) == b;
day5Rows      = month1Rows(day5Indices , :);
  mean(day5Rows(:,5))
  x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
  plot(x,mean(day5Rows(:,5)));
  endwhile

Sory我知道它有点长,但我需要解释一下,谢谢。

2 个答案:

答案 0 :(得分:0)

我重写了一下,因为我认为你通过使用这么多不同的变量和数值的硬编码来过度复杂化。通常,更容易提取您所需的内容:

months = res1(:, 3);
prec = res1(:, 5);

m_start = 1; # month where to start averaging
m_end = 4;   # month where to end averaging

# prepare output vector
avg = zeros(m_end - m_start + 1, 1);

for m = m_start:m_end
    temp = prec(months == m);
    avg(m) = mean(temp);
end

plot(avg)
grid

在您的示例中,您只使用了非零值,这是有意的吗?如果你想要这种行为,我建议使用一个小的epsilon值作为阈值:

for m = m_start:m_end
    temp = prec(months == m);
    # --------------------------
    # ignore smaller values
    eps = 1e-12;
    temp = temp(temp > eps);
    # --------------------------
    avg(m) = mean(temp);
end

答案 1 :(得分:0)

您描述的计算有点令人困惑。我假设第一步是确定一个月内每天的平均降水量(在车站上取平均值)

mean_precipitation = accumarray([res1(:,3), res1(:,4)], res1(:,5), [], @mean);

矩阵的每一行对应一个月,每列一天。 accumarray函数执行您在循环中执行的大部分工作。第一个参数[res1(:,3), res1(:4)]是一个两列矩阵,其中第一列指定月份(行),第二列指定每个“累积”结果所属的日期(列)。第二个参数res1(:,5)是每个最终结果中“累积”的值,最后一个参数@mean是应用于每个月日数据集合的累积函数的类型。有关替代说明(或谷歌)的信息,请参阅help accumarray - 最初它的工作原理可能有点令人困惑。

计算中的下一步有两种不同的解释。

一个月的雨天平均降雨量

如果您想要一个月内 降水的天数的平均降水量,那么:

sum(mean_precipitation, 2) ./ sum(mean_precipitation > 0, 2)

ans =

   17.8790
    1.5627
   14.3677
       NaN

这将给出最后一个月的NaN,因为没有记录降水的天数,因此没有定义平均值。

一个月内所有日子的平均降水量

如果您想要本月所有天的平均降水量,那么您需要计算每个月的天数。这可以通过eomday()找到(我假设所有观察都在2001年),那么计算就是

sum(mean_precipitation, 2) ./ eomday(2001, (1:size(mean_precipitation, 1))')

ans =

   1.15348
   0.11162
   0.92695
   0.00000

希望这能为您提供有关如何执行计算的一些想法。

为什么没有while循环?

虽然循环是一种较旧的命令式编写代码。有时它们对于清晰度是有用的,但有时它们比使用可能“计算”计算的已建立函数要慢(参见Why does vectorized code run faster than for loops in MATLAB?