# Quadratic Equation from 3 points

1. May 18, 2010

### theoarc

Okay so this seems like a very simple problem to me but I can't figure it out so I definitely need some help. I'm not a mathematician but a programmer and in this case I need to figure out how to get the curve that passes through 3 points. I know this can be done easily with substitution but that tends to requires human logic in order to decide what equations to use in which order. I need another method. I need to be able to do this programmatically.

I know when I put 3 points into the TI-83 and ask it to do a Quadratic Regression it will give me a function and plot a graph in y = ax2 + bx + c

That's what I am looking for a method of solving for y = ax2 + bx + c from 3 points hopefully without substitution.

I hope I am making sense.
Thanks for any help.

2. May 18, 2010

### Tedjn

You will need to substitute the points somehow in order to find the coefficients. If you have a library available that can handle common matrix operations, this can be made pretty simple, however.

3. May 18, 2010

### phizo

Hmmm care to give us the three points? or is it hypothetical exercise?

Anyway I do a bit of programing and have a spattering of maths too.

So I assume some points such as (1,6) (7,8)(10,2) or whatever, and you need to find A B &C? And you want to write a progam to do it?

4. May 18, 2010

### Xitami

$ax_1^2+bx_1+c=y_1$
$ax_2^2+bx_2+c=y_2$
$ax_3^2+bx_3+c=y_2$

$\left[\begin{array}{ccc}a\\b\\c\end{array}\right] = \left[\begin{array}{ccc}y_1\\y_2\\y_3\end{array}\right] \left[\begin{array}{ccc}x_1^2&x_1&1\\x_2^2&x_2&1\\x_3^2&x_3&1\end{array}\right] ^{-1}$

http://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_3.C3.973_matrices

Last edited: May 18, 2010
5. May 18, 2010

### phizo

I might have a go using the points I have given and see how far I get, or not, as the case maybe. :rofl:

6. May 18, 2010

### Unit

Do you realize that three points may not necessarily all lie on a parabola? For example, there is no parabola that contains (0, 0), (1, 1) and (2, 2).

However, there is an infinite number of parabolae that contain any two distinct points. For example, the points (-1, 0) and (1, 0). For this particular case, the axis of symmetry is at 0, so the parabolae are of the form $y = ax^2 - a$ where a is a real number.

7. May 18, 2010

### phizo

OK I just started out with an idea and coubbled togeather a bit of a program.
It's not completed, just a bit of a framework to get and idea of what I am doing.

I am trying stick in some values for a b and c and work out the values which give the lowest
error, then when I have that I will have to try and narrow the range and step based on the results.

Anyway here is how far I got, no comment, obviously ;)

Code (Text):

#include <stdio.h>

main(argc,argv)
int  argc;
char *argv[];
{

printf("started\n");

// y = ax2 + bx + c
// (1,6) (7,8)(10,2)

float y1,y2,y3,x1,y2,x3, sa,sb,sc, na,nb,nc, step, ea, olodea;

x1=1;y1=6;x2=7; y2=8;x3=10; y3=2; oldea=100000;

sa=sb=sc=250;
step=1;

for(a=-sa; a<sa; a+=step){
for(b=-sb; a<sb; b+=step){
for(c=-sc; a<sc; c+=step){

e1 = a*36 + b*6 +c -1;
e2 = a*64 + b*8 +c -7;
e3 = a*4  + b*2 + c-10;
et = e1 + e2 + e3;
ea=abs(et)
if (ea<oldea) {
oldea=ea;
na=a; nb=b; nc=c; //n=new, so i am saving the nearest guess

}

}
}
}

printf("\n a=%f b-%f c=%c"; na,nb,nc);

}

Obviously it won't even compile at the moment!!

Might give you an idea though.

Last edited: May 18, 2010
8. May 18, 2010

### phizo

So I think after I had got some results I would run the whole thing again using say 30% above and below my range and with and appropiate smaller step.

Then you just repeat the process keeping your fingers crossed!! :rofl:

Last edited: May 18, 2010
9. May 18, 2010

### phizo

OK so I have version running, I can hear the fan has kicked in and I can smell burning!!
250^3 is a big number I think I might reduce that!!

10. May 18, 2010

### Xitami

