私は現在、Processing でいくつかの数値熱伝達計算を行っています。これには、相補誤差関数 (erfc) の適切な近似値が必要です。熱伝達方程式の 1 つは、exp(s^2) と erfc(s) の積で構成されます。これは、(s の値が大きい場合) 非常に大きな数に非常に小さな数を掛けることを意味します。このため、erfc の精度はかなり高くする必要があります。そうしないと、多数の s の計算が不安定になります。
Processing の数学関数 (sqrt()、exp()、pow() など) は double を使用できないため、float を使用していますが、s の値が大きい場合に安定性の問題が発生します。大きな値とは、約を意味します。例として、4.5 の erfc は 1.97*10^(-10) になります。
...そして質問へ。
1) 補完誤差関数値のより正確な表現を得るために、処理の数学関数 (平方根、指数、累乗など) で double を使用することは何とか可能ですか?
2) 私が知る限り、Python も float を使用しており、double ではありません。つまり、(少なくとも私の考えでは) Processing と Python は、補完的なエラー関数に対して同じ結果を取得する必要があります。しかし、そうではありません。Python は、Processing よりも正確な誤差関数の近似を行っています。どうすればいいの?
相補誤差関数近似の Python バージョンと処理バージョンを以下に示します。
パイソン:
from math import sqrt
from math import pi
from math import exp
n=1000 #number of intervals
b=float(1) #integration end
h=b/n #Interval width
leftRiemann=0
for s in range(0, n):
leftRiemann=leftRiemann+h*2/sqrt(pi)*exp(-((s*h)**2))
rightRiemann=0
for s in range(1, n+1):
rightRiemann=rightRiemann+h*2/sqrt(pi)*exp(-((s*h)**2))
trapez=0.5*leftRiemann+0.5*rightRiemann
centrePoint=0
for s in range(1, n+1):
centrePoint = centrePoint+h*2/sqrt(pi)*exp(-((h*(s-0.5))**2))
erfc=1 - (1.0/3*trapez+2.0/3*centrePoint)
print erfc
処理:
void setup() {
int n = 1000;
float b = 1;
float h = b/n;
float leftRiemann = 0;
for(int s=0; s<n; s++) {
leftRiemann = leftRiemann + h*2/sqrt(PI)*exp(-pow(s*h, 2));
}
float rightRiemann = 0;
for(int s=1; s<=n; s++) {
rightRiemann = rightRiemann + h*2/sqrt(PI)*exp(-pow(s*h, 2));
}
float trapez = 0.5*leftRiemann + 0.5*rightRiemann;
float centrePoint = 0;
for(int s=1; s<=n; s++) {
centrePoint = centrePoint + h*2/sqrt(PI)*exp(-pow(h*(s-0.5), 2));
}
float erfc = 1 - (trapez/3 + 2*centrePoint/3);
println(erfc);
}
Python: erfc(1) = 0.15729920705
処理: erfc(1) = 0.15729982
テーブル値: erfc(1) = 0.157299