Given two points fit a curve
Show older comments
I am wondering if the following could be done.
I have two points an origin and a final point, Lets call them (xo,yo) and (xn,yn). I am trying to fit a number of different curves (all of which have to be monotonic).
Curves could be exponential, logistic, parabolic, straigth line, etc. I just was wondering if there was a fast and easy way to do this.
Thanks
Answers (3)
Image Analyst
on 24 Oct 2014
0 votes
Did you look up interpolation in the help? There are a number of functions to do this, such as polyfit, nlfit, etc. I attach polyfit and spline fit examples.
Star Strider
on 24 Oct 2014
0 votes
If two points (and no other data) are all you have, you can at best ‘fit’ a straight line between them.
4 Comments
Juan
on 24 Oct 2014
Star Strider
on 24 Oct 2014
My pleasure!
For a parabola, (quadratic) that is actually a relatively straightforward calculation:
x = [1 5]; % Define Points
y = [3 7];
xm = @(x) [x'.^2 x' ones(size(x))']; % Quadratic Regression Matrix
b = xm(x)\y'; % Estimate Parameters
xc = linspace(min(x)-1,max(x)+1); % Create X-Value Vector
yc = xm(xc)*b; % Calculate Y-Values
figure(1)
plot(xc,yc,'-b', x,y,'pr')
grid
You can adapt the ‘xm’ function (creates the regression matrix and then is used to calculate the curve) for any other function that can be expressed as a function that is linear in the parameters, as this is. The rest of the code doesn’t change.
My issue is that I know I can fit a straight line but I also want to fit a parabola o some other type of curve.
Just as an FYI, this is ill-posed. There are infinitely many parabola that will fit two points. A line is a special case of a parabola, so with the line you really already had a parabolic fit to begin with! You might need additional requirements so that the parabola is uniquely specified.
Also, Strider's solution does not ensure monotonicity, as required in the post. You need to impose the constraint
-b(2)/2*b(1)>=xn if yn>y0
-b(2)/2*b(1)<=x0 if yn<y0
Star Strider's solution can be modified by rewriting these as linear constraints as below, and using lsqlin.
yn>y0:
b(1)>=0
2*b(1)*xn + b(2) <= 0
yn<y0:
b(1)<=0
2*b(1)*x0 + b(2) <= 0
The main problem is enforcing monotonicity, or equivalently keeping the derivative of the function continuously positive or negative over the interval [x0,xn]. You can use fseminf to do this, if you need to stay generic, and if you have the Optimization Toolbox. So, if f(p,x) is the family of functions you're searching over (parabolic, exponential, etc...) with parameter vector, p, and similarly df(p,x) is the derivative of f with respect to x, then you can constrain the sign of the derivative using the seminfcon argument as below,
f=@myFamily; %functions of (p,x)
df=@myFamilysDerivative;
cost=@(p,x) (f(p,x0)-y0)^2 + (f(p,xn)-yn)^2;
[x,fval] = fseminf(cost, p0, 1, @(p,S) myinfcon(p,S,x0,xn,y0,yn))
function [c,ceq, K1] = myinfcon(p,S,x0,xn,y0,yn)
c=[]; ceq=[];
if isnan(S)
S=[(xn-x0)/10, 0];
end
w=x0:s:xn;
K1=sign(y0-yn)*dfp(p,w);
end
This allows you to fit a generic differentiable f(x,p). It would better, of course, to use a routine customized to each particular family you are interested in. For example, the SLM toolbox ( Download ) allows you to do monotonic curve fits customized to splines.
Categories
Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!