【问题标题】:How to calculate values using for-end and if-else in Octave?如何在 Octave 中使用 for-end 和 if-else 计算值?
【发布时间】:2021-03-25 14:52:41
【问题描述】:

我需要在以下等式中计算变量Nfj:

ea_M = (sf/E)*(2*Nfj)^b + ef*(2*Nfj)^c

使其等于ea 的 4 个不同值:5.0900e-04、4.3626e-04、3.6358e-04 和 2.9084e-04。结果应该是Nfj 的4 个值,应该存储在results 中。我之所以四舍五入是因为我认为不可能计算出完全相等的 ea 值,如果不四舍五入,则等式总是错误的。

我为它编写了这段代码,但它没有按预期工作:脚本运行了很长时间没有任何结果。如何修复它以使其正常工作?

sf = 882.07;
ef = 0.59;
b = -0.102969;
c = -0.58;
E = 210000;
ea = [5.0900e-04; 4.3626e-04; 3.6358e-04; 2.9084e-04]

for pos = 1:length(ea)
  for Nfj = 1e3:10:1e12
    ea_M = (sf/E)*(2*Nfj)^b + ef*(2*Nfj)^c;
    if  round(ea_M * 10^5)/10^5 == round(ea(pos) * 10^5)/10^5;
      disp(ea_M)
      disp(Nfj)
      results(pos) = Nfj;
    end
  end
end

【问题讨论】:

  • 你没有使用你的Nfj变量,所以ea_M应该总是一样的。
  • 所以我遵循,而不是计算 Nfj,而是逐步遍历所有可能的 Nfj,并将其与实际计算的值进行比较,然后如果 Nfj 接近于您计算的值,则存储该 Nfj。它看起来有点低效,因为您要进行十亿次迭代才能获得四个值。我看到的一个具体问题是 ea_M 行 (sf E Ns b ef c) 中的任何变量看起来都不会在您通过循环时以任何方式发生变化,所以如果这些输入没有改变,您每次出现该行时,都会得到相同的 ea_M。
  • 您好,我已经根据您的cmets更正了脚本。原始脚本中的 Ns 应该是 Nfj。不幸的是,脚本运行了很长时间而没有结果,因此欢迎提出任何改进建议。非常感谢您的帮助!
  • 所以你无法解出Nfj 的方程?试试数值求解器怎么样?蛮力尝试Nfj 的所有可能值将非常低效,并且您可能会跳过使相等起作用的实际值(您尝试每 10 个值,然后四舍五入到小数点后 5 位,你看到了吗?每尝试一次Nfj 就会增加 1e-5?)
  • 您好 Cris,我没有在 Octave 中求解此类方程的经验。我知道我的方法可能效率低下,但我不知道更好的方法。你能告诉我如何用 Octave 中的数值求解器来解决它吗?

标签: octave


【解决方案1】:

您正在尝试每 10th 个值,从 103 到 1012:有 1011值在这里试试!这当然很多。您将一直在搜索,并且您可能会跳过使等式成立的实际值。

如果您无法手动求解方程,您可以使用数值求解器。我们先打印函数:

sf = 882.07;
ef = 0.59;
b = -0.102969;
c = -0.58;
E = 210000;

ea_M = @(Nfj) (sf/E)*(2*Nfj).^b + ef*(2*Nfj).^c;

Nfj = logspace(3,12,1000);
plot(Nfj, ea_M(Nfj))
set(gca, 'xscale', 'log')

看起来这个函数很单调,你正在寻找的四个值在你正在搜索的 103 到 1012 的区间内。要找到它等于您的值之一的位置,我们可以减去该值并找到它等于零的位置。如果从函数大于零的点和小于零的点开始,您可以非常快速地缩小搜索范围。您每次将间隔减半,保留包含过零的间隔的一半。 fzero 函数就是这样做的。

ea = [5.0900e-04; 4.3626e-04; 3.6358e-04; 2.9084e-04];
results = zeros(size(ea));
for pos = 1:numel(ea)
   results(pos) = fzero(@(Nfj) ea_M(Nfj) - ea(pos), [1e3,1e12]);
end
results

在 MATLAB 中,此代码在几分之一秒内运行并输出:

results =

   1.0e+10 *

    0.0429
    0.1849
    1.0627
    9.1919

而ea_M(results) - ea 大约为零。


关于我在此处发布的代码的几点说明:

  1. ea_M 被定义为匿名函数。这使得重用表达式更容易,而不是一遍又一遍地编写它。我将^ 替换为.^ 以允许此函数一次对Nfj 值的数组进行计算,而不仅仅是单个值。这是fzero 调用所必需的。

  2. 我在对数刻度上绘制了函数,因为这个函数需要它。并非所有功能都如此。

  3. 我预先分配了results 数组,你应该避免在循环中增加数组的大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多