GithubHelp home page GithubHelp logo

espdev / csaps Goto Github PK

View Code? Open in Web Editor NEW
161.0 12.0 26.0 2.22 MB

Cubic spline approximation (smoothing)

Home Page: https://csaps.readthedocs.io

License: MIT License

Python 100.00%
splines smoothing smooth csaps approximation cubic-splines python smoothing-splines

csaps's Introduction

csaps

PyPI version Supported Python versions GitHub Actions (Tests) Documentation Status Coverage Status License

csaps is a Python package for univariate, multivariate and n-dimensional grid data approximation using cubic smoothing splines. The package can be useful in practical engineering tasks for data approximation and smoothing.

Installing

Use pip for installing:

pip install -U csaps

The module depends only on NumPy and SciPy. Python 3.9 or above is supported.

Simple Examples

Here is a couple of examples of smoothing data.

An univariate data smoothing:

import numpy as np
import matplotlib.pyplot as plt

from csaps import csaps

np.random.seed(1234)

x = np.linspace(-5., 5., 25)
y = np.exp(-(x/2.5)**2) + (np.random.rand(25) - 0.2) * 0.3
xs = np.linspace(x[0], x[-1], 150)

ys = csaps(x, y, xs, smooth=0.85)

plt.plot(x, y, 'o', xs, ys, '-')
plt.show()

univariate

A surface data smoothing:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from csaps import csaps

np.random.seed(1234)
xdata = [np.linspace(-3, 3, 41), np.linspace(-3.5, 3.5, 31)]
i, j = np.meshgrid(*xdata, indexing='ij')
ydata = (3 * (1 - j)**2. * np.exp(-(j**2) - (i + 1)**2)
         - 10 * (j / 5 - j**3 - i**5) * np.exp(-j**2 - i**2)
         - 1 / 3 * np.exp(-(j + 1)**2 - i**2))
ydata = ydata + (np.random.randn(*ydata.shape) * 0.75)

ydata_s = csaps(xdata, ydata, xdata, smooth=0.988)

fig = plt.figure(figsize=(7, 4.5))
ax = fig.add_subplot(111, projection='3d')
ax.set_facecolor('none')
c = [s['color'] for s in plt.rcParams['axes.prop_cycle']]
ax.plot_wireframe(j, i, ydata, linewidths=0.5, color=c[0], alpha=0.5)
ax.scatter(j, i, ydata, s=10, c=c[0], alpha=0.5)
ax.plot_surface(j, i, ydata_s, color=c[1], linewidth=0, alpha=1.0)
ax.view_init(elev=9., azim=290)

plt.show()

surface

Documentation

More examples of usage and the full documentation can be found at https://csaps.readthedocs.io.

Testing

We use pytest for testing.

cd /path/to/csaps/project/directory
pip install -e .[tests]
pytest

Algorithm and Implementation

csaps Python package is inspired by MATLAB CSAPS function that is an implementation of Fortran routine SMOOTH from PGS (originally written by Carl de Boor).

Also the algothithm implementation in other languages:

  • csaps-rs Rust ndarray/sprs based implementation
  • csaps-cpp C++11 Eigen based implementation (incomplete)

References

C. de Boor, A Practical Guide to Splines, Springer-Verlag, 1978.

License

MIT

csaps's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar espdev avatar shusheer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csaps's Issues

Referene

Hi, Thanks for the good work. Do you have a reference of your formulation? eg mathematical solution for cubic smoothing spline that you used to implement.

Thanks,
Trung

Issue with the smooth parameter.

What the csaps function looks like without smooth parameter:

spline = csaps(x_points, y_points)
plt.plot(x, fit)
plt.scatter(x_points, y_points)
plt.show()

spline_plot_no_smoothing

What the csaps function looks like with any non-default smoothing parameter, even if small:

spline = csaps(x_points, y_points, smooth=.05)
plt.plot(x, fit)
plt.scatter(x_points, y_points)
plt.show()

spline_plot_with_smoothing

Automatic Smoothing Result

Hi!
Thanks for a great package.
Is there any source for how the smoothing parameter "smooth" is determined automatically?
I can not understand where in the code that it is written?
Could you help me by providing the source for the algorithm that is used, or maybe describe here the logic behind it or where in the code that I can find it?

This could be very useful to add to the docs as well?

Thanks a lot in advance.

Is it possible to apply this to a 2D signal (x,y position)?

