All Projects → nschloe → smoothfit

nschloe / smoothfit

Licence: GPL-3.0 license
Smooth data fitting in N dimensions.

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to smoothfit

AtCoder
atcoder.jp/user/saikat
Stars: ✭ 24 (-40%)
Mutual labels:  mathematics
muparserx
A C++ Library for Parsing Expressions with Strings, Complex Numbers, Vectors, Matrices and more.
Stars: ✭ 102 (+155%)
Mutual labels:  mathematics
maelstrom
Numerical simulation of magnetohydrodynamics.
Stars: ✭ 28 (-30%)
Mutual labels:  mathematics
GOS-Book.github.io
📙 Пособие для подготовки ГОСу по математике для студентов МФТИ
Stars: ✭ 49 (+22.5%)
Mutual labels:  mathematics
My NoteBook
サイエンス、テクノロジー、エンジニアリング関連の情報を記載したノート(忘備録)です。
Stars: ✭ 104 (+160%)
Mutual labels:  mathematics
mish
A no-std libm implementation in Rust
Stars: ✭ 14 (-65%)
Mutual labels:  mathematics
tukey
Mini stats toolkit for Clojure/Script
Stars: ✭ 17 (-57.5%)
Mutual labels:  mathematics
alchemy
Generate any a-by-( b + c ) finite rectangle SVG containing potentially Infinitely many a-by-( 2 * b ) finite rectangles animated along a number line of ( ( c - b ) / a )^n scale symmetry.
Stars: ✭ 29 (-27.5%)
Mutual labels:  mathematics
cddlib
An efficient implementation of the Double Description Method
Stars: ✭ 71 (+77.5%)
Mutual labels:  mathematics
pacopy
📐 Numerical parameter continuation in Python.
Stars: ✭ 33 (-17.5%)
Mutual labels:  mathematics
matematicaelementar
Matemática Elementar para Computação
Stars: ✭ 29 (-27.5%)
Mutual labels:  mathematics
machine-learning-notebooks
🤖 An authorial collection of fundamental python recipes on Machine Learning and Artificial Intelligence.
Stars: ✭ 63 (+57.5%)
Mutual labels:  mathematics
ai-math-roadmap
Your no-nonsense guide to the Math used in Artificial Intelligence
Stars: ✭ 173 (+332.5%)
Mutual labels:  mathematics
string-math
Evaluates a math expression from a string. Supports variables and custom operators.
Stars: ✭ 14 (-65%)
Mutual labels:  mathematics
meshgen-comparison
🕸️ A comparison of mesh generators.
Stars: ✭ 25 (-37.5%)
Mutual labels:  mathematics
4ti2
A software package for algebraic, geometric and combinatorial problems on linear spaces. By R. Hemmecke, R. Hemmecke, M. Köppe, P. Malkin, M. Walter
Stars: ✭ 21 (-47.5%)
Mutual labels:  mathematics
discrete-math-python-scripts
Python code snippets from Discrete Mathematics for Computer Science specialization at Coursera
Stars: ✭ 98 (+145%)
Mutual labels:  mathematics
maths-for-deep-learning-ai
A open source book covering the foundational maths of deep learning and machine learning using TensorFlow
Stars: ✭ 35 (-12.5%)
Mutual labels:  mathematics
csmath-2021
This mathematics course is taught for the first year Ph.D. students of computer science and related areas @zju
Stars: ✭ 30 (-25%)
Mutual labels:  mathematics
chaotic-maps
Simple implementations of chaotic maps in Processing
Stars: ✭ 18 (-55%)
Mutual labels:  mathematics

smoothfit

PyPi Version PyPI pyversions GitHub stars PyPi downloads

Discord

gh-actions codecov LGTM Code style: black

Given experimental data, it is often desirable to produce a function whose values match the data to some degree. This package implements a robust approach to data fitting based on the minimization problem

\|\lambda\Delta f\|^2_{L^2(\Omega)} + \sum_i (f(x_i) - y_i)^2 \to\min

(Rendered with xdoc.)

(A similar idea is used in for data smoothing in signal processing; see, e.g., section 8.3 in this document.)

Unlike polynomial regression or Gauss-Newton, smoothfit makes no assumptions about the function other than that it is smooth.

The generality of the approach makes it suitable for function whose domain is multidimensional, too.

Pics or it didn't happen

Runge's example

Runge's example function is a tough nut for classical polynomial regression.

If there is no noise in the input data, the parameter lmbda can be chosen quite small such that all data points are approximated well. Note that there are no oscillations in the output function u.

import matplotlib.pyplot as plt
import numpy as np
import smoothfit

a = -1.5
b = +1.5

