函数向量化包含八度定积分的数值计算
Vectorization of function contains the numerical computation of definite integral in octave
我正在尝试使用一个公式来拟合我的数据,该公式包含具有无限积分极限的定积分的数值计算。为了拟合,我使用需要矢量化模型函数的八度函数 leasqr
。以下代码生成错误,在调用数值积分时发生。
参数不一致(op1 为 1x387,op2 为 10x2)
function [fGsAb] = GsAbs (x, p)
Hw = 3108.0 ;
fGsAb = Hw ./ (2.4 .* p(1) .*p(2)) .^2 .* (exp ( - (Hw - p(1) .* x) .^2 ...
./ (2.4 .* p(1) .*p(2)) .^2 ) - exp ( - (Hw + p(1) .* x) .^2 ...
./ (2.4 .* p(1) .*p(2)) .^2 )) ;
endfunction
function [GsDisp] = gauss_disp(x, p)
[GsDisp1, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
h = [200:15:6000];
pin =[1 250];
dd = gauss_disp (h, pin);
如果我使用循环:
for i = 1 : length (h)
dd (i) = gauss_disp (h (i), pin)
endfor
我没有错误,但是我不能在leasqr
中使用这个结构。我怎样才能绕过这个限制?
提前致谢!
更改您的 gauss_disp.m 文件:
function [GsDisp] = gauss_disp(x, p)
[GsDisp1, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
对此:
function [GsDisp] = gauss_disp(x, p)
GsDisp = arrayfun(@(z) gauss_disp_elementwise(z, p), x)
endfunction
function GsDisp = gauss_disp_elementwise(x, p)
[GsDisp1, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
即将您的原始函数变成仅处理标量值的辅助子函数,然后将其与 arrayfun
一起使用以获得整个 x
范围的输出。这样您就可以在 leasqr
函数中使用它,例如:
y = leasqr(h, dd, pin, @gauss_disp);
PS:arrayfun 语法只是为了方便。您可以轻松地使用类似于您在问题中使用的 for 循环。
我正在尝试使用一个公式来拟合我的数据,该公式包含具有无限积分极限的定积分的数值计算。为了拟合,我使用需要矢量化模型函数的八度函数 leasqr
。以下代码生成错误,在调用数值积分时发生。
参数不一致(op1 为 1x387,op2 为 10x2)
function [fGsAb] = GsAbs (x, p)
Hw = 3108.0 ;
fGsAb = Hw ./ (2.4 .* p(1) .*p(2)) .^2 .* (exp ( - (Hw - p(1) .* x) .^2 ...
./ (2.4 .* p(1) .*p(2)) .^2 ) - exp ( - (Hw + p(1) .* x) .^2 ...
./ (2.4 .* p(1) .*p(2)) .^2 )) ;
endfunction
function [GsDisp] = gauss_disp(x, p)
[GsDisp1, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
h = [200:15:6000];
pin =[1 250];
dd = gauss_disp (h, pin);
如果我使用循环:
for i = 1 : length (h)
dd (i) = gauss_disp (h (i), pin)
endfor
我没有错误,但是我不能在leasqr
中使用这个结构。我怎样才能绕过这个限制?
提前致谢!
更改您的 gauss_disp.m 文件:
function [GsDisp] = gauss_disp(x, p)
[GsDisp1, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
对此:
function [GsDisp] = gauss_disp(x, p)
GsDisp = arrayfun(@(z) gauss_disp_elementwise(z, p), x)
endfunction
function GsDisp = gauss_disp_elementwise(x, p)
[GsDisp1, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( @(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
即将您的原始函数变成仅处理标量值的辅助子函数,然后将其与 arrayfun
一起使用以获得整个 x
范围的输出。这样您就可以在 leasqr
函数中使用它,例如:
y = leasqr(h, dd, pin, @gauss_disp);
PS:arrayfun 语法只是为了方便。您可以轻松地使用类似于您在问题中使用的 for 循环。