Hi, this is an amazing content. I would like to filter my 2D signal to obtain both the velocity and acceleration at a time t, in order to estimate a CTRA model. Which method would you recommend to me? I am using the Argoverse Motion Forecasting dataset.

An example of what I am trying to do is as following:

imagen

csaps.CubicSmoothingSpline does not perform natural boundary condition extrapolation correctly

csaps.CubicSmoothingSpline purports to perform extrapolation using the "natural" boundary condition.

From https://github.com/espdev/csaps/blob/master/docs/formulation.rst:
"csaps spline is cubic only and it has natural boundary condition type."

This means the first derivative should be constant outside the range of observations provided to the smoother. This is not currently the behaviour.

Note that the scipy.interpolate.CubicSpline also exhibits the same behaviour, even when we explicitly specify bc_type='natural'

Example code to test:

import matplotlib.pyplot as plt

import numpy as np

from csaps import CubicSmoothingSpline

from scipy.interpolate import CubicSpline

xs = [1,2,3,4,5,6,7,8]
ys = [4.5, 3.6, 1.6, 0.0, -3.3, -3.1, -1.8, -1.7]

csaps_smoother = CubicSmoothingSpline(xs, ys)

scipy_smoother = CubicSpline(xs,ys, bc_type='natural')

extrapolated = np.linspace(min(xs)-10,max(xs)+10,int(21+(max(xs)-min(xs))))


fig, axs = plt.subplots(2, 2,figsize=(12,12))
axs[0, 0].plot(xs, ys,'.')
axs[0, 0].plot(extrapolated,csaps_smoother(extrapolated),'-')
axs[0, 0].set_title('csaps, deriv=0')
axs[0, 1].plot(xs, ys,'.')
axs[0, 1].plot(extrapolated,scipy_smoother(extrapolated),'-')
axs[0, 1].set_title('scipy, deriv=0')
axs[1, 0].plot(xs, csaps_smoother(xs,nu=1),'.')
axs[1, 0].plot(extrapolated,csaps_smoother(extrapolated,nu=1),'-')
axs[1, 0].set_title('csaps, deriv=1')
axs[1, 1].plot(xs, scipy_smoother(xs,nu=1),'.')
axs[1, 1].plot(extrapolated,scipy_smoother(extrapolated,nu=1),'-')
axs[1, 1].set_title('scipy, deriv=1')
plt.show()

I believe this issue is a superset of Issue #46 (periodic functions) wherein csaps.CubicSmoothingSpline._make_spline does not take account of boundary condition.

Performance regression of evaluating n-d grid splines in v1.0.0

It turned out that SciPy NdPPoly spline evaluator if much slower than csaps NdGridSplinePPForm evaluator in v0.11.0. We need to revert evaluate to csaps code that was used previously.

Benchmarks for 2-d data array with input 100x100 and spline evaluating output 3000x3000:

  • csaps v0.11.0: 81.1458 ms min in 12 rounds
  • csaps v1.0.0: 1.0721 s min in 5 rounds

~14x slower

Runtime error when calling np.pad with Numpy < 1.17

Great job on the package!

I got a runtime error from Numpy 1.16 when calling the np.pad function from this line

File "/home/pem/anaconda3/lib/python3.7/site-packages/csaps/_sspumv.py", line 282, in _make_spline
d1 = np.diff(np.pad(u, pad_width), axis=0) / dx
TypeError: pad() missing 1 required positional argument: 'mode'

Turns out that prior to Numpy 1.17, np.pad doesn't provide a default value for the mode parameter. Upgrading Numpy fixed the problem.

It would be helpful if you bump the required Numpy version to 1.17 or higher in your setup.py or provide a default value wherever you call np.pad if you'd like to maintain a wider range of supported Numpy versions.

Update documentation

We need to update the documentation in accordance with #25. Also we can add spline analysis examples.

Input data aspects for smoothing

Hi, Thanks for developing this interesting data smoothing library.

  • I would like to know what does 'Data site' mean, for instance, in a time series data can I use the time stamp attributes for X (as Data site) ? like we sample a chemical temperature and pressure data every 5 seconds. So would X be , X = [5,10,15,20,25,30] in such a case ? and then y could be a ndarray of (temperature and pressure) ?

  • In the above case, Is it correct to specify Xi - (optional) as Xi = [5,10,15,20.25,30] if we expect to get the smoothed data for the same time range as X ? Kindly clarify. Thanks in advance.

results of UnivariateCubicSmoothingSpline for smooth = 0

@espdev Thank you for writing this library. it is awesome and very useful. I noticed that when I use UnivariateCubicSmoothingSpline with smooth = 0, I don't get a straight line, instead, it does "auto smooth".

