【问题标题】:Ocatave While loop八度While循环
【发布时间】:2017-04-06 02:59:38
【问题描述】:

我正在开发一个 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);

但这仅适用于第一个月,所以我正在尝试做一个 while 循环来为所有月份和整天执行此操作并绘制它,我有这个但它只是永远持续下去:

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

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

【问题讨论】:

  • a 和 b 在哪里递增?

标签: while-loop octave


【解决方案1】:

我重写了一点,因为我认为你使用这么多不同的变量和数值的硬编码使事情变得过于复杂。通常更容易准确地提取您需要的内容:

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

【讨论】:

  • 很抱歉没有回复我很忙,但我已经完成了程序,感谢您的回复和努力。 :)
【解决方案2】:

你描述的计算有点混乱。我假设第一步是确定一个月中每一天的平均降水量(各站的平均值)

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

矩阵的每一行对应一个月,每一列对应一天。 accumarray 函数完成了您在循环中所做的大部分工作。第一个参数[res1(:,3), res1(:4)] 是一个两列矩阵,其中第一列指定月份(行),第二列指定每个“累积”结果所属的日期(列)。第二个参数res1(:,5) 是“累加”到每个最终结果中的值,最后一个参数@mean 是应用于每个月-日数据收集的累加函数类型。请参阅 help accumarray 以获取替代描述(或 google) - 一开始它的工作方式可能会有点令人困惑。

对于下一步的计算,有两种不同的解释。

一个月内雨天的平均降水量

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

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?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 2020-09-23
    • 2017-06-04
    • 1970-01-01
    相关资源
    最近更新 更多