$a_{13}=a_{23}=a_{33}=1$

Last edited: May 18, 2010
11. May 18, 2010

### phizo

OK got a bit further:-

Code (Text):

#include <stdio.h>
#include <math.h>
main(argc,argv)
int  argc;
char *argv[];
// y = ax2 + bx + c // (1,6) (7,8)(10,2)
float y1,y2,y3,x1,x2,x3, sa,sb,sc, na,nb,nc, step, ea, oldea, a, b, c, e1,e2,e3,et;
x1=1;y1=6;x2=7; y2=8;x3=10; y3=2; oldea=10000000;
int cc=0;
sa=sb=sc=10;
step=1;

for(a=-sa; a<sa; a+=step){
for(b=-sb; b<sb; b+=step){
for(c=-sc; c<sc; c+=step){
e1 = a*36 + b*6 +c -1;
e2 = a*64 + b*8 +c -7;
e3 = a*4  + b*2 + c-10;
et = e1 + e2 + e3;
ea=fabs(et);
printf("ea %f et %f oldea %f \n",ea,et,oldea); //fflush(stdout);
if (ea< oldea) {
oldea=ea;
na=a; nb=b; nc=c; //n=new, so i am saving the nearest guess
}
printf("sa %f sb %f sc %f \n",a,b,c); fflush(stdout);
}
}
if (cc>10) break;
}
printf("\n a=%f b= %f c=%f", na,nb,nc);
}

Results

Code (Text):

......
sa 9.000000 sb 9.000000 sc 7.000000
ea 1086.000000 et 1086.000000 oldea 0.000000
sa 9.000000 sb 9.000000 sc 8.000000
ea 1089.000000 et 1089.000000 oldea 0.000000
sa 9.000000 sb 9.000000 sc 9.000000

a=-1.000000 b= 8.000000 c=-2.000000

Last edited: May 18, 2010
12. May 18, 2010

### Dickfore

The matrix of the system is called Vandermonde matrix.

13. May 18, 2010

### phizo

So for first point, 1,6, which in the program is 6,1 due to error

You have 6 = -1 x 1 + 8x1 -2 = 5, so not far out

Second 7,8 or 8,7 due to error

7 = -1 x 64 + 64 -2 = 5 so 2 out

Third 10,2 but 2,10 in program

10 = -1 x 4 + 16 + 2 = 14 so 4 out.

So it seems to work in a rough manner

Now if I plugged some new values in based on those results and also reduced the step size
I would hopefully home in on the solution. However if I get the estimates wrong I
might miss it.

I will try and modify it later to do that.

14. May 18, 2010

### phizo

I hate matrices!!! :rofl:

15. May 18, 2010

### Xitami

yes!

16. May 18, 2010

### phizo

I need to make some adjustment to my prog, will try that tomorrow and see how I get on.

17. May 19, 2010

### Martin Rattigan

You could use the Lagrange interpolation formula if you can guarantee that the $x$ coördinates of your points will be distinct.

That is, if your points are $(x_1,y_1),(x_2,y_2),(x_3,y_3)$ with no two of $x_1,x_2,x_3$ the same

$$y=y_1\frac{(x-x_2)(x-x_3)}{(x_1-x_2)(x_1-x_3)}+y_2\frac{(x-x_1)(x-x_3)}{(x_2-x_1)(x_2-x_3)}+y_3\frac{(x-x_1)(x-x_2)}{(x_3-x_1)(x_3-x_2)}$$

In the case $(0,0),(1,1),(2,2)$ mentioned by Unit this will just give you a straight line. If you have duplicate $x$ coördinates there won't be an equation of the form you asked for that goes through the three points unless the corresponding $y$ coördinates are also duplicated, in which case you have only one or two points and you can drop the duplicate(s) and include an arbitrary extra point(s) with distinct $x$ coördinate(s).

The formula generalizes in an obvious way to a different number of points.

You're asking for a hyperbola with a vertical axis in general. Is that really what you want? E.g. a unique circle will go thro' three distinct points. Also if you may want to expand it to more points it would be a good idea to think in terms of spline functions. See http://en.wikipedia.org/wiki/Spline_(mathematics [Broken]).

Last edited by a moderator: May 4, 2017
18. May 19, 2010

