2016-12-27 5 views
0

私はこれらのスクリプトで与えられた最小限の方程式を見つけたいと思います。それは非常に乱雑に見えている(しかし、式の深いundestandingは必要ない - 私が推測する)。 defの終わりに式が最小にすることです:scipy.optimize.least_squaresとmatlab lsqnonlinの相違点

vys1=-Qd-40*sqrt(5)*sqrt((ch+cm)*ep*kb*Na*T)*w1 
vys2=fi0-fib-Q0/cq 
vys3=fib-fid+Qd/cq1 
vysf= np.array([vys1,vys2,vys3]) 
return vysf 

私は結果を比較するlsqnonlinを使用して、MATLABでこのスクリプトを記述します。 Matlabの結果は非常に正確です。結果結果​​のために(彼らはPythonとMATLABで同一である場合)(FI0、FIB、FID)

Python 
[-0.14833481 -0.04824387 -0.00942132] Sum(value) ~1e-3. 
Matlab 
[-0,13253 -0,03253  -0,02131 ] Sum(value)~1e-15 

注意がそのスクリプトが式のタイプミスのチェックを持っている ある同じ[vys1,vys2,vys3]ある -

python [0.00069376 0.05500097 -0.06179421] 
matlab [0.0006937598,0.05500096 -0.06179421] 

結果を改善するためのオプションがleast_squaresにありますか?任意の助けてくれてありがとう(英語誤解のために残念)

Pythonの

import scipy as sc 
import numpy as np 
from math import sinh 
import matplotlib as plt 
from numpy import exp, sqrt 
from scipy.optimize import leastsq,least_squares 

def q(par,ep,Na,kb,T,e,gamaal,gamasi,gamax,k1,k2,k3,k4,cq,cq1,ch,cm): 
    fi0,fib,fid=np.array([par[0],par[1],par[2]]) 
    AlOH= gamaal*k1*exp(e*fi0/(T*kb))/(ch + k1*exp(e*fi0/(T*kb))) 
    AlOH2= ch*gamaal/(ch + k1*exp(e*fi0/(T*kb))) 
    SiO= gamasi*k2*exp(e*fi0/(T*kb))/(ch + k2*exp(e*fi0/(T*kb))) 
    SiOH= ch*gamasi/(ch + k2*exp(e*fi0/(T*kb))) 
    X= gamax*k3*k4*exp(e*fib/(T*kb))/(ch*k4 + cm*k3 + k3*k4*exp(e*fib/ (T*kb))) 
    XH= ch*gamax*k4/(ch*k4 + cm*k3 + k3*k4*exp(e*fib/(T*kb))) 
    Xm= cm*gamax*k3/(ch*k4 + cm*k3 + k3*k4*exp(e*fib/(T*kb))) 
    Q0=e*(0.5*(AlOH2+SiOH-AlOH-SiO)-gamax) 
    Qb=e*(XH+Xm) 
    Qd=-Q0-Qb 
    w1=sc.sinh(0.5*e*fid/kb/T) 
    vys1=-Qd-40*sqrt(5)*sqrt((ch+cm)*ep*kb*Na*T)*w1 
    vys2=fi0-fib-Q0/cq 
    vys3=fib-fid+Qd/cq1 
    vysf= np.array([vys1,vys2,vys3]) 
    return vysf 

kb=1.38E-23;T=300;e=1.6e-19;Na=6.022e23;gamaal=1e16;gamasi=1e16 
gamax=1e18;k1=1e-4;k2=1e5;k3=1e-4;k4=1e-4;cq=1.6;cq1=0.2 
cm=1e-3;ep=80*8.8e-12 
ch1=np.array([1e-3,1e-5,1e-7,1e-10]) 

# Check the equations, if they are same 
x0=np.array([-0.120, -0.0750 ,-0.011]) 
val=q(x0,ep,Na,kb,T,e,gamaal,gamasi,gamax,k1,k2,k3,k4,cq,cq1,ch1[0],cm) 
print(val) 
w1=least_squares(q,x0, args=(kb,ep,Na,T,e,gamaal,gamasi,gamax,k1,k2,k3, 
          k4,cq,cq1,ch1[0],cm)) 
