Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated classes #22

Merged
merged 1 commit into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions csaps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
from csaps._sspumv import (
SplinePPForm,
CubicSmoothingSpline,
UnivariateCubicSmoothingSpline,
MultivariateCubicSmoothingSpline,
)
from csaps._sspndg import (
NdGridSplinePPForm,
Expand All @@ -39,8 +37,6 @@
'SplinePPForm',
'NdGridSplinePPForm',
'CubicSmoothingSpline',
'UnivariateCubicSmoothingSpline',
'MultivariateCubicSmoothingSpline',
'NdGridCubicSmoothingSpline',

# Type-hints
Expand Down
183 changes: 0 additions & 183 deletions csaps/_sspumv.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import typing as ty
import functools
import warnings

import numpy as np
import scipy.sparse as sp
Expand Down Expand Up @@ -294,185 +293,3 @@ def _make_spline(self, smooth: ty.Optional[float]) -> ty.Tuple[SplinePPForm, flo
spline = SplinePPForm(breaks=self._xdata, coeffs=coeffs)

return spline, p


class UnivariateCubicSmoothingSpline(ISmoothingSpline[SplinePPForm, float, UnivariateDataType]):
__doc__ = CubicSmoothingSpline.__doc__

def __init__(self,
xdata: UnivariateDataType,
ydata: MultivariateDataType,
weights: ty.Optional[UnivariateDataType] = None,
smooth: ty.Optional[float] = None,
axis: int = -1) -> None:
with warnings.catch_warnings():
warnings.simplefilter('always', DeprecationWarning)
warnings.warn(
"'UnivariateCubicSmoothingSpline' class is deprecated "
"and will be removed in the future version. "
"Use 'CubicSmoothingSpline' class instead.", stacklevel=2)

self._cssp = CubicSmoothingSpline(
xdata, ydata, weights=weights, smooth=smooth, axis=axis)

@property
def smooth(self) -> float:
return self._cssp.smooth

@property
def spline(self) -> SplinePPForm:
return self._cssp.spline

def __call__(self, xi: UnivariateDataType) -> np.ndarray:
return self._cssp(xi)


# For case isinstance(CubicSmoothingSpline(...), UnivariateCubicSmoothingSpline)
UnivariateCubicSmoothingSpline.register(CubicSmoothingSpline)


class MultivariateCubicSmoothingSpline(ISmoothingSpline[SplinePPForm, float, UnivariateDataType]):
"""Multivariate parametrized cubic smoothing spline

Class implments multivariate data approximation via cubic smoothing spline with
parametric data sites vector `t`: `X(t), Y(t), ..., M(t)`.

This approach with parametrization allows us to use univariate splines for
approximation multivariate data.

For example:

.. code-block:: python

# 3D data
data = [
# Data vectors Dimension
(2, 4, 1, 3), # X
(1, 4, 3, 2), # Y
(3, 4, 1, 5), # Z
]

x, y, z = 0, 1, 2

t = (0, 1, 2, 3) # parametric vector of data sites (t1 < t2 < ... < tN)

# Construct multivariate spline from t and X, Y, Z
sx = UnivariateCubicSmoothingSpline(t, data[x])
sy = UnivariateCubicSmoothingSpline(t, data[y])
sz = UnivariateCubicSmoothingSpline(t, data[z])

# Or the same with using vectorization
sxyz = UnivariateCubicSmoothingSpline(t, data)

Parameters
----------

ydata : np.ndarray, array-like
Input multivariate data vectors. N-D array.

tdata : [*Optional*] np.ndarray, list
Parametric vector of data sites with condition: `t1 < t2 < ... < tN`.
If it is not set will be computed automatically.

weights : [*Optional*] np.ndarray, list
Weights 1D vector with size equal of N

smooth : [*Optional*] float
Smoothing parameter in range [0, 1] where:
- 0: The smoothing spline is the least-squares straight line fit
- 1: The cubic spline interpolant with natural condition

axis : int
Axis along which "ydata" is assumed to be varying.
Meaning that for x[i] the corresponding values are np.take(ydata, i, axis=axis).
By default is -1 (the last axis).

See Also
--------
UnivariateCubicSmoothingSpline

"""

def __init__(self,
ydata: MultivariateDataType,
tdata: ty.Optional[UnivariateDataType] = None,
weights: ty.Optional[UnivariateDataType] = None,
smooth: ty.Optional[float] = None,
axis: int = -1):

with warnings.catch_warnings():
warnings.simplefilter('always', DeprecationWarning)
warnings.warn(
"'MultivariateCubicSmoothingSpline' class is deprecated "
"and will be removed in the future version. "
"Use 'CubicSmoothingSpline' class instead.", stacklevel=2)

ydata = ty.cast(np.ndarray, np.asarray(ydata, dtype=np.float64))

if tdata is None:
tdata = self._compute_tdata(to_2d(ydata, axis))

tdata = ty.cast(np.ndarray, np.asarray(tdata, dtype=np.float64))

if tdata.size != ydata.shape[-1]: # pragma: no cover
raise ValueError(f'"tdata" size must be equal to "ydata" shape[{axis}] size ({ydata.shape[axis]})')

self._tdata = tdata

# Use vectorization for compute spline for every dimension from t
self._univariate_spline = CubicSmoothingSpline(
xdata=tdata,
ydata=ydata,
weights=weights,
smooth=smooth,
axis=axis,
)

def __call__(self, ti: UnivariateDataType):
return self._univariate_spline(ti)

@property
def smooth(self) -> float:
"""Returns the smoothing parameter

Returns
-------
smooth : float
Smooth factor in the range [0, 1]
"""
return self._univariate_spline.smooth

@property
def spline(self) -> SplinePPForm:
"""Returns the spline description in `SplinePPForm` instance

Returns
-------
spline : SplinePPForm
The spline description in :class:`SplinePPForm` instance
"""
return self._univariate_spline.spline

@property
def t(self) -> np.ndarray:
"""Returns parametrization data vector

Returns
-------
t : np.ndarray
The parametrization data vector
"""
return self._tdata

@staticmethod
def _compute_tdata(data):
"""Computes "natural" t parametrization vector for N-dimensional data

.. code-block::

t_1 = 0
t_i+1 = t_i + sqrt((x_i+1 - x_i)**2 + (y_i+1 - y_i)**2 + ... + (n_i+1 - n_i)**2)
"""
head = 0.
tail = np.sqrt(np.sum(np.diff(data, axis=1) ** 2, axis=0))
return np.cumsum(np.hstack((head, tail)))
2 changes: 1 addition & 1 deletion docs/manual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ The example for univariate data:
>>> print('Spline class name:', type(spline).__name__)
... print('Spline smoothing parameter:', spline.smooth)
... print('Spline description:', spline.spline)
Spline class name: UnivariateCubicSmoothingSpline
Spline class name: CubicSmoothingSpline
Spline smoothing parameter: 0.8999999999999999
Spline description: SplinePPForm
breaks: [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5.]
Expand Down
File renamed without changes.
21 changes: 0 additions & 21 deletions tests/test_multivariate.py

This file was deleted.

File renamed without changes.
18 changes: 9 additions & 9 deletions tests/test_univariate.py → tests/test_umv.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
])
def test_invalid_data(x, y, w):
with pytest.raises(ValueError):
csaps.UnivariateCubicSmoothingSpline(x, y, weights=w)
csaps.CubicSmoothingSpline(x, y, weights=w)