### theoarc

haha Phizo, that looks like a fun experiment. Not exactly sure it's what I am after... not exactly sure I understand it. You should do some speed tests on it to solve something simple like:
(2, 0) , (-2, 0) , (0, 4)

Currently I'm writing the code in AS3; however, in the end it will need to be in C so I'll probably get better speed later. Anyway using matrices as suggested by Xitami I was able to solve this rather easily, that was exactly what I was looking for.

There's a Matrix library for as3 called KMatrix that worked great. I'm sure there are many in C as well.

Anyway it took 5ms to solve for a, b, and c from the above numbers. So I'm happy with that.

I had seen the Lagrange interpolation formula. However, I didn't want to use it because it looks to require a lot more calculations in the long run. I could do a test and see which is faster over a period of time but I'm pretty happy with the Matrix solution at the moment. I haven't tested it in an actual useful situation yet so I'll find out soon.

Last edited: May 19, 2010
19. May 19, 2010

### Xitami

(x1,y1), (x2, y2), (x3, y3)
y=a*x*x+b*x+c

$$a=\frac{ \left(y_{2} - y_{3}\right) x_{1} + \left( y_{1} - y_{2}\right) x_{3} + \left(y_{3} - y_{1}\right) x_{2} }{ \left(x_{3} - x_{2}\right) x_{1}^2 + \left(-x_{3}^2 + x_{2}^2\right) x_{1} + \left(x_{2} x_{3}^2 - x_{2}^2 x_{3}\right) }$$

$$b= \frac{ \left(-y_{2} + y_{3}\right) x_{1}^2 + \left(-y_{1} x_{3} + y_{1} x_{2}\right) x_{1} + \left( \left(-y_{1} + y_{2}\right) x_{3}^2 + y_{1} x_{2} x_{3} - y_{3} x_{2}^2\right) }{ \left(x_{3} - x_{2}\right) x_{1}^2 + \left(-x_{3}^2 + x_{2}^2\right) x_{1} + \left(x_{2} x_{3}^2 - x_{2}^2 x_{3}\right) }$$

$$c=\frac{ \left(y_{2} x_{3} - y_{3} x_{2}\right) x_{1}^2 + \left( \left(y_{1} - y_{2}\right) x_{3}^2 - y_{1} x_{2} x_{3} + y_{3} x_{2}^2\right) x_{1}}{ \left(x_{3} - x_{2}\right) x_{1}^2 + \left(-x_{3}^2 + x_{2}^2\right) x_{1} + \left(x_{2} x_{3}^2 - x_{2}^2 x_{3}\right) }$$

$$\mu S$$ i think

Last edited: May 19, 2010
20. May 19, 2010

### theoarc

Xitami,

that's perfect!

I've only tested it once but it worked brilliantly.
Also takes less than 1ms to complete. That's at least 5x the speed of using the matrix class.

Thanks a lot :D

21. May 19, 2010

### phizo

OK, I have made some modifications, there were some programing and logical error, and a few more remain but I think it came up with the right values for you inputs.

Code (Text):

best guess  a=-2.00    b= 0.00     c=8.00    ea 21.00    et 21.00    oldea 4.00     ***  sa -1.00    sb 0.00     sc -3.00
best guess  a=-2.00    b= 0.00     c=8.00    ea 18.00    et 18.00    oldea 4.00     ***  sa -1.00    sb 0.00     sc -2.00
best guess  a=-2.00    b= 0.00     c=8.00    ea 15.00    et 15.00    oldea 4.00     ***  sa -1.00    sb 0.00     sc -1.00
best guess  a=-2.00    b= 0.00     c=8.00    ea 12.00    et 12.00    oldea 4.00     ***  sa -1.00    sb 0.00     sc 0.00
best guess  a=-2.00    b= 0.00     c=8.00    ea 9.00     et 9.00     oldea 4.00     ***  sa -1.00    sb 0.00     sc 1.00
best guess  a=-2.00    b= 0.00     c=8.00    ea 6.00     et 6.00     oldea 4.00     ***  sa -1.00    sb 0.00     sc 2.00
best guess  a=-2.00    b= 0.00     c=8.00    ea 3.00     et 3.00     oldea 4.00     ***  sa -1.00    sb 0.00     sc 3.00
best guess  a=-1.00    b= 0.00     c=3.00    ea 0.00     et 0.00     oldea 3.00     ***  sa -1.00    sb 0.00     sc 4.00
best guess  a=-1.00    b= 0.00     c=4.00    ea 3.00     et 3.00     oldea 0.00     ***  sa -1.00    sb 0.00     sc 5.00

