geocat.comp.polynomial.ndpolyval
geocat.comp.polynomial.ndpolyval#
- geocat.comp.polynomial.ndpolyval(p, x, axis=0, **kwargs)#
Extended version of numpy.polyval to support multi-dimensional outputs provided by geocat.comp.ndpolyfit.
As the name suggest, this version supports a multi-dimensional p array. Let’s say p is of dimension (s0,s1,s2) and axis=1, then the output would be of dimension (s0, M, s2) where M depends on x. The same way, x could be a multi dimensional array or a single array. In another word, x is either of dimension (M, ), (M, 1), (1, M) or, in this example, of dimension (s0, M, s2). When x is not the vector, it must have the same dimension as of p except for the dimension that is defined by axis.
- Parameters
p (
Iterable
) – Polynomial coeficients.x (
Iterable
) – Coordinates where polynomial must be evaluated.axis (
int
, optional) – The axis along which to evaluate the polynomial. Defaults to 0.**kwargs – Currently not used.
- Returns
output (
xarray.DataArray
) – Polynomial evaluated with the provided coordinates.
Examples
Evaluating a polynomial:
>>> p = [2, 3] # representing y = 2*x + 3 >>> x = np.arange(-5, 6, dtype="float") >>> x array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4., 5.]) >>> from geocat.comp.polynomial import ndpolyval >>> y = ndpolyval(p, x) >>> y.shape (11,) >>> print(y) <xarray.DataArray (dim_0: 11)> array([-7., -5., -3., -1., 1., 3., 5., 7., 9., 11., 13.]) Dimensions without coordinates: dim_0 >>> np.testing.assert_almost_equal(y, 2*x+3)
evaluating a multi-dimensional fitted polynomial:
>>> p = np.tile(np.asarray(p).reshape(1, 2, 1, 1), [3, 1, 4, 5]) >>> p.shape (3, 2, 4, 5) >>> p[1, :, 1, 1] array([2, 3]) >>> p[1, :, 1, 2] array([2, 3]) >>> y = ndpolyval(p, x, axis=1) >>> y.shape (3, 11, 4, 5)
Fitting a first degree polynomial and calculating the residual manually:
>>> from geocat.comp.polynomial import ndpolyfit, ndpolyval >>> import numpy as np >>> n = 10 >>> x = np.linspace(0, 1, n) >>> print(x.shape) (10,) >>> y = np.random.random((3, 4, n, 2, 5)) >>> print(y.shape) (3, 4, 10, 2, 5) >>> # First fitting a first degree polynomial to our 5-Dimensional array ... p = ndpolyfit(x, y, deg=1, axis=2) >>> print("p.shape: ", p.shape) p.shape: (3, 4, 2, 2, 5) >>> # Now re-evaluating the polynomial at the same points: ... y_fitted = ndpolyval(p, x, axis=2) >>> We are ready to manually calculate the residual now: ... signed_residual = y_fitted - y >>> y_fitted.shape (3, 4, 10, 2, 5)
when evaluating x can be another multi-dimensional array
>>> # Let's work on the p that was calculated in previous example ... # using the command: ... # p = ndpolyfit(x, y, deg=1, axis=2) ... print("p.shape: ", p.shape) p.shape: (3, 4, 2, 2, 5)
>>> # Let's pass x which has 20 members this time: ... x = np.random.random(20) >>> print("x.shape: ", x.shape) x.shape: (20,) >>> new_y = ndpolyval(p, x, axis=2) >>> print("new_y.shape: ", new_y.shape) # Note new_y.shape[2] = 20 new_y.shape: (3, 4, 20, 2, 5)
>>> # Now let's make a multi-dimensional x ... # NOTE: all dimension, except axis=2 is the same as the one in p ... # because during fitting step axis was set to 2 ... x = np.random.random((3, 4, 42, 2, 5)) >>> new_y = ndpolyval(p, x, axis=2) >>> print("new_y.shape: ", new_y.shape) # Note new_y.shape[2] = 42 new_y.shape: (3, 4, 42, 2, 5)
>>> # now if a wrongly sized array is passed, you would get an error: ... x = np.random.random((5, 2, 42, 4, 3)) >>> new_y = ndpolyval(p, x, axis=2) Traceback (most recent call last): ... ValueError: x has invalid shape.