Matlab

Moderators: None (Apply to moderate this forum)
Number of threads: 1471
Number of posts: 2147

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Problem with FMINCON, please help! Posted by eribold on 14 Apr 2009 at 6:40 AM
Hi,

I am trying to use FMINCON to solve a fitting problem. I cannot use the fitting toolbox since I want the fit to pass through a specific point, and after trying a lot I realized reading several posts that this is not possible.

However, I am not able to solve the problem with FMINCON either.
Here is what I need to do.

I have two column vectors

xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71]
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424, 0.137]

and I need the fitting to pass through the point xdata(5,1) ydata(5,1) that is (-0.0076 , 0.1424).

I must use a custom objective function, which is given by

ydata= z*(1+beta(1)*xdata+beta(2)*xdata.^2)

where z=ydata(5,1)=0.1424

Could someone help me out on this?

Thanks a lot in advance

Report
Re: Problem with FMINCON, please help! Posted by giug on 14 Apr 2009 at 7:51 AM
I'm not sure that is not possible to use a simple fit function. I try to explain my idea, tell me if I am wrong.

You have to find a fit function that depends on two variables (beta1 and beta2). y= 0.1424*(1+beta(1)*x+beta(2)*x.^2)
You have a constraint: the fitting curve have to pass through a specific point (let's name it (xc yc)). This give you a condition on beta1 and beta2:
yc= 0.1424*(1+beta(1)*xc+beta(2)*xc.^2)

0.1424=0.1424*(1+beta(1)*(-0.0076)+beta(2)*(-0.0076).^2)

so you can write beta1 as function of beta2. I try to compute manually (but probably I'm wrong) and I found: beta1=-xc*beta2.

So, now, the initial function become:
y= 0.1424*(1+(0.0076*beta2)*x+beta2*x.^2)

You can use the fittype function to tell to matlab what is the function for fitting:

f = fittype('0.1424*(1+(0.0076*beta1)*x+(beta1)*x^2)');

it recognize by itself that beta1 is the free parameter and x the independent variable.

Now, let's fit...
[c2,gof2] = fit(xdata,ydata,f);
and plot...
figure()
plot(xdata,ydata,'*')
hold on
plot(c2)

I resume all the code:

xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71];
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424; 0.137];
f = fittype('0.1424*(1+(0.0076*beta1)*x+(beta1)*x^2)');
[c2,gof2] = fit(xdata,ydata,f);
figure()
plot(xdata,ydata,'*')
hold on
plot(c2)


It runs and it gives me a good result. I hope it is what you want.

Report
Re: Problem with FMINCON, please help! Posted by eribold on 14 Apr 2009 at 8:15 AM
hi!

first of all, thanks a lot for the help!

I tried your code and it gives me the following result:
In fit>handlewarn at 714
In fit at 328
??? Index exceeds matrix dimensions.

Error in ==> cfit.plot at 67
ydata = ydata(idx);

moreover, i do not know whether I can use this approach because in fittype('0.1424*(1+(0.0076*beta1)*x+(beta1)*x^2)') the first 0.1424 is actually something that I have to take from a variable since this is all a part of a code which will go inside a loop: basically I will have to do 1000 iterations where everytime xdata and ydata will change and everytime the first part (the 0.1424) will be taken as a cell inside ydata.
so basically instead of the number I will have to put the name of the variable (which will contain a different number for every loop) and I don't know whether it will recognize that.



Report
Re: Problem with FMINCON, please help! Posted by giug on 14 Apr 2009 at 8:36 AM
I correct the error (in bold).
For the 0.1424 you can substitute it with z and initialize z in another part of the code:


xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71];
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424; 0.137];
z=ydata(5);
f = fittype('z*(1+(0.0076*beta1)*x+(beta1)*x^2)');
[c2,gof2] = fit(xdata,ydata,f);
figure()
plot(xdata,ydata,'*')
hold on
plot(c2)
Report
Re: Problem with FMINCON, please help! Posted by eribold on 15 Apr 2009 at 12:48 AM
ok now it works, but the problem is that, as I expected, it "fit" treats z as a variable and it gives a value and confidence bounds for it as well!

moreover, the 0.0076 you have in your formula should itself be linked to a cell in ydata, so the program should be this:

xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71];
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424; 0.137];
z=ydata(5);
z2=xdata(5);
f = fittype('z*(1-(z2*beta1)*x+(beta1)*x^2)');
[c2,gof2] = fit(xdata,ydata,f);
figure()
plot(xdata,ydata,'*')
hold on
plot(c2)

and yes, it works, but if you look at in "c2" you'll see that z and z2 are treated as variables for the fitting procedure and the number that is written in them is not "read" by the optimizer. Am I wrong?

Indeed on the help for fittype you find: By default, the independent variable is assumed to be x and the dependent variable is assumed to be y. All other variables are assumed to be coefficients.

and I also tried to input the fact that I want only beta1 as the coefficient in "f = fittype('z*(1-(z2*beta1)*x+(beta1)*x^2)', 'coefficients',{'beta1'});"

but I got an error message

Thanks again
Report
Re: Problem with FMINCON, please help! Posted by giug on 15 Apr 2009 at 12:59 AM
Yes, you are right, sorry.

You have to specify it in the fit type (for the example I use only z as parameter):

xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71];
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424; 0.137];
z=ydata(5);
z2=xdata(5);
f = fittype('z*(1-(0.0076*beta1)*x+(beta1)*x^2)','problem','z');
[c2,gof2] = fit(xdata,ydata,f,'problem',z);
figure()
plot(xdata,ydata,'*')
hold on
plot(c2)

