Skip to content

utksara/mrafit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MRA FIT

Fit curves with high precision using Multi-resolution analysis and Wavelet transform. The module directly implements Orthogonal Gausslets as described in the paper, however, in addition, the module also has hat basis functions and allows for the construction of custom Gausslets.

Installation

To install the latest version

pip install mrafit

To install a specific version (example 1.1.2)

pip install mrafit==1.1.2

Use cases

Approximating curve using basis function

mrafit allows reconstruction of a curve by expressing it in terms of localized basis functions. In other words, a curve represented by a list of points $x_i$, $y_i$ can be represented as a much smaller list of coefficients $c_i$, which reduces the dimensionality of representation. The same can be done for any 3-d curve represented by $x_i$, $y_i$, $z_i$.

Quantum chemistry and molecular structure

Quantum chemistry involves calculating electronic states in Atoms and molecules with a large number of electrons using Schrödinger's equation, which makes it particularly challenging due to the complexity involved in electron-electron interactions. Orthogonal wavelet transformation can drastically simplify quantum chemistry calculations by reducing complexity from O(4) to O(2) while calculating the electron interaction Potential

ML and AI

Since any 2-d, 3-d curve can be reduced to a 1-d representation of coefficients, this can provide a massive computational advantage in ML problems where parametric learning of curves is required. Instead of learning points, one can simply apply mrafit and learn mra coefficients instead.

Examples

Most common use case

  • To fit any function (type Callable) using a basis WaveletBasis (class Wavelet)
from mrafit.wavelet_basis.WaveletBasis
basis = WaveletBasis()
coeff, Y, error = basis.get_mra_approx(func, X)

In the above example, WaveletBasis by default is Haar basis, it can be replaced with one of the available basis in the module. In case of Gausslet basis, the code is modified as

from mrafit.wavelet_basis.GaussletBasis
basis = GaussletBasis(resolution = 0.1)
coeff, Y, error = basis.get_mra_approx(func, X)

here,

Input params

function : a callable function of function values (function or numpy array)
X : Uniform 1-d grid (numpy array)

Output params

coeffs: values of coefficients of given basis function (numpy array)
approx_function: values of approximated function using given basis (numpy array)
error: error of the approximate values with respect to the original value of the function

  • To reconstruct any function of the coefficients of a basis is provided
Y = basis.get_reconstructed_func(coeffs, X)
  • Example use case with GaussletBasis
import mrafit.wavelet_bases as wavelet_bases
import numpy as np

# From wavelet_bases, an instance of any available basis can be created. For example, to use the orthogonal Gausslet basis, we can define


gb = wavelet_bases.GaussletBasis()
func = lambda x : np.exp(-x**2/3) * (x**2 - x + 1)

# To approximate any given function defined over domain \(-1, 1\) with respect to a basis


X = np.linspace(-1, 1, 100)
coeffs, approx_func, error = gb.get_mra_approx(func, X)


# The example below includes a list of all steps to fit a synthetic function using mrafit

""" This parameter controls how precisely you want to approximate a function; the smaller the value better the approximation."22"
resolution = 0.5

wid = 10
N = 800
error_bound = 10e-2 * resolution

""" Use this section if you want to test gausslet with Stephen White's coefficients"""
gb = wavelet_bases.GaussletBasis(resolution=resolution)

""" Sample function to be approximated, you can change it as per your need"""
func = lambda x : np.exp(-x**2/3) * (x**2 - x + 1)

""" Finally applying the mra approximation"""
X = np.linspace(-wid, wid, N)
coeffs, approx_func, error = gb.get_mra_approx(func, X)

plt.plot(X, approx_func)
plt.plot(X, np.vectorize(func)(X))

The image below shows the approximate function vs the actual function alt text

Evaluation of a basis

Apart from the error obtained from get_mra_approx function, one can determine the performance of a basis function using get_orthongonality and get_completeness functions. This is especially useful for the bases which are known to be orthogonal or complete, but due to numerical transformation can give unexpected results.

from mrafit.wavelet_basis.WaveletBasis
basis = WaveletBasis()
coeff, Y, error = basis.get_mra_approx(func, X)

orthogonality = basis.get_orthogonality()
completness = basis.get_completeness()

Both returns score between 0(least complete) to 1 (most complete)

Adjusting accuracy using grid spacing and resolution

In the get_mra_approx function, we input a parameter called X : a uniform one-dimensional grid expressed as a numpy array. The accuracy of how well a curve can be fit using a basis is highly sensitive to X. If X is a fine grid, it results in high accuracy but also incurs a high computational cost. On the other hand, even a coarse grid can provide fairly accurate results in many cases. But X alone doesn't determine accuracy; when initializing a basis, there is an optional parameter resolution of type float. It determines the support of a single basis function : if a resolution = 1, it means a single basis function has a support of width 1, and if resolution = 0.5, the same basis function is shrunk to half making its support of width 0.5. This means resolution size can be reduced to achieve further gain in accuracy. By default resolution = 1 for most bases. There is an upper bound on accuracy that a basis can achieve with a given resolution, i.e. increasing grid resolution leads to asymptotic increase in accuracy.

But the more critical part is choosing the right X for a given resolution. If resolution is too small and grid size is relatively large, the get_approx_func will result in a highly erroneous fit. A good rule is to assign values to grid spacing and resolution proportionately, for example we can have resolution as a single independent variable and rest of the parameters dependent on it as

resolution = 0.1
N = int(100/resolution)
X = np.linspace(-5, 5, N)

To see this in practice, refer to effect_of_resolution.ipynb notebook in examples

List and plot of wavelet basis in the module

  • HaarBasis HaarBasis
  • HatBasis HatBasis
  • GaussianBasis GaussianBasis
  • GaussletBasis GaussletBasis
  • PlateauGaussletBasis PlateauGaussletBasis
  • SharpGaussletBasis SharpGaussletBasis

About

Repository for multi-resolution analysis with gausslets

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors