1 | initial version |

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:

- 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$.
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.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!

2 | No.2 Revision |

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:

- 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$.
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.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!

3 | No.3 Revision |

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:

- 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$.
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.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!

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.