# Revision history [back]

Hello, @Mo! As @Cyrille mentioned, given $n$ points, there exists an infinite number of curves that pass through them. However, there is a number of things you could do in order to obtain one of those curves. Let me explain three of them:

1. You can take advantage of the particular characteristics of your set of points. In this case, a simple visual inspection will show that the points are of the form $(x, x^2)$. So, a good curve for this set is quite simply $y=x^2$.
2. Of course, visual inspection is not always as easy as in this particular case. When you can't figure out the structure of function, a classical approach is to use interpolation polynomials. (This is also mentioned by @Cyrille.) Now, Sage has many interpolation facilities; in particular, there is the spline command. You can write something like this:

points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
S = spline(points)


Now, S is an interpolation spline, which you can evaluate en $x=0.2$, for example, with S(0.2); you can plot S with plot(S, xmin=0, xmax=2); you can differentiate it in $x=1.3$ with S.derivative(1.3); you can integrate it in its whole domain with S.definite_integral(0, 2); you could even plot the derivative and the antiderivative with a little bit of clever programming.

The disadvantage of the spline command is that it doesn't give you an explicit formula for the function.

3. There is another interpolation command which is a little more complicated, but more useful, in my humble opinion (in particular, it gives you a explicit formula). It's called lagrange_polynomial. In its simplest form, it uses divided differences to obtain the polynomial coefficients (you can read about that in any Numerical Methods book). You have to do something like this:

PR = PolynomialRing(RR, 'x')
points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
poly = PR.lagrange_polynomial(points)
print(poly)


The first line creates a polynomial ring, which I called PR, with real coefficients (thus the RR) and independent variable x (thus the 'x'). The second line is your set of points. The third line asks Sage to create the Lagrange Interpolation Polynomial in this polynomial ring. You should get something like this:

     -1.11022302462516e-16*x^3 + x^2 - 1.11022302462516e-16*x

You can use this polynomial as with any other polynomial. You can make plot(poly, (x, 0, 2)), poly.derivative(x), poly.derivative(x)(1.3), poly.integrate(x), etc.

However, as you can see, the coefficients for $x^3$ and $x$ are negligible, so you could deduce that poly is actually x^2. You can verify that using the following:

PR = PolynomialRing(QQ, 'x')
points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
poly = PR.lagrange_polynomial(points)
print(poly)

This is exactly the same as before, but you use rational coefficients instead of real ones (thus the QQ). Of course, the same result is obtained if you replace QQ with ZZ, since, in this case, the coefficients turn out to be integers. the result is x^2, as suspected!


There are other methods you can use to obtain curves that pass through $n$ points, but these are the simplest and more usual (and useful). Just remember the two downsides of interpolation: (1) Your are getting only one of an infinite number of possible functions that pass through your points. (2) You can only work inside the interpolation interval with certain level of certainty (in particular, S(3) will return nan or not-a-number; poly(4) will evaluate to 16, but you are in that case extrapolating, which is a very dangerous operation, especially in the lab).

I hope this helps!

Hello, @Mo! As @Cyrille mentioned, given $n$ points, there exists an infinite number of curves that pass through them. However, there is a number of things you could do in order to obtain one of those curves. Let me explain three of them:

1. You can take advantage of the particular characteristics of your set of points. In this case, a simple visual inspection will show that the points are of the form $(x, x^2)$. So, a good curve for this set is quite simply $y=x^2$.
2. Of course, visual inspection is not always as easy as in this particular case. When you can't figure out the structure of function, a classical approach is to use interpolation polynomials. (This is also mentioned by @Cyrille.) Now, Sage has many interpolation facilities; in particular, there is the spline command. You can write something like this:

points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
S = spline(points)


Now, S is an interpolation spline, which you can evaluate en $x=0.2$, for example, with S(0.2); you can plot S with plot(S, xmin=0, xmax=2); you can differentiate it in $x=1.3$ with S.derivative(1.3); you can integrate it in its whole domain with S.definite_integral(0, 2); you could even plot the derivative and the antiderivative with a little bit of clever programming.

The disadvantage of the spline command is that it doesn't give you an explicit formula for the function.

3. There is another interpolation command which is a little more complicated, but more useful, in my humble opinion (in particular, it gives you a explicit formula). It's called lagrange_polynomial. In its simplest form, it uses divided differences to obtain the polynomial coefficients (you can read about that in any Numerical Methods book). You have to do something like this:

PR = PolynomialRing(RR, 'x')
points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
poly = PR.lagrange_polynomial(points)
print(poly)


The first line creates a polynomial ring, which I called (creatively enough) PR, with real coefficients (thus the RR) and independent variable x (thus the 'x'). The second line is your set of points. The third line asks Sage to create the Lagrange Interpolation Polynomial in this polynomial ring. You should get something like this:

  -1.11022302462516e-16*x^3 + x^2 - 1.11022302462516e-16*x


