# How to fit a polynomial with a pre-determined degree to a set of points?

**URL:** https://discourse.julialang.org/t/how-to-fit-a-polynomial-with-a-pre-determined-degree-to-a-set-of-points/91981
**Category:** General Usage
**Tags:** regression, fit, curve-fitting, polynomials, approxfun
**Created:** [December 21, 2022, 10:14pm UTC](https://discourse.julialang.org/t/how-to-fit-a-polynomial-with-a-pre-determined-degree-to-a-set-of-points/91981 "2022-12-21T22:14:38Z")
**Posts on this page:** 1
**Showing post:** 3

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [December 22, 2022, 10:56am UTC](https://discourse.julialang.org/t/how-to-fit-a-polynomial-with-a-pre-determined-degree-to-a-set-of-points/91981/3 "2022-12-22T10:56:23Z")

</div>

The thing is that ApproxFun needs to know the values of `f` at specific values of `x`. For a Chebyshev approximation, if you happen to know the function values at the Chebyshev nodes there’s no problem:

```julia
using CairoMakie
using ApproxFun

f(x) = sin(2*pi*x)

# Get 30 Chebyshev nodes in the interval [0, 5]
# (these nodes are not evenly spaced)
S = Chebyshev(0..5)
x = points(S, 30)

# Suppose we know the value of f at these points
y = f.(x)

# We can calculate the corresponding Chebyshev coefficients
c = transform(S, y)
# And build the approximation of f
fa = Fun(S, c)

fig = plot(x, y, figure=(; resolution=(500, 200)))
plot!(domain(S), fa)
fig

```

![image](https://global.discourse-cdn.com/julialang/original/3X/8/7/87a6bfb6808487c72a8a4039c9763f80ccab007e.png)

More probably, you have data points on an even grid or a random grid. You can still find the coefficients of the Chebyshev polynomials that go through these points using linear regression as shown in the [FAQ](https://juliaapproximation.github.io/ApproxFun.jl/latest/faq/):

```julia
# Points on a regular grid
x = range(0, 5, length=30)
y = f.(x)

# Function space for approximations on the given interval
S = Chebyshev(x[begin]..x[end])

# Build design matrix for linear regression by evaluating each
# polynomial at the given x values
X = hcat((Fun(S, [zeros(k-1); 1]).(x) for k in 1:length(x))...)

# Use linear regression to find the Chebyshev coefficients
c = X\y
fa = Fun(S, c)

fig = plot(x, y, figure=(; resolution=(500, 200)))
plot!(domain(S), fa)
fig

```

![image](https://global.discourse-cdn.com/julialang/original/3X/5/c/5c2cbc90cc892bb11be8fbb25f1fee4d6200bb87.png)

Though according to the FAQ for numberical stability it’s better to use an overdetermined system (i.e. replace `length(x)` by a smaller number in the code above).

Another option proposed [here](https://discourse.julialang.org/t/best-way-to-take-derivatives-of-unevenly-spaced-data-with-interpolations-discrete-derivatives/54097/4) is to make a first approximation with the AAA algorithm and use the result (a rational function) to calculate values at the Chebyshev nodes:

```julia
using BaryRational

# Using >30 points to avoid Froissart doublets (poles near zeros)
x = range(0, 5, length=50)
y = f.(x)

# Rational approximation
f_aaa = aaa(x, y)

# Approximations of f at the Chebyshev nodes (we choose n=100)
x_cheb = points(S, 100)
y_cheb = f_aaa.(x_cheb)

# Chebyshev approximation of f
c = transform(S, y_cheb)
fa = Fun(S, c)

fig = plot(x, y, figure=(; resolution=(500, 200)))
plot!(0..5, fa)
fig

```

![image](https://global.discourse-cdn.com/julialang/original/3X/f/0/f00168940586bcc3d640341fc872ac839c35abb9.png)

---

_[View the full topic](https://discourse.julialang.org/t/how-to-fit-a-polynomial-with-a-pre-determined-degree-to-a-set-of-points/91981)._