Tell me if it's ok. if you want to use also z2 you have to use a cell array, as the matlab help says.
Report
Re: Problem with FMINCON, please help! Posted by eribold on 15 Apr 2009 at 1:22 AM
Ok this works now, thanks a lot!

However I now see that in this way I will not get my desired result since putting that point passing through in the function as well is not entirely correct.

Let me explain myself: I still want the fitting function to pass through the point (y(5),x(5)) BUT the function in general form needs to be

ydata= beta(1)*(1+beta(2)*xdata+beta(3)*xdata.^2)

so that even if I insert one point I won't be able to use the same technique since I now have 3 unknowns. I could use two points, solve manually the linear system and to the same (but actually I am trying to do this without success since b1 multiplies everything), but I would rather prefer the curve to be constrained to go just through 1 point, so that it has more freedom. Is there any other way or now it is really possible only with fmincon (which I am not so good at)?
Report
Re: Problem with FMINCON, please help! Posted by giug on 15 Apr 2009 at 1:57 AM
In this case...
I solved the function, imponing the passing through the point, so that beta1 now is function of beta2 and beta3.
I found:
beta1=(0.1424/(1-0.0076*beta2+0.0076^2*beta3))

Then, I modified the code:
xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71];
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424; 0.137];
z=ydata(5);
z2=xdata(5);
f = fittype('(0.1424/(1-0.0076*beta2+0.0076^2*beta3))*(1-beta2*x+beta3*x^2)');
c2 = fit(xdata,ydata,f)
figure()
plot(xdata,ydata,'*')
hold on
plot(c2)

In this way it find the coefficients beta2 and beta3.

Something wrong?
Report
Re: Problem with FMINCON, please help! Posted by eribold on 15 Apr 2009 at 4:08 AM
Yes now it works perfectly, thanks a lot!!

Last question: is there a way (which would be above my expectations) with this method to minimize not the mean squared error but a "volume weighted mean squared error", where obviously I would have another vector jdata with all the volumes corresponding to the cells in xdata and ydata, let's say jdata= [100; 200; 300; 350; 1000; 900].

where volume weighted mean squared error is given by:

(SumOveri(Volume(i)*(ydata(i)-ymodel(i))^2))/(Sumoveri(Volume(i)))
Report
Re: Problem with FMINCON, please help! Posted by giug on 16 Apr 2009 at 2:00 AM
I think this is no possible with the fit function.
Report
Re: Problem with FMINCON, please help! Posted by eribold on 16 Apr 2009 at 5:42 AM
Ok i think to have solved it with the backslash method:

xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71];
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424; 0.137];

%Volume
jdata= [100; 200; 300; 350; 1000; 900];
sum = 0.0
for i = 1:size(jdata,1)
sum = sum + jdata(i,1)
end
for i = 1:size(jdata,1)
coeff(i,1) = sqrt(jdata(i,1)/sum)
end
% Create Design matrix
for i = 1:size(xdata,1)
A(i,1) = coeff(i,1)*(xdata(i,1)-xdata(5,1))
A(i,2) = coeff(i,1)*(xdata(i,1)^2-xdata(5,1)^2)
end
% Create vector of the right hand side
for i = 1:size(ydata,1)
b(i,1) = coeff(i,1)*(ydata(i,1)-ydata(5,1))
end
% Solve linear system A*beta = b to get regression
% coefficients
% !MATLAB command
beta = A\b
beta1=ydata(5,1)-beta(1,1)*xdata(5,1)-beta(2,1)*xdata(5,1)^2;
beta2=beta(1,1)/beta1;
beta3=beta(2,1)/beta1;

however now i have a problem: in this way I do not get the values for

sse
r-squared
adj r-squared
rmse

as i would get with the fit function. how can i calculate them manually?

Report
Re: Problem with FMINCON, please help! Posted by giug on 16 Apr 2009 at 6:46 AM
I don't know if you read your mailbox. If you have a vector with weights you can use it in the fit function. So, have you a vector with the weights?
Report
Re: Problem with FMINCON, please help! Posted by giug on 16 Apr 2009 at 8:43 AM
This is the code:

xdata= [-4.22; -3.64; -3.35; -2.79; -0.0076; 1.71];
ydata= [0.34; 0.28; 0.26; 0.25; 0.1424; 0.137];
jdata= [100; 200; 300; 350; 1000; 900];
z=ydata(5);
z2=xdata(5);
options = fitoptions('Weights',jdata);
f = fittype('(0.1424/(1-0.0076*beta2+0.0076^2*beta3))*(1-beta2*x+beta3*x^2)');
c2 = fit(xdata,ydata,f,options);
figure()
plot(xdata,ydata,'*')
hold on
plot(c2)
Report
Re: Problem with FMINCON, please help! Posted by eribold on 16 Apr 2009 at 9:41 AM
that's perfect!!! thanks a lot!!
Report
Re: Problem with FMINCON, please help! Posted by giug on 19 Apr 2009 at 2:57 AM
To specify the starting point you have to modify a bit the code:

options1 = fitoptions('Weights',jdata);
f = fittype('(0.1424/(1-0.0076*beta2+0.0076^2*beta3))*(1-beta2*x+beta3*x^2)');
options.StartPoint=[1 1];
c2 = fit(xdata,ydata,f,options1);

I modified options in options1 because options is a reserved word and now that you have to use it give you some problems.
The code above runs well.



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.