You can use this polynomial as with any other polynomial. You can make plot(poly, plot(poly, (x, 0, 2)), poly.derivative(x), poly.derivative(x)(1.3), poly.integrate(x), etc. 2)), poly.derivative(x), poly.derivative(x)(1.3), poly.integrate(x), etc.

However, as you can see, the coefficients for $x^3$ and $x$ are negligible, so you could deduce that poly poly is actually x^2. x^2. You can verify that using the following: following:

PR = PolynomialRing(QQ, 'x')
points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
poly = PR.lagrange_polynomial(points)
print(poly)


This is exactly the same as before, but you use rational coefficients instead of real ones (thus the QQ). QQ). Of course, the same result is obtained if you replace QQ with ZZ, QQ with ZZ, since, in this case, the coefficients turn out to be integers. the result is x^2, x^2, as suspected! suspected!

There are other methods you can use to obtain curves that pass through $n$ points, but these are the simplest and more usual (and useful). Just remember the two downsides of interpolation: (1) Your are getting only one of an infinite number of possible functions that pass through your points. (2) You can only work inside the interpolation interval with certain level of certainty (in particular, S(3) will return nan or not-a-number; poly(4) will evaluate correctly to 16, but you are in that case are, in that case, extrapolating, which is a very dangerous operation, especially in the lab).

I hope this helps!

Hello, @Mo! As @Cyrille mentioned, given $n$ points, there exists an infinite number of curves that pass through them. However, there is a number of things you could do in order to obtain one of those curves. Let me explain three of them:

1. You can take advantage of the particular characteristics of your set of points. In this case, a simple visual inspection will show that the points are of the form $(x, x^2)$. So, a good curve for this set is quite simply $y=x^2$.
2. Of course, visual inspection is not always as easy as in this particular case. When you can't figure out the structure of function, a classical approach is to use interpolation polynomials. (This is also mentioned by @Cyrille.) Now, Sage has many interpolation facilities; in particular, there is the spline command. You can write something like this:

points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
S = spline(points)


Now, S is an interpolation spline, which you can evaluate en $x=0.2$, for example, with S(0.2); you can plot S with plot(S, xmin=0, xmax=2); you can differentiate it in $x=1.3$ with S.derivative(1.3); you can integrate it in its whole domain with S.definite_integral(0, 2); you could even plot the derivative and the antiderivative with a little bit of clever programming.

It is my understanding that splines are excellent approximating real-life functions, because natural phenomena tend to have smooth behavior. If these points were the result of measurements of a natural phenomenon in the lab, I would consider using splines for interpolation.

The disadvantage of the spline command is that it doesn't give you an explicit formula for the function.

3. There is another interpolation command which is a little more complicated, but more useful, in my humble opinion (in particular, it gives you a explicit formula). It's called lagrange_polynomial. In its simplest form, it uses divided differences to obtain the polynomial coefficients (you can read about that in any Numerical Methods book). You have to do something like this:

PR = PolynomialRing(RR, 'x')
points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
poly = PR.lagrange_polynomial(points)
print(poly)


The first line creates a polynomial ring, which I called (creatively enough) PR, with real coefficients (thus the RR) and independent variable x (thus the 'x'). The second line is your set of points. The third line asks Sage to create the Lagrange Interpolation Polynomial in this polynomial ring. You should get something like this:

 -1.11022302462516e-16*x^3 + x^2 - 1.11022302462516e-16*x


You can use this polynomial as with any other polynomial. You can make plot(poly, (x, 0, 2)), poly.derivative(x), poly.derivative(x)(1.3), poly.integrate(x), etc.

However, as you can see, the coefficients for $x^3$ and $x$ are negligible, so you could deduce that poly is actually x^2. You can verify that using the following:

PR = PolynomialRing(QQ, 'x')
points = [(0, 0), (0.5, 0.25), (0.6, 0.36), (2, 4)]
poly = PR.lagrange_polynomial(points)
print(poly)


This is exactly the same as before, but you use rational coefficients instead of real ones (thus the QQ). Of course, the same result is obtained if you replace QQ with ZZ, since, in this case, the coefficients turn out to be integers. the result is x^2, as suspected!

There are other methods you can use to obtain curves that pass through $n$ points, but these are the simplest and more usual (and useful). Just remember the two downsides of interpolation: (1) Your are getting only one of an infinite number of possible functions that pass through your points. (2) You can should only work inside the interpolation interval with certain level of certainty (in particular, S(3) will return nan or not-a-number; poly(4) will evaluate correctly to 16, but you are, in that case, extrapolating, which is a very dangerous operation, especially in the lab).

I hope this helps!