........

best guess  a=-1.00    b= 0.00     c=4.00    ea 86.00    et 86.00    oldea 0.00     ***  sa 9.00     sb 9.00     sc 6.00
best guess  a=-1.00    b= 0.00     c=4.00    ea 89.00    et 89.00    oldea 0.00     ***  sa 9.00     sb 9.00     sc 7.00
best guess  a=-1.00    b= 0.00     c=4.00    ea 92.00    et 92.00    oldea 0.00     ***  sa 9.00     sb 9.00     sc 8.00
best guess  a=-1.00    b= 0.00     c=4.00    ea 95.00    et 95.00    oldea 0.00     ***  sa 9.00     sb 9.00     sc 9.00
best guess  a=-1.00    b= 0.00     c=4.00
****************************************** a=-1.000000 b= 0.000000 c=4.000000
****************************************** a=-1.000000 b= 0.000000 c=4.000000
****************************************** a=-1.000000 b= 0.000000 c=4.000000

New prog.

Code (Text):

#include <stdio.h>
#include <math.h>
main(argc,argv)
int  argc;
char *argv[]; {
// y = ax2 + bx + c // (1,6) (7,8)(10,2)
float y1,y2,y3,x1,x2,x3, sa,sb,sc, sae,sbe,sce, na,nb,nc;
float stepa, stepb, stepc, ea, oldea, a, b, c, e1, e2, e3, et;
int c1;
c1=0;
x1=2;y1=0;
x2=-2; y2=0;
x3=0; y3=4;

oldea=10000000;
sa=sb=sc=-10;
sae=sbe=sce=10;

stepa=1;
stepb=1;
stepc=1;

while(c1++<3){

oldea=10000000;
for(a=sa; a<sae; a+=stepa){
for(b=sb; b<sbe; b+=stepb){
for(c=sc; c<sce; c+=stepc){
e1 = a*x1*x1 + b*x1 +c -y1;
e2 = a*x2*x2 + b*x2 +c -y2;
e3 = a*x3*x3 + b*x3 +c -y3;
et = fabs(e1) + fabs(e2) + fabs(e3);
ea=fabs(et);
printf("ea %-08.2f et %-08.2f oldea %-08.2f ***  ",ea,et,oldea); //fflush(stdout);
if (ea< oldea) {
oldea=ea;
na=a; nb=b; nc=c; //n=new, so i am saving the nearest guess
}
printf("sa %-08.2f sb %-08.2f sc %-08.2f \n",a,b,c);
printf(" best guess  a=%-8.2f b= %-8.2f c=%-8.2f", na,nb,nc);

}
}
}

printf("\n****************************************** a=%f b= %f c=%f", na,nb,nc);

sa=na*0.3;
sb=nb*0.3;
sc=nc*0.3;
sae=na*2.5;
sbe=nb*2.5;
sce=nc*2.5;
stepa=(float)(sa-sae)/30;
stepb=(float)(sb-sbe)/30;
stepc=(float)(sc-sce)/30;

}

}

I would need some better test data as part of the program is not used because it
finds the result easilly.

22. May 19, 2010

### phizo

Hence I would appreciate some test data!!!

23. May 19, 2010

### phizo

I tried it with
x1=2; y1=0;
x2=-2; y2=0;
x3=5; y3=4;

And it came up with a=0.000000 b= 0.000000 c=0.000000

Maybe there is no solution or more likely errors on my part. (things never work first effort).

Well it did also say oldea=4, which means it did not find a solution as the error was 4 not 0.

24. May 19, 2010

### Xitami

y=4/21x^2 +0x -16/21

25. May 19, 2010

### phizo

Yes there is a problem when it's best guess for a b or c is 0, because I then do 2.5 times 0
and 0.3 times zero, which both give me zero as an answer for my test range!!