# plot original function
x = np.linspace(a, b, 201)
plt.plot(x, 1 / (1 + 25 * x ** 2), "-", color="0.8", label="1 / (1 + 25 * x**2)")

# sample points
x0 = np.linspace(-1.0, 1.0, 21)
y0 = 1 / (1 + 25 * x0 ** 2)
plt.plot(x0, y0, "xk")

# smoothfit
basis, coeffs = smoothfit.fit1d(x0, y0, a, b, 1000, degree=1, lmbda=1.0e-6)
plt.plot(basis.mesh.p[0], coeffs[basis.nodal_dofs[0]], "-", label="smooth fit")

plt.ylim(-0.1)
plt.grid()
plt.show()

Runge's example with noise

If the data is noisy, lmbda needs to be chosen more carefully. If too small, the approximation tries to resolve all data points, resulting in many small oscillations. If it's chosen too large, no details are resolved, not even those of the underlying data.

import matplotlib.pyplot as plt
import numpy as np
import smoothfit

a = -1.5
b = +1.5

# plot original function
x = np.linspace(a, b, 201)
plt.plot(x, 1 / (1 + 25 * x ** 2), "-", color="0.8", label="1 / (1 + 25 * x**2)")

# 21 sample points
rng = np.random.default_rng(0)
n = 51
x0 = np.linspace(-1.0, 1.0, n)
y0 = 1 / (1 + 25 * x0 ** 2)
y0 += 1.0e-1 * (2 * rng.random(n) - 1)
plt.plot(x0, y0, "xk")

lmbda = 5.0e-2
basis, coeffs = smoothfit.fit1d(x0, y0, a, b, 1000, degree=1, lmbda=lmbda)
plt.plot(basis.mesh.p[0], coeffs[basis.nodal_dofs[0]], "-", label="smooth fit")

plt.grid()
plt.show()

Few samples

import numpy as np
import smoothfit

x0 = np.array([0.038, 0.194, 0.425, 0.626, 1.253, 2.500, 3.740])
y0 = np.array([0.050, 0.127, 0.094, 0.2122, 0.2729, 0.2665, 0.3317])
u = smoothfit.fit1d(x0, y0, 0, 4, 1000, degree=1, lmbda=1.0)

Some noisy example data taken from Wikipedia.

A two-dimensional example

import meshzoo
import numpy as np
import smoothfit

n = 200
rng = np.random.default_rng(123)
x0 = rng.random((n, 2)) - 0.5
y0 = np.cos(np.pi * np.sqrt(x0.T[0] ** 2 + x0.T[1] ** 2))

# create a triangle mesh for the square
points, cells = meshzoo.rectangle_tri(
    np.linspace(-1.0, 1.0, 32), np.linspace(-1.0, 1.0, 32)
)

basis, u = smoothfit.fit(x0, y0, points, cells, lmbda=1.0e-4, solver="dense-direct")

# Write the function to a file
basis.mesh.save("out.vtu", point_data={"u": u})

This example approximates a function from R2 to R (without noise in the samples). Note that the absence of noise the data allows us to pick a rather small lmbda such that all sample points are approximated well.

Comparison with other approaches

Polynomial fitting/regression

The classical approach to data fitting is polynomial regression. Polynomials are chosen because they are very simple, can be evaluated quickly, and can be made to fit any function very closely.

There are, however, some fundamental problems:

This above plot highlights the problem with oscillations.

Fourier smoothing

One approach to data fitting with smoothing is to create a function with all data points, and simply cut off the high frequencies after Fourier transformation.

This approach is fast, but only works for evenly spaced samples.

For equidistant curve fitting there is nothing else that could compete with the Fourier series. -- Cornelius Lanczos

import matplotlib.pyplot as plt
import numpy as np


rng = np.random.default_rng(0)

# original function
x0 = np.linspace(-1.0, 1.0, 1000)
y0 = 1 / (1 + 25 * x0 ** 2)
plt.plot(x0, y0, color="k", alpha=0.2)

# create sample points
n = 51
x1 = np.linspace(-1.0, 1.0, n)  # only works if samples are evenly spaced
y1 = 1 / (1 + 25 * x1 ** 2) + 1.0e-1 * (2 * rng.random(x1.shape[0]) - 1)
plt.plot(x1, y1, "xk")

# Cut off the high frequencies in the transformed space and transform back
X = np.fft.rfft(y1)
X[5:] = 0.0
y2 = np.fft.irfft(X, n)
#
plt.plot(x1, y2, "-", label="5 lowest frequencies")

plt.grid()
plt.show()

License

smoothfit is published under the GPLv3+ license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].