Create similar curves through specific data points

10 次查看(过去 30 天)
Hi,
I have the following curve in green which can be created by using the data point in the attachment.
I want to create similar shaped curves where each of them runs through the two fixed data points at P1(0/0) and P2 (-31.5,30) but with a slight offset to each other. So all curves basically cross each other and start at P1 and rund through P2. I understand that in theory there are unlimited options. How would you do that?

采纳的回答

John D'Errico
John D'Errico 2025-3-4
编辑:John D'Errico 2025-3-4
The question is becoming more clear now, based on your response to my first answer. I'll post this as a separate answer, since things can often become lost in a thread of comments.
load xCommon.mat
load yAverage.mat
plot(xCommon,yAverage)
hold on
plot(-31.5,30,'rs')
hold off
grid on
You tell me you actually have a series of curves, all of which would pass through a known point at (-31.5,30).
What I need to point out first is that point at (x,y) = (-31.5,30) is not consistent with the shape of your curve. Just extrapolate that blue curve by eye, and you will see that. Perhaps you are mistaken, and you wanted it to lie at (-30,31.5) instead, which would be much closer.
Anyway, you want to identify a model that represents this basic shape. We see a derivative singularity at the right end point, so a point of infinite slope. At the left end, the curves all pass through that given point at (-31.5,30).
A basic curve shape that would represent this is a simple power law curve.
y = a*(x0 - x)^b
where b is less than 1, but greater than zero. For the data you have supplied, we would have x0 = 0.
max(xCommon)
ans = 0
You tell me the curve passes through the point (-31.5,30), but your data does not go down all the way to that point.
min(xCommon)
ans = -23
First, let me see if a simple power law curve does represent your data well.
mdlform = fittype('a*(-x)^b','indep','x')
mdlform =
General model: mdlform(a,b,x) = a*(-x)^b
mdl = fit(xCommon,yAverage,mdlform,'start',[1 0.5])
mdl =
General model: mdl(x) = a*(-x)^b Coefficients (with 95% confidence bounds): a = 6.995 (6.988, 7.001) b = 0.4552 (0.4548, 0.4555)
plot(mdl,xCommon,yAverage)
And that fits your data actually pretty well. How well does it extrapolate on the left to the point at x=-31.5?
mdl(-31.5)
ans = 33.6335
It misses that point by a little, but not a lot. Unfortunately, if I try to force that model to pass through the point at (-31.5,30), the model no longer fits your data.
We can do better if we swap the axes. That is, fit xCommon as a function of yAverage.
mdlform2 = fittype('a*x^2 + b*x^3 + c*x^4','indep','x')
mdlform2 =
General model: mdlform2(a,b,c,x) = a*x^2 + b*x^3 + c*x^4
mdl2 = fit(yAverage,xCommon,mdlform2)
Warning: Start point not provided, choosing random start point.
mdl2 =
General model: mdl2(x) = a*x^2 + b*x^3 + c*x^4 Coefficients (with 95% confidence bounds): a = -0.0255 (-0.02553, -0.02547) b = 0.0003413 (0.0003384, 0.0003442) c = -1.464e-05 (-1.47e-05, -1.457e-05)
plot(mdl2,yAverage,xCommon)
And there we see that your data and the curve as fit overlay nearly perfectly. The curve also has the property of a derivative singularity at x==0, due to the model I chose, f we go back, and swap the axes to the original.
The flaw is, the data you have suppied is not consistent with a point on that curve at (-31.5,30). Instead, this model strongly suggests that when y=30, x should be around -25.6. Again, the data you gave us is not consistent with your goals.
In either case though, we can find a curve that seems to reasonably represent that data, and has roughly the desired shape.

更多回答(2 个)

Walter Roberson
Walter Roberson 2025-3-3
x1 = -23;
y1 = 28;
x2 = -12;
syms y2
x3 = 0;
y3 = 0;
syms a b c
eqn1 = a*x1^2 + b*x1 + c == y1
eqn1 = 
eqn2 = a*x2^2 + b*x2 + c == y2
eqn2 = 
eqn3 = a*x3^2 + b*x3 + c == y3
eqn3 = 
sol = solve([eqn1, eqn2, eqn3], [a, b, c])
sol = struct with fields:
a: 28/253 - y2/132 b: 336/253 - (23*y2)/132 c: 0
syms x
eqn = expand(subs(a*x^2 + b*x + c, sol))
eqn = 
fsurf(eqn, [-10 10 -10 10])

John D'Errico
John D'Errico 2025-3-3
编辑:John D'Errico 2025-3-3
You have asked a confusing question, which usually means you are yourself confused, perhaps about what you really want to do. It is hard to know. But, the basics of your question are easy enough to answer.
You have given two points, (0,0), and (-31.5,30). How many points determine a line? TWO. The slope of that line is deltay/deltax.
slope = (30-0)/(-31.5 - 0)
slope = -0.9524
And the equation of that line is geven by the old point-slope form we should have learned a few millenia ago. Well, I did. Maybe not quite that long though. Since one of the points the line must pass through is (0,0), that gives us:
y-0 = slope*(x-0)
or
y = -30/31.5*x
that line passes through the two points.
Now, you can add a new term to that functional form that will stoll pass through the same points, as long as the new form has a root at BOTH x=0, and at x=-31.5. What does that mean? ANYTHING that looks like this will suffice:
a*x*(x+31.5)
If a is negative, the curve will lie above the straight line between those points. positive values of a will fall below the line. TRY IT!
yquad = @(x,a) -30/31.5*x + a*x.*(x+31.5);
fplot(@(x) yquad(x,0),[-31.5,0],'g-')
hold on
fplot(@(x) yquad(x,0.025),[-31.5,0],'r-')
fplot(@(x) yquad(x,-0.025),[-31.5,0],'b-')
fplot(@(x) yquad(x,-0.01),[-31.5,0],'k-')
hold off
grid on
legend('a = 0 (straight line)','a = 0.025','a = -0.025','a = -0.01')
You can be more creative yet, in fact, infinitely so, as long as the extra terms are zero at those two points.
Since we don't really know your goals in this, it is impossible to go much further though. If I had to make a wild guess, it would be that you hve some data, and you want to fit such a curve through the data that passes through those points. The simple solution is to use what I suggested, estimating the value of a. You could also add extra (higher order) terms that have the same properties, but different shapes. The tools to fit such a curve would be regression tools, perhaps fit, or lsqnonlin, lsqcurvefit, nlinfit, etc.
  1 个评论
Konvictus177
Konvictus177 2025-3-4
That was actuall not that difficult and yes you are correct. I am trying to fit some data or to be more specific, I want to find a simple equation to recreate curves that have very similar shapes compared to my real data based on the average line that I gave you.
How would my equation look like if want to keep only the point at P(-31.5/30) and remove the P(0/0). So basically the curves would all have different x coodinates for a common y like y=-15.
Something like the image below.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Linear and Nonlinear Regression 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by