# 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 – Polynomial evaluated with the provided coordinates.

Return type

`xarray.DataArray`

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.
```