print(w1['x']) 

MATLAB

function[F1,poten,fval]=test() 
kb=1.38E-23;T=300;e=1.6e-19;Na=6.022e23;gamaal=1e16;gamasi=1e16;gamax=1e18; 
k1=1e-4;k2=1e5;k3=1e-4;k4=1e-4;cq=1.6;cq1=0.2;ch=[1e-3];cm=1e-3;ep=80*8.8e- 12; 
% Test if equation are same 
x0=[-0.120, -0.0750 ,-0.011]; 
F1=rovnica(x0,ch) ; 
[poten,fval]= lsqnonlin(@(c) rovnica(c,ch(1)),x0); 
function[F]=rovnica(c,ch) 
fi0=c(1); 
fib=c(2); 
fid=c(3); 
aloh=exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*gamaal.*k1.*(ch+exp(1).^(e.* ... 
fi0.*kb.^(-1).*T.^(-1)).*k1).^(-1); 
aloh2=ch.*gamaal.*(ch+exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*k1).^(-1); 
sioh=ch.*gamasi.*(ch+exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*k2).^(-1); 
sio=exp(1).^(e.*fi0.*kb.^(-1).*T.^(-1)).*gamasi.*k2.*(ch+exp(1).^(e.* ... 
fi0.*kb.^(-1).*T.^(-1)).*k2).^(-1); 
Xm=cm.*gamax.*k3.*(cm.*k3+ch.*k4+exp(1).^(e.*fib.*kb.^(-1).*T.^(-1)) ... 
.*k3.*k4).^(-1); 
XH=ch.*gamax.*k4.*(cm.*k3+ch.*k4+exp(1).^(e.*fib.*kb.^(-1).*T.^(-1)) ... 
.*k3.*k4).^(-1); 
Q0=e*(0.5*(aloh2+sioh-aloh-sio)-gamax); 
Qb=e*(XH+Xm); 
Qd=-Q0-Qb; 
F=[-Qd+(-40).*5.^(1/2).*((ch+cm).*ep.*kb.*Na.*T).^(1/2).*sinh((1/2).*e.* ... 
fid.*kb.^(-1).*T.^(-1));... 
fi0-fib-Q0/cq;... 
(fib-fid+Qd/cq1)]; 
end 
end 
+1

コードのフォーマットを改善する必要があります。 – godaygo

+0

'' least_squares'が持つオプションのリストは、[ここ](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html)です。最も関連性が高いのは、公差オプションftol、gtol、xtolです。これらを減らすと、最小化の結果が向上することがあります。しかし、この場合ではありません。昨年の夏にSciPyに追加されたMATLABのlsqnonlinは、10年以上にわたりエンジニアリングチームの努力の恩恵を受けており、least_squaresよりも優れているようです。あなたはSciPyのリポジトリに問題をオープンしたいかもしれませんが、より簡単な機能を持つのは良いことです。 – FTP

+0

matlabとleast_squaresの両方の最適化メソッドはafaics trust-region-reflectiveなので、実際には大きなパフォーマンスの違いは期待できません。 Counterexampleは確かに見つけるのに非常に有用であろうが、ここでそれは原因が他のところにあるように見える。 –

答えて

2

この行に誤りがあります:

w1=least_squares(q,x0, args=(kb,ep,Na,T,e,gamaal,gamasi,gamax,k1,k2,k3, 
          k4,cq,cq1,ch1[0],cm)) 

あなたは引数を持っているがkb間違った場所でqの署名がある:

def q(par,ep,Na,kb,T,e,gamaal,gamasi,gamax,k1,k2,k3,k4,cq,cq1,ch,cm): 

引数kbNaTの間です。あなたはleast_squares呼び出しでargs引数を修正した場合:

w1 = least_squares(q, x0, args=(ep, Na, kb, T, e, gamaal, gamasi, gamax, 
           k1, k2, k3, k4, cq, cq1, ch1[0], cm)) 

は、Pythonスクリプトの出力は、Matlabの出力と一致する

[ 0.00069376 0.05500097 -0.06179421] 
[-0.13253313 -0.03253254 -0.02131043] 

です。

関連する問題