Note
Go to the end to download the full example code.
12.1.10.2.2. Fit data#
This demo shows how data fitting can be performed using the itom.dataObject
and itom.algorithms
.
import numpy as np
from itom import dataObject
from itom import algorithms
Polynomial of order 2 in x- and y-direction
def polyFuncOrder2x2(x: float, y: float) -> float:
return 2.5 * x**2 + -1.7 * y**2 + 1.3 * x * y + 0.7 * x - 0.3 * y + 3.2
Vectorize this function to be evaluated over an array of x and y-coordinates
f = np.vectorize(polyFuncOrder2x2)
[X, Y] = np.meshgrid(np.arange(-10, 10.5, 0.5), np.arange(-10, 10.5, 0.5))
Z = f(X, Y)
total = np.prod(Z.shape)
First create a 2d polynomial fit with order x = 2 and order y = 2. Z_ must be a regular grid where the x- and y- values are defined by its axisScales and axisOffsets attributes.
Z_ = dataObject(Z)
Z_.axisScales = (0.5, 0.5)
Z_.axisOffsets = (20, 20)
coeffs = algorithms.polyfitWeighted2D(Z_, 2, 2)
print("coefficients: ", coeffs)
# Reconstruct the fitted sphere using the determined coefficients.
# First, create a ``dataObject`` with the desired size, scaling and offset for the
# the grid of x- and y- values. The z-values are then calculated.
Z_reconstruction = Z_.copy()
Z_reconstruction[:, :] = float("nan")
algorithms.polyval2D(Z_reconstruction, coeffs, 2, 2)
coefficients: (3.200000000000888, -0.3000000000000551, -1.7000000000000066, 0.6999999999999961, 1.2999999999999994, 2.5)
Randomly select a number of samples unique values in the range [0,total)
.
samples = 100
randomUniqueValues = np.random.choice(total, samples)
X2 = dataObject([1, samples], "float64")
Y2 = dataObject([1, samples], "float64")
Z2 = dataObject([1, samples], "float64")
c = Z.shape[1]
for i in range(samples):
idx = randomUniqueValues[i]
X2[0, i] = X[int(idx / c), idx % c]
Y2[0, i] = Y[int(idx / c), idx % c]
Z2[0, i] = Z[int(idx / c), idx % c]
Determine the polyonimal coefficients only using the random samples.
coeffs2 = algorithms.polyfitWeighted2DSinglePoints(X2, Y2, Z2, 2, 2)
# coeffs and coeffs2 must be the same!
print("fitted coefficient: ", coeffs2)
fitted coefficient: (3.2000000000000166, -0.30000000000000165, -1.699999999999999, 0.6999999999999973, 1.3000000000000007, 2.5000000000000004)
And reconstruct the entire surface for X and Y values.
reconstruction = dataObject()
algorithms.polyval2DSinglePoints(
dataObject(X),
dataObject(Y),
reconstruction,
coeffs2,
2,
2,
)
sample_reconstruction = dataObject()
algorithms.polyval2DSinglePoints(X2, Y2, sample_reconstruction, coeffs2, 2, 2)
Total running time of the script: (0 minutes 0.001 seconds)