@pytest.mark.parametrize('y', [
Expand Down Expand Up @@ -111,7 +111,7 @@ def test_invalid_data(x, y, w):
def test_vectorize(y):
x = np.arange(np.array(y).shape[-1])

ys = csaps.UnivariateCubicSmoothingSpline(x, y)(x)
ys = csaps.CubicSmoothingSpline(x, y)(x)
np.testing.assert_allclose(ys, y)


Expand All @@ -127,7 +127,7 @@ def test_splineppform(y, order, pieces, ndim):
x = np.arange(np.array(y).shape[-1])
y = np.array(y)

s = csaps.UnivariateCubicSmoothingSpline(x, y).spline
s = csaps.CubicSmoothingSpline(x, y).spline

assert s.order == order
assert s.pieces == pieces
Expand All @@ -153,7 +153,7 @@ def test_axis(shape, axis):
y = np.arange(int(np.prod(shape))).reshape(shape)
x = np.arange(np.array(y).shape[axis])

ys = csaps.UnivariateCubicSmoothingSpline(x, y, axis=axis)(x)
ys = csaps.CubicSmoothingSpline(x, y, axis=axis)(x)

np.testing.assert_allclose(ys, y)

Expand All @@ -162,7 +162,7 @@ def test_zero_smooth():
x = [1., 2., 4., 6.]
y = [2., 4., 5., 7.]

sp = csaps.UnivariateCubicSmoothingSpline(x, y, smooth=0.)
sp = csaps.CubicSmoothingSpline(x, y, smooth=0.)

assert sp.smooth == pytest.approx(0.)

Expand All @@ -180,7 +180,7 @@ def test_auto_smooth():
x = np.linspace(0, 2 * np.pi, 21)
y = np.sin(x) + (np.random.rand(21) - .5) * .1

sp = csaps.UnivariateCubicSmoothingSpline(x, y)
sp = csaps.CubicSmoothingSpline(x, y)

xi = np.linspace(x[0], x[-1], 120)
yi = sp(xi)
Expand Down Expand Up @@ -245,7 +245,7 @@ def test_auto_smooth():
]),
])
def test_npoints(x, y, xi, yid):
sp = csaps.UnivariateCubicSmoothingSpline(x, y)
sp = csaps.CubicSmoothingSpline(x, y)
yi = sp(xi)

np.testing.assert_allclose(yi, yid)
Expand All @@ -264,7 +264,7 @@ def test_weighted(w, yid):
y = [2., 4., 5., 7.]
xi = np.linspace(1., 6., 10)

sp = csaps.UnivariateCubicSmoothingSpline(x, y, weights=w)
sp = csaps.CubicSmoothingSpline(x, y, weights=w)
yi = sp(xi)

np.testing.assert_allclose(yi, yid)
Expand All @@ -276,4 +276,4 @@ def test_big_vectorized():
y = np.random.rand(1000, 10000)
xi = np.linspace(0, 10000, 20000)

csaps.UnivariateCubicSmoothingSpline(x, y)(xi)
csaps.CubicSmoothingSpline(x, y)(xi)