using lsqnonlin () for solution of an nonlinear equation

1 Ansicht (letzte 30 Tage)
KB
KB am 26 Jul. 2014
Bearbeitet: KB am 1 Aug. 2014
Please consider the following code:
function diff = myfun(D,Y)
t = 0:30:600;
l = length(t);
a = 0.5*0.75*10^(-4);
for i = 1:l
Yp(i)=0;
for n = 1:10
y(i,n) = exp(-D*t(i)*(pi^2)*(n^2)/(a^2))/n^2;
Yp(i) = Yp(i) + y(i,n);
end
end
diff = 1- (6*Yp/pi^2)-Y;
%function
Y = [0.0566 0.4432 0.5539 0.6783 0.7303 0.3569 0.4001 0.4278 0.4499 0.4720 ...
0.4500 0.5157 0.5237 0.5492 0.5590 0.5799 0.5890 0.6000 0.6150 0.6300...
0.6450];
D0 = 2.0*10^(-12);
options=optimset('LargeScale','on','Display','iter','MaxFunEvals',1e20,'TolFun',2e-50,'TolX',2e-50,'LevenbergMarquardt','on');
[D,resnorm,residual,exitflag,output,lambda]=lsqnonlin(@myfun,D0,[],[],options);
I am trying to get D value using the lsqnonlin() but I am getting the message:
Error using ==> feval
Undefined function or method 'diffusion' for input arguments of type 'double'.
Error in ==> lsqnonlin at 200
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. LSQNONLIN cannot continue.
Please help me with the code why I am getting this error message. What could be the better possible way to obtain the solution for D value.

Akzeptierte Antwort

Matt J
Matt J am 26 Jul. 2014
Bearbeitet: Matt J am 26 Jul. 2014
I suspect that the code you are running is not the code you have shown. The posted myfun(D,Y) takes 2 arguments, but you are not passing a value for Y to myfun in any way. MATLAB should be complaining that Y is missing, unless your call to lsqnonlin looks something like this,
[D,resnorm,residual,exitflag,output,lambda]=lsqnonlin(@(D) myfun(D,Y), D0,[],[],options);
Also, if D is a scalar, it would be probably be much simpler to use fminsearch instead of lsqnonlin to minimize norm(diff).
  17 Kommentare
Matt J
Matt J am 30 Jul. 2014
Bearbeitet: Matt J am 30 Jul. 2014
Your code, and its output, are difficult to read. You should use the
button to format it distinctly from your text (like my posted code appears). In any case, the code you've shown is not what I ran. I'm still applying lsqnonlin to the scaled version of the problem:
fun=@(D)diffusion(D,Y);
[Dsc,Resnorm]=lsqnonlin(@(Dsc) fun((1e-10)*Dsc),D0,0,[],options);
D=Dsc*1e-10;
KB
KB am 1 Aug. 2014
Bearbeitet: KB am 1 Aug. 2014
Thanks Matt. You have been really awesome. Could you help me out with this data set:
and I am using similar code:
function diff = kani(D,Y)
t = 0:120:7200;
l=length(t);
a = 0.5*0.75*10^(-4);
for i = 1:l
Yp(i)=0;
for n = 1:10
y(i,n) = exp(-D*t(i)*(pi^2)*(n^2)/(a^2))/n^2;
Yp(i) = Yp(i) + y(i,n);
end
end
y;
Yp;
diff = 1- (6*Yp/pi^2)-Y;
Y = [ 0 0.0035 0.0066 0.0091 0.0121 0.0143 0.0150 0.0161 0.0167 0.0174 0.0188 0.0197 0.0199 0.0210 0.0218 0.0226 0.0229 0.0226 0.0237 0.0247 0.0244 0.0262 0.0249 0.0252 0.0248 0.0267 0.0285 0.0272 0.0279 0.0277 0.0292 0.0294 0.0289 0.0301 0.0282 0.0285 0.0299 0.0285 0.0304 0.0306 0.0309 0.0315 0.0317 0.0310 0.0310 0.0304 0.0339 0.0326 0.0320 0.0323 0.0335 0.0312 0.0332 0.0333 0.0316 0.0311 0.0315 0.0307 0.0313 0.0312 0.0328];
fun=@(D)kani(D,Y);
D0 = 0;
options = optimset('Display','iter','MaxFunEvals',1e20,'TolFun',2e-50,'TolX',2e-50);
[Dsc,Resnorm]=lsqnonlin(@(Dsc) fun((1e-10)*Dsc),D0,0,[],options);
D=Dsc*1e-10
Resnorm
D_interval=linspace(0,2*D,1000);
plot(D_interval, arrayfun(@(D)norm(fun(D))^2,D_interval));
xlabel 'D'
ylabel 'norm(diff)^2' }
and this is what I got:
I have tried to solve this by scaling the D value very low e^(-20), but still not getting it.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by