迭代求解流体问题中的未知数

时间:2010-12-14 17:08:19

标签: algorithm

我是一名有计算机科学家问题的机械工程师。这是我正在使用的方程式的例子:

  

x =√((y-z)×2 / r)
  z = f×(L / D)×(x / 2g)
  f = x中有一些疯狂的东西
  等...(有更多的方程式,其中包含x)

情况如下:

我需要r找到x,但我需要x来找到z。我还需要x来找到f,这是找到z的一部分。所以我猜x的值,然后我用这个值来找到r和f。然后我回去使用我找到的r和f的值来找到x。我一直这样做,直到猜测和计算结果相同。

我的问题是:

如何让计算机执行此操作?我一直在使用mathcad,但是像C ++这样的另一种语言的例子很好。

5 个答案:

答案 0 :(得分:2)

你应该面对迭代算法做的第一件事就是在纸上写下 你想法产生的序列:

例如:

 x_0 = ..., f_0 = ..., r_0 = ...
 x_1 = ..., f_1 = ..., r_1 = ...

 ...

 x_n = ..., f_n = ..., r_n = ...

现在,您已了解应该实施的内容(即使您不知道如何)。如果您无法找到x_i,r_i或whatever_i之一的闭合表单表达式,则需要以数字方式求解一维方程。这将意味着更多的工作。

现在,对于实施部分,如果你从未写过一个程序,你应该认真地问一个可以帮助你的人(或者雇用一名实习生并让他编写代码)。我们无法帮助您从头开始,例如。 C编程,但我们愿意帮助您解决编写程序时出现的特定问题

请注意,即使您强烈认为有独特的解决方案,也无法保证您的算法收敛。解非线性方程是一个难题。

答案 1 :(得分:1)

似乎mathcad有许多迭代算法的抽象,而不需要使用“低级”语言直接实现它们。也许这个问题更适合于mathcad论坛:

http://communities.ptc.com/index.jspa

答案 2 :(得分:1)

如果您使用的是Mathcad,则它具有内置功能。它被称为 solve block

以关键字“given”开头

<强>鉴于

定义所有未知数的猜测值

<强> X:= 2 F:= 3 R:= 2 ...

定义你的约束

x =√((y-z)×2 / r)

z = f×(L / D)×(x / 2g)

f =其中有一些疯狂的东西

等......(其中有更多的x方程式)

计算解决方案

find(x,y,z,r,...)=

检查Mathcad帮助或Quicksheets以获取确切语法的示例。

答案 3 :(得分:1)

您的问题的简单答案是这个伪代码:

X = startingX;
lastF = Infinity;
F = 0;
tolerance = 1e-10;
while ((lastF - F)^2 > tolerance)
{
    lastF = F;
    X = ?;
    R = ?;
    F = FunctionOf(X,R);
}

这可能根本不符合您的期望。它可能会给出一个有效但无意义的答案,或者它可能会在不同的错误答案之间无休止地循环。

这是收敛的标准替代。有更多高级技术,如DIIS,但我不确定你是否想去那里。我发现这篇文章的同时弄清楚我是否想去那里。

一般来说,考虑如何将问题转化为更容易的问题确实是值得的。

根据我的经验,最好将您的问题视为单变量有界根发现问题,如果可以,请使用Brent's Method

下一个最差的选择是使用类似BFGS的多变量最小化。

迭代解决方案很糟糕,但是一旦你把它们想象为X2 = f(X1),其中X是输入向量而你试图减少X1和X2之间的差异,就更容易解决了。

答案 4 :(得分:0)

正如评论者所指出的那样,你的问题的数学方面超出了你在这里所期望的帮助的范围,甚至超出了你根据你发布的细节提供的帮助。

但是,我认为,即使你彻底理解了数学,你的问题还有计算机科学方面的问题需要解决。

编写代码时,请尝试将其组织为仅依赖于传递给子例程的参数的函数。所以编写一个子程序,它接受y,z和r的值并返回x。制作另一个接收f,L,D,G并返回z。现在您有可测试的例程,您可以检查以确保它们正确计算。检查例程中的例程的输入值 - 例如,在计算x时,如果为r传入0,则将得到除以0的错误。想想你想如何处理这个问题。

如果要以交互方式解决此问题,则需要一种方法,根据一次迭代的结果,决定下一次迭代的值是什么。这也应该封装在子程序中。现在,如果您使用的语言只允许从子例程(最常见的计算语言C,C ++,Java,C#)返回一个值,则需要将所有变量打包成某种数据结构以返回它们。您可以使用实数或双精度数组,但选择创建对象会更好,然后您可以通过名称而不是位置来引用变量(错误的可能性更小)。

迭代的另一个方面是知道何时停止。当你得到一个收敛的解决方案时,你肯定会这样做。将此决定转换为另一个子例程。现在,当您需要更改收敛条件时,代码中只有一个位置可供使用。但是你需要考虑停止的其他原因 - 如果你的解决方案开始出现分歧而不是收敛,你会怎么做?放弃之前允许运行多少次迭代?

计算机迭代的另一个方面是舍入误差。数学上10 ^ 40/10 ^ 38是100.数学上10 ^ 20 + 1&gt; 10 ^ 20。在大多数计算中,这些陈述都不正确。您的计算可能需要考虑到这一点,否则您最终会得到垃圾数字。这是一个跨领域问题的例子,它不适合在子程序中封装。

我建议你去看看Python语言和pythonxy.com扩展。相关论坛中的人员可以帮助您学习如何迭代求解方程组。