using the example you gave with smooth = 0 I get:
image

what I expected to get is the following:
image

I believe the root cause for this is that the following if statement in the code would be false for self._smooth = 0:
if self._smooth:
p = self._smooth
else:
p = self._compute_smooth(r, qtwq)

proposed correction:
if (self._smooth or self._smooth==0):
p = self._smooth
else:
p = self._compute_smooth(r, qtwq)

Interpolate on irregular grid

Hi,

as far as I understand, CSAPS is able to work with univariate, multivariate (both depending x being 1dimensional) and ND-gridded data.

In my use case, I have an irregular grid with missing values in random positions. Is it possible to use CSAPS on that kind of data?

As an example, would CSAPS work on data generated like in the scipy.griddata example?

If irregular grids don't work, would it be feasible to use NaNs to fill the grid?

weights per data point in the nd grid case?

Hi, I'm using your package to fit a smoothing sline through gridded (2D) data points, but I'd like to assign an individual weight to each datapoint. However, I only seem to be able to assign weights to dimensions. When I pass a numpy array the size of ydata, I get an error: TypeError: 'weights' must be a sequence of the vectors.

Is there any possibility or workaroung to use the nd case while still using an individual weight per data point?

checking shapes equality is always false in evaluate method

The following condition is always false because we compare list and tuple:

if values.shape != shape:

We need to refactor the code to avoid performing this code in SplinePPForm class. It violates the single responsibility principle and also the encapsulation.

SplinePPForm class should know nothing about:

  • shape
  • axis
  • other things which are not related to evaluating data

The reshaping result array should be performed in the __call__ method of the caller class (CubicSmoothingSpline), but not in SplinePPForm class.

CSAPS on conda-forge

Dear developers,

CSAPS works great, but providing CSAPS only through pypi currently makes it impossible to implement it as a dependency on conda packages (see conda/conda-build#548).

Could you please publish CSAPS on conda-forge?
Many people use conda for package installation/management.

Creating a conda-forge recipe for a PyPI package like CSAPS can be done using the instructions on the conda-forge site.

Cheers,

questions about AutoSmoothingResult

To whom it may concern,

Sorry I'm using a ticket to ask a question, but I couldn't see any other way to contact y'all.

This package looks VERY interesting to me. I've been looking for a python implementation of DeBoor smoothing splines, and was afraid I'd have to implement it myself. However, I have a few questions.

First, how does AutoSmoothingResult work? What criterion does it use to find a smoothing parameter? (may I suggest the answer be put in the documentation?)

Second, scipy univariate smoothing splines have an option where essentially you set the desired chi-squared fit and the algorithm automatically adjusts the number of knots until that condition is met. Does csaps have a similar option? (except instead of adjusting knots, the smoothing paramter is adjusted ofc), that is, something like the second equation under "de Boors approach" on the page https://en.wikipedia.org/wiki/Smoothing_spline.

Thanks!

csaps.CubicSmoothingSpline does not handle periodic functions correctly

csaps.CubicSmoothingSpline purports to support periodic functions, but does not implement this correctly.

I believe this is because it is a smoothing spline, which means that there are far more knots stored than "effective knots" due to smoothing. This means that when the periodic function is used by the underlying scipy implementation, which likely only looks at the first and last knots, you get a sharp discontinuity.

This is all purely speculation!

A not-brilliant-fix is to repeat your data -1 and +1 period and fit just the usual (non-periodic) smoothed spline to this. There will not be any huge discontinuity, but this does not guarantee that your endpoints will match exactly, so it's better but not perfect. Note that you can't have identical x values in your input, so you need to offset very slightly, or average your endpoints.

The correct solution is probably to have the smoother correctly consider periodic functions, either when you generate the smoother with CubicSmoothingSpline() which would require an additional parameter for periodic functions, or re-implementing the underlying scipy for interpolating/extrapolating (which is probably more work).

You can test this with the following code:

import numpy as np
import matplotlib.pyplot as plt

from csaps import csaps

np.random.seed(1234)

x = np.linspace(-5., 5., 25)
y = np.exp(-(x/2.5)**2) + (np.random.rand(25) - 0.2) * 0.3

smoother = csaps(x, y, smooth=0.85)

xs = np.linspace(-6.5, 6.5, 100)

ys = smoother(xs)
ys_periodic = smoother(xs, extrapolate='periodic')

better_smoother = csaps(np.r_[x-10.001,x,x+10.001], np.r_[y,y,y], smooth=0.85)

ys_better = better_smoother(xs)

plt.plot(x, y, 'o', xs, ys, '-', xs, ys_periodic, '-', xs, ys_better, '-')
plt.show()

print("non-periodic", smoother([-5,5]))
print("periodic",smoother([-5,5], extrapolate='periodic'))
print("better, but not perfect",better_smoother([-5,5]))

Question: smoothing clamped spline

Hi!
Thanks for this great package.
Currently the smoothing spline is based on natural boundary, is there any possibility we can smooth a clamped spline?

Spline from auto-computed smooth with normalizedsmooth=True doesn't match using that smooth value directly

Hi, thanks for this package.

I stumbled across some behavior I didn't expect. In the following code, I'm computing a smoothing factor automatically with normalizedsmooth=True. If I then use the resulting smooth value, keeping normalizedsmooth=True, the smoothed result is different. Any idea why?

import numpy as np
from csaps import csaps

n = 25

x = np.linspace(-5., 5., n)
y = np.exp(-(x/2.5)**2) + (np.random.rand(n) - 0.2) * 0.3
xi = np.linspace(-5., 5., 150)

is_normalized = True

# Smooth data and compute smoothing factor automatically
yi_auto, smooth = csaps(x, y, xi, normalizedsmooth=is_normalized)

# Smooth data with smoothing factor 0.85
yi_explicit = csaps(x, y, xi, smooth=smooth, normalizedsmooth=is_normalized)

print(np.array_equal(yi_auto, yi_explicit))
print(yi_auto[0], yi_explicit[0])

csaps.CubicSmoothingSpline provides incorrect derivatives under certain circumstances

Certain arrangements of smoothing intensity, weights and xdata, in particular irregularly spaced data where some xvalues are rather close together, causes CubicSmoothingSpline to produce a first derivative that is not the integral of the second derivative. This can be exacerbated by certain weights. In particular, the first derivative can be very non-smooth, even though the second derivative is smooth.

This is important, because a very common use-case for CubicSmoothingSpline (as opposed to say LOWESS smoothing) is to ensure smooth derivatives.

There are at least two possible solutions:
1 - modifying x-values or combining close points, for some definition of close (might be very data-specific).
2 - Sequentially integrating derivatives from the 3rd upwards, to enforce correct 1st and 2nd derivatives (might be quite computationally expensive).
3 - Converting to compressed scipy.CubicSpline form using code discussed at #46 (comment) also avoids this problem, as the spline is effectively resampled at optimally distributed x values.

Code demonstrating the problem (apologies for the large amount of data in the test case - it's some real data from a project I am working on, and I haven't been able to determine exactly which features are causing the problem, though enforcing a minimum x spacing seems to work as shown, and removing weights reduces the issue but doesn't eliminate it).

As you can see, the resulting splines all give quite different estimates of the data, so what we mean by "correct" is up for discussion.

# Problem case giving unsmooth derivatives
# The first derivative of the smoothed function is NOT the integral of the second derivative
# (notice small discontinuities / steps)
# This is particularly acute when certain weight values play a part as well

x = [-288.55699074,-288.28206019,-287.66591435,-287.64053241,-286.65069444,
-286.65068866,-285.52694444,-285.23972222,-284.64372685,-284.44784722,
-283.38444444,-283.38365741,-282.55511574,-282.53914352,-281.63871528,
-280.46857639,-280.46855324,-278.46340278,-278.37118056,-277.58601852,
-277.58574074,-276.54689815,-276.54663194,-275.62396991,-274.54616898,
-274.54615741,-273.55909722,-273.38333333,-272.57217593,-272.5721412,
-269.7065625,-269.51540509,-268.61980324,-268.60930556,-267.57458333,
-267.57457755,-263.58122685,-259.53576389,-258.82375,-258.82333333,
-257.85988426,-257.85986111,-254.25375,-254.25374421,-253.60337963,
-253.60333333,-251.7546875,-251.75461806,-250.94400463,-247.44850694,
-244.78422454,-244.7834838,-243.80513889,-243.80423611,-242.545625,
-242.54511574,-241.58532407,-241.58527778,-240.53894676,-240.53893519,
-239.59284722,-239.59278935,-234.86810185,-234.86706019,-229.50280093,
-229.50270833,-228.67150463,-228.67148148,-227.83733796,-227.63991898,
-225.75958333,-225.75953704,-224.77252315,-224.77251157,-223.98796296,
-223.98793981,-222.53775463,-222.53773148,-221.47532407,-219.68340278,
-219.6830787,-218.77277778,-218.77275463,-216.28890046,-216.28887731,
-215.52909722,-214.40041667,-214.40039352,-212.61553241,-212.61550926,
-211.81768519,-211.47722222,-211.47716435,-208.37016204,-208.36606481,
-207.62565972,-206.73474537,-206.73467593,-205.8547338,-205.83864583,
-204.94078704,-204.85533565,-203.72707176,-203.72493056,-203.72258102,
-203.57979167,-203.57978009,-202.72645833,-202.68732639,-202.54818287,
-201.68228009,-201.51018519,-201.43820602,-200.49405093,-200.49201389,
-199.62027778,-199.50150463,-199.50037037,-199.49247685,-198.74945602,
-198.74351852,-197.64726852,-197.6459375,-197.48726852,-196.49546296,
-196.43032407,-195.52611111,-195.46309028,-194.50974537,-194.50868056,
-193.46177083,-193.46171296,-192.88958333,-192.88957176,-191.64532407,
-191.64497685,-190.5394213,-190.51228009,-189.69407407,-189.69158565,
-188.55555556,-188.43287037,-186.77581019,-186.76670139,-184.90331019,
-184.90259259,-182.46954861,-182.46900463,-181.82518519,-180.79622685,
-180.79261574,-179.48037037,-179.47877315,-178.50547454,-178.50518519,
-177.54893519,-177.5484838,-176.70898148,-176.70897569,-172.47497685,
-171.58761574,-171.58756944,-169.23037037,-169.19318287,-168.54819444,
-165.79189815,-165.79189236,-165.79136574,-164.7587037,-164.75511574,
-161.85717593,-161.85717014,-160.74731481,-160.74730903,-156.4134838,
-156.41269676,-155.81989583,-155.81988426,-154.45269676,-154.43328704,
-153.80079861,-153.80032407,-152.54888889,-152.54819444,-148.93758102,
-147.84275463,-147.84274884,-146.98821759,-145.84561343,-145.84560185,
-140.25047454,-140.25046296,-138.99819444,-138.99818866,-137.92916667,
-137.85449074,-136.48898148,-136.48894676,-124.4325,-122.78548611,
-122.78547454,-121.78831019,-121.7624537,-119.5171875,-119.51571759,
-118.54518519,-118.54511574,-116.81631944,-116.6050463,-115.41570602,
-115.41196759,-114.53983796,-114.51606481,-112.65020833,-112.59722222,
-111.58196759,-111.58173611,-110.28418981,-108.88050926,-108.88037037,
-106.58741898,-106.58740741,-105.82334491,-105.61048611,-102.78446759,
-102.78175926,-101.92847222,-101.92841435,-99.70208333,-99.66606481,
-98.69592593,-98.69592014,-97.68861111,-96.54909722,-96.43082176,
-93.6450463,-93.64504051,-91.82571759,-91.82571181,-83.88231481,
-83.88003472,-82.53726852,-81.8415162,-81.78796296,-78.41912037,
-77.88599537,-77.88598958,-75.8,-75.79999421,-74.91194444,
-74.91193866,-70.52842593,-70.52751157,-66.66107639,-66.49625,
-64.62689815,-64.62497685,-63.84877315,-62.67493056,-62.67486111,
-56.45991898,-56.45849537,-55.80101852,-53.5209375,-53.42854167,
-51.79412037,-51.70625,-50.72030093,-50.72027778,-49.55359954,
-48.56030093,-48.52893519,-47.61050926,-47.61006944,-45.62118056,
-45.61965278,-43.70581019,-43.70578704,-42.61976852,-42.61907407,
-41.67361111,-41.64385417,-32.35585648,-31.6496875,-31.64862269,
-17.80746528,-17.77924769,-16.75157407,-16.75155093,-15.57109954,
-15.57106481,-14.64717593,-13.72175926,-13.67280093,-12.61773148,
-10.63041667,-10.63005787,-9.80740741,-9.80736111,-8.71253472,
-8.70666667,-6.74260417,-6.74258102,-5.34083333,-4.91016204,
-4.90943287,-2.30743056,-2.30638889,-0.42960648,-0.42840278]

y = [70.7572706,70.54032874,70.05606702,70.03624935,69.27432557,
69.27432117,68.43243561,68.22067996,67.78516637,67.64308661,
66.88118275,66.88062559,66.30052443,66.28947425,65.67543639,
64.90642245,64.90640759,63.66449628,63.60904412,63.14039473,
63.14022978,62.52515116,62.52499365,61.97652441,61.32001027,
61.32000308,60.68789985,60.57033966,60.00261623,60.00259097,
57.61865841,57.43806534,56.55456891,56.54383346,55.43956239,
55.43955595,50.38210045,44.53858607,43.50952278,43.50892299,
42.12805664,42.12802358,36.99275737,36.99274908,36.05906926,
36.05900272,33.41368763,33.41358922,32.27359692,27.70135708,
24.84323913,24.84254672,23.98532718,23.98459096,23.0642553,
23.0639276,22.5150554,22.51503233,22.08034126,22.08033742,
21.8389586,21.8389484,23.10692951,23.10771641,29.81761462,
29.81776653,31.21601939,31.21605924,32.68017101,33.03425222,
36.54083419,36.54092348,38.47670459,38.47672766,40.0590836,
40.05913083,43.0771602,43.07720928,45.35765585,49.31879272,
49.31952077,51.38303931,51.38309234,57.16432204,57.16437592,
58.92167454,61.46687347,61.46692457,65.24326265,65.24330938,
66.81838801,67.46953204,67.46964169,72.89983173,72.90644953,
74.08206155,75.44675245,75.44685685,76.74713302,76.77050437,
78.05420313,78.17438359,79.7183499,79.72118421,79.72429379,
79.91227229,79.91228745,80.99326008,81.04109716,81.20997602,
82.219385,82.41175016,82.49142149,83.49504942,83.49713412,
84.36266061,84.47724037,84.47833159,84.4859241,85.18879314,
85.19431565,86.18839601,86.18957211,86.32923784,87.17818962,
87.23249526,87.96788031,88.01785229,88.75344863,88.75424891,
89.51806878,89.51810973,89.91613619,89.91614411,90.73453049,
90.73474985,91.40125092,91.41664377,91.85156726,91.85279549,
92.34222988,92.38575227,92.75900826,92.75984105,92.59792734,
92.59772702,91.20024149,91.19975484,90.56381405,89.28641717,
89.28134229,87.14597333,87.14300865,85.15861765,85.15797276,
82.84855607,82.84738518,80.54827418,80.54825753,66.28762042,
63.00718054,63.00700893,54.31636812,54.18091963,51.84551574,
42.2968528,42.29683372,42.29509707,38.97123725,38.95998918,
30.75854662,30.75853234,28.19489508,28.19488261,21.31146526,
21.31063361,20.72423984,20.72422916,19.66675016,19.65459906,
19.30037669,19.30014055,18.82393793,18.82375279,18.89283954,
19.25883033,19.25883262,19.63216496,20.23324209,20.2332487,
24.12129249,24.12130103,25.03004562,25.03004973,25.76826801,
25.81806455,26.67629851,26.67631891,30.46561539,30.74262981,
30.74263179,30.91672453,30.92128596,31.30818311,31.3084222,
31.4588991,31.45890927,31.69236101,31.71975256,31.87221841,
31.87267866,31.9724062,31.97484795,32.10544092,32.10723373,
32.11864839,32.11864583,32.06417118,31.90691934,31.90689831,
31.39692865,31.3969252,31.14906127,31.07254683,29.76210069,
29.76059886,29.26593574,29.26590077,27.78880075,27.76287183,
27.0440895,27.04408511,26.26627309,25.36699318,25.27332511,
23.11069468,23.11069035,21.80609638,21.80609244,18.29594004,
18.295638,18.20182827,18.21706169,18.22000001,18.82965191,
18.98616378,18.98616554,19.69017271,19.6901748,20.01523736,
20.0152395,21.42764295,21.42784833,21.84871481,21.84950598,
21.78327154,21.78313985,21.72088105,21.59779516,21.59778708,
20.92961501,20.92955839,20.91266214,21.04288478,21.05619122,
21.41830913,21.44484473,21.79485625,21.79486561,22.3360831,
22.90340539,22.92289613,23.5358956,23.53620858,25.13688862,
25.13825808,27.00134805,27.00137215,28.16778118,28.16854978,
29.24170683,29.27634617,42.20507624,43.32162108,43.32331588,
68.1726824,68.22889458,70.29050421,70.29055095,72.69085058,
72.69092166,74.59109794,76.51130697,76.6133282,78.82157314,
83.02355351,83.0243163,84.77591304,84.77601173,87.11188547,
87.12441636,91.32441849,91.32446806,94.32811947,95.25177267,
95.25333675,100.83484899,100.83708178,104.85695,104.85952725]

w = [0.09462211,0.04377652,0.14838558,0.05943898,0.15541495,0.13085324,
0.062704,0.06243595,0.08839641,0.08066833,0.08655245,0.13400375,
0.12432887,0.09684014,0.08021506,0.1265312,0.05262315,0.06449225,
0.0758878,0.08259978,0.0806998,0.18695698,0.08123137,0.07486425,
0.12497271,0.10635125,0.15783934,0.08400718,0.24832489,0.12591398,
0.75945646,0.13893085,0.07963481,0.10749733,0.12091365,0.06358539,
0.01520488,0.03701155,0.16559939,0.21220943,0.08161835,0.16941486,
0.08949668,0.13363251,0.09692045,0.18369284,0.13672927,0.08379181,
0.01858722,0.01133573,0.06237293,0.24676197,0.10859054,0.12052321,
0.13203374,0.14501103,0.14774643,0.09328596,0.04971943,0.15257333,
0.28338405,0.09501884,0.98374631,0.05226721,0.09065792,0.13678137,
0.09321165,0.44103697,0.06999414,0.05989127,0.12692356,0.0915057,
0.11936501,0.10480617,0.1567755,0.07513431,0.07117161,0.06858016,
0.01640047,0.29806503,0.22542,0.12794823,0.21382192,0.80778319,
0.05041481,0.02423374,0.14427077,0.10418953,0.21508381,0.10940715,
0.04888315,0.04528401,0.04778175,0.11278799,0.43211842,0.03932949,
0.11803702,0.07236406,0.09973482,0.11787877,0.10316486,0.03396932,
0.07494178,0.0980055,0.15682156,0.39430807,0.2966579,0.0321651,
0.04839777,0.09632106,0.08455145,0.03593526,0.09416399,0.1499288,
0.20404766,0.05393556,0.05599547,0.08508938,0.03143724,0.03516901,
0.48995939,0.22142592,0.05018331,0.02789187,0.02197713,0.03036933,
0.20079765,0.0914527,0.04390079,0.0632086,0.12006129,0.04469976,
0.10379572,0.06173869,0.04413667,0.03245433,0.1633229,0.0436747,
0.06350709,0.05263706,0.04127021,0.04639606,0.06203611,0.0542154,
0.04355763,0.0831866,0.03767251,0.04846966,0.01901781,0.24288383,
0.05686747,0.0987101,0.11008607,0.0864383,0.17024615,0.23189691,
0.13231802,0.11141714,0.11234526,0.04201772,0.10555506,0.23622534,
0.15991181,0.07504075,0.08703826,0.078157,0.07949321,0.29557024,
0.0676124,0.16409294,0.24457436,0.10823184,0.14073518,0.35402206,
0.13634875,0.08048864,0.11152011,0.0714971,0.11998616,0.07697284,
0.08883651,0.08903601,0.12036493,0.07058305,0.01155317,0.08867653,
0.21117371,0.05630087,0.0809992,0.27670459,0.26026519,0.13855529,
0.15380278,0.23979833,0.20920358,0.1440551,0.13541747,0.1463744,
0.04642054,0.24201843,0.11214505,0.18320577,0.04986542,0.19388245,
0.07125025,0.22815885,0.08084224,0.06743765,0.28559653,0.11051846,
1.71124858,0.10948372,0.1427056,0.14208709,0.21579165,0.14818066,
0.10186744,0.02192575,0.07098707,0.09253821,0.13900954,0.12502331,
0.06113228,0.15379208,0.05778127,0.25567184,0.12133423,0.1361762,
0.06835819,0.17893468,0.07440845,0.05984869,0.02637486,0.06455977,
0.05552673,0.16468979,0.06516525,0.06218418,0.10451724,0.4187673,
0.08585429,0.02827772,0.19387362,0.0435158,0.02646894,0.16485791,
0.12165923,0.11332932,0.06376871,0.1044266,0.059728,0.14428556,
0.10856501,0.16783946,0.12808263,0.06199017,0.112075,0.04430589,
0.17411464,0.09521449,0.05556677,0.10710905,0.16484723,0.09197195,
0.09080481,0.11942555,0.29181033,0.05171834,0.10642797,0.0591445,
0.07264419,0.05472201,0.07241181,0.07863706,0.05298894,0.17034628,
0.13621438,0.12312648,0.20335133,0.10124627,0.08194233,0.08727886,
0.07454792,0.17554491,0.13723729,0.04581896,0.11138872,0.09357495,
0.09733723,0.21097312,0.05863559,0.02409536,0.11577836,0.08534116,
0.02837538,0.09877817,0.03943265,0.09397333,0.16018314,0.09669458,
0.18185679,0.11361261,0.07640622,0.0501189,0.1409333,0.04278513,
0.08166752,0.0946821,0.138107,0.05173292]

xrnd = np.rint(np.array(x)*25.)/25.
xrndv = xrnd[1:]
xrndv[np.flatnonzero(np.diff(xrnd)==0)]+=1./50.
xrndv[np.flatnonzero(np.diff(xrnd)==0)]+=1./100.

xs = np.unique(np.r_[x[0]+np.cumsum(np.repeat(np.diff(x)/4,4)),np.linspace(x[0], x[-1], len(x)*10)])

unweighted = CubicSmoothingSpline(x, y, smooth=5e-06)
weighted = CubicSmoothingSpline(x, y, weights=w, smooth=5e-06)
weightedimprovedx = CubicSmoothingSpline(xrnd, y, weights=w, smooth=5e-06)

def CubicSplineFromCubicSmoothingSpline(smoothing_spline, xrange=None, bc_type='natural', extrapolate=None):
    # If using this to generate a periodic spline from  a csaps spline, data is usually replicated
    # Therefore restrict the xrange to the actual period to be modelled
    x = smoothing_spline.spline.breaks
    y3 = smoothing_spline.spline.coeffs[0,:]*6
    if xrange:
        assert xrange[0] < xrange[1]
        xminidx = max(0,np.flatnonzero(np.r_[xrange[0],x]<=xrange[0])[-1]-1)
        xmaxidx = min(x.size-1,np.flatnonzero(np.r_[x,xrange[1]]>=xrange[1])[0])
        x = x[xminidx:xmaxidx+1].copy()
        x[0]=max(xrange[0],x[0])
        x[-1]=min(xrange[1],x[-1])
        y3 = y3[xminidx:xmaxidx+1]
    idxs_to_use = [0,x.size-1]
    idx_before_zero_crossings = np.where(np.diff(np.sign(y3)))[0]
    idxs_to_use.extend(idx_before_zero_crossings.tolist())
    for aidx,bidx in zip(np.r_[0,idx_before_zero_crossings],np.r_[idx_before_zero_crossings,x.size-1]):
        idx = np.argmax(np.abs(y3[aidx:bidx+1]))+aidx
        idxs_to_use.append(idx)
    x_compressed = np.unique(x[idxs_to_use])
    y_compressed = smoothing_spline(x_compressed)
    if bc_type=='periodic':
        y_compressed[0] = y_compressed[-1] = np.mean(y_compressed[[0,-1]])
    return CubicSpline(x_compressed, y_compressed, bc_type=bc_type, extrapolate=extrapolate)

compressedspline = CubicSplineFromCubicSmoothingSpline(weighted)

plt.plot(xs, unweighted(xs), '-', xs, weighted(xs), '-', xs, weightedimprovedx(xs), '-', xs, compressedspline(xs), '-', x, y, 'o')
plt.show()

for nu in range(1,4):
    fig,(ax1,ax2,ax3,ax4)=plt.subplots(1, 4, figsize=(12,4))
    ax1.plot(xs, unweighted(xs,nu=nu), '-')
    ax1.title.set_text('unweighted nu='+str(nu))
    ax2.plot(xs, weighted(xs,nu=nu), '-')
    ax2.title.set_text('weighted nu='+str(nu))
    ax3.plot(xs, weightedimprovedx(xs,nu=nu), '-')
    ax3.title.set_text('weighted, improved x nu='+str(nu))
    ax4.plot(xs, compressedspline(xs,nu=nu), '-')
    ax4.title.set_text('compressed spline nu='+str(nu))
    plt.show()

Roughness weights

Any plans to implement roughness weights, which are still not implemented but this is extremely important feature!!! (see #59 (comment) )?

Derivative of Spline Surface

Hi Eugene,

I came across your package trying to replicate some analysis that had been done in Matlab using csaps. The tool works perfectly, however the analysis I'm replicating used the Matlab function fnders to return the derivative of the spline surface fitted using csaps.

Is there a way to do this in your package, or is it something you would consider as an additional feature?

Many thanks again for the tool.

Best Regards,

Ben

How to cite

Hey,
I'm using your csaps package in a academic context and would like to add a reference to it. Do you have a preferred way on how you would like to be cited, e.g. a bibtex entry or something?

Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.