From ce0593ca87594f14c506d0fc0946bf1fb8656018 Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Mon, 21 Oct 2024 23:07:16 -0700 Subject: [PATCH 1/9] moved examples from old branch --- src/nemos/basis.py | 135 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 1b0c9f12..22401c7e 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -204,6 +204,18 @@ def fit(self, X: FeatureMatrix, y=None): ------- self : The transformer object. + + Examples + -------- + # Example input + >>> import numpy as np + >>> X, y = np.random.normal(size=(100, 2)), np.random.uniform(size=100) + + # Define and fit tranformation basis + >>> from nemos.basis import MSplineBasis, TransformerBasis + >>> basis = MSplineBasis(10) + >>> transformer = TransformerBasis(basis) + >>> transformer_fitted = transformer.fit(X) # input must be a 2d array """ self._basis._set_kernel(*self._unpack_inputs(X)) return self @@ -223,6 +235,28 @@ def transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: ------- : The data transformed by the basis functions. + + Examples + -------- + >>> # Example input + >>> import numpy as np + >>> X, y = np.random.normal(size=(100, 2)), np.random.uniform(size=100) + + >>> # Define and fit tranformation basis + >>> from nemos.basis import MSplineBasis, TransformerBasis + >>> basis = MSplineBasis(10, mode="conv", window_size=200) + >>> transformer = TransformerBasis(basis) + >>> transformer_fitted = transformer.fit(X) # input must be a 2d array + >>> # Before calling `fit` the convolution kernel is not set + >>> transformer.kernel_ + + >>> transformer_fitted = transformer.fit(X) # input must be a 2d array + >>> # Now the convolution kernel is initialized and has shape (window_size, n_basis_funcs) + >>> transformer_fitted.kernel.shape + (200, 10) + + >>> # Transform basis + >>> feature_transformed = transformer.transform(X[:, 0:1]) # input must be a 2d array, (num_samples, 1) """ # transpose does not work with pynapple # can't use func(*X.T) to unwrap @@ -248,6 +282,20 @@ def fit_transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: array-like The data transformed by the basis functions, after fitting the basis functions to the data. + + Examples + -------- + >>> # Example input + >>> import numpy as np + >>> X, y = np.random.normal(size=(100, 1)), np.random.uniform(size=100) + + >>> # Define tranformation basis + >>> from nemos.basis import MSplineBasis, TransformerBasis + >>> basis = MSplineBasis(10) + >>> transformer = TransformerBasis(basis) + + >>> # Fit and transform basis + >>> feature_transformed = transformer.fit_transform(X) # input must be a 2d array, (num_samples, 1) """ return self._basis.compute_features(*self._unpack_inputs(X)) @@ -882,6 +930,23 @@ def evaluate_on_grid(self, *n_samples: int) -> Tuple[Tuple[NDArray], NDArray]: This differs from the numpy.meshgrid default, which uses Cartesian indexing. For the same input, Cartesian indexing would return an output of shape $(M_2, M_1, M_3, ....,M_N)$. + Examples + -------- + >>> # Evaluate and visualize 4 M-spline basis functions of order 3: + >>> import numpy as np + >>> import matplotlib.pyplot as plt + >>> from nemos.basis import MSplineBasis + >>> mspline_basis = MSplineBasis(n_basis_funcs=4, order=3) + >>> sample_points, basis_values = mspline_basis.evaluate_on_grid(100) + >>> for i in range(4): + ... p = plt.plot(sample_points, basis_values[:, i], label=f'Function {i+1}') + >>> plt.title('M-Spline Basis Functions') + Text(0.5, 1.0, 'M-Spline Basis Functions') + >>> plt.xlabel('Domain') + Text(0.5, 0, 'Domain') + >>> plt.ylabel('Basis Function Value') + Text(0, 0.5, 'Basis Function Value') + >>> l = plt.legend() """ self._check_input_dimensionality(n_samples) @@ -1071,7 +1136,29 @@ class AdditiveBasis(Basis): n_basis_funcs : int Number of basis functions. - + Examples + -------- + >>> # Generate sample data + >>> import numpy as np + >>> import nemos as nmo + >>> X, y = np.random.normal(size=(30, 2)), np.random.poisson(size=30) + >>> # X.shape is (n_samples, n_inputs), where n_inputs is the number required by the basis + + >>> # define two basis objects and add them + >>> basis_1 = nmo.basis.BSplineBasis(10) + >>> basis_2 = nmo.basis.RaisedCosineBasisLinear(15) + >>> additive_basis = nmo.basis.AdditiveBasis(basis1=basis_1, basis2=basis_2) + >>> transformed_X = additive_basis.to_transformer().transform(X) + >>> print(transformed_X.shape) + (30, 25) + + >>> # can add another basis to the AdditiveBasis object + >>> X = np.random.normal(size=(30, 3)) + >>> basis_3 = nmo.basis.RaisedCosineBasisLog(100) + >>> additive_basis_2 = additive_basis + basis_3 + >>> transformed_X = additive_basis_2.to_transformer().transform(X) + >>> print(transformed_X.shape) + (30, 125) """ def __init__(self, basis1: Basis, basis2: Basis) -> None: @@ -1182,7 +1269,29 @@ class MultiplicativeBasis(Basis): ---------- n_basis_funcs : int Number of basis functions. - + + Examples + -------- + >>> # Generate sample data + >>> import numpy as np + >>> import nemos as nmo + >>> X, y = np.random.normal(size=(30, 3)), np.random.poisson(size=30) + + >>> # define two basis and multiply + >>> basis_1 = nmo.basis.BSplineBasis(10) + >>> basis_2 = nmo.basis.RaisedCosineBasisLinear(15) + >>> multiplicative_basis = nmo.basis.MultiplicativeBasis(basis1=basis_1, basis2=basis_2) + >>> transformed_X = multiplicative_basis.to_transformer().transform(X[:, 0:2]) + >>> print(transformed_X.shape) + (30, 150) + + >>> # Can multiply or add another basis to the AdditiveBasis object + >>> # This will cause the number of output features of the result basis to grow accordingly + >>> basis_3 = nmo.basis.RaisedCosineBasisLog(100) + >>> multiplicative_basis_2 = multiplicative_basis * basis_3 + >>> transformed_X = multiplicative_basis_2.to_transformer().transform(X) + >>> print(transformed_X.shape) + (30, 15000) """ def __init__(self, basis1: Basis, basis2: Basis) -> None: @@ -1613,7 +1722,17 @@ class BSplineBasis(SplineBasis): ------------ [1] Prautzsch, H., Boehm, W., Paluszny, M. (2002). B-spline representation. In: Bézier and B-Spline Techniques. Mathematics and Visualization. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-662-04919-8_5 + + Examples + -------- + >>> from numpy import linspace + >>> from nemos.basis import BSplineBasis + >>> bspline_basis = BSplineBasis(n_basis_funcs=5, order=3) + >>> bspline_transformer = bspline_basis.to_transformer() + + >>> sample_points = linspace(0, 1, 100) + >>> basis_functions = bspline_basis(sample_points) """ def __init__( @@ -2453,6 +2572,18 @@ def bspline( Notes ----- The function uses splev function from scipy.interpolate library for the basis evaluation. + + Examples + -------- + >>> import numpy as np + >>> from numpy import linspace + >>> from nemos.basis import bspline + + >>> sample_points = linspace(0, 1, 100) + >>> knots = knots = BSplineBasis(10)._generate_knots(sample_points) + >>> bspline_eval = bspline(sample_points, knots) # define a cubic B-spline + >>> bspline_eval.shape + (100, 10) """ knots.sort() nk = knots.shape[0] From 03b80db66a037746a5e6803afe4def917bfbe243 Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Tue, 22 Oct 2024 11:19:34 -0700 Subject: [PATCH 2/9] tox fixes --- src/nemos/basis.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 22401c7e..791a5ed4 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -244,17 +244,17 @@ def transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: >>> # Define and fit tranformation basis >>> from nemos.basis import MSplineBasis, TransformerBasis - >>> basis = MSplineBasis(10, mode="conv", window_size=200) + >>> basis = MSplineBasis(10, mode="conv", window_size=200) >>> transformer = TransformerBasis(basis) >>> transformer_fitted = transformer.fit(X) # input must be a 2d array - >>> # Before calling `fit` the convolution kernel is not set - >>> transformer.kernel_ - - >>> transformer_fitted = transformer.fit(X) # input must be a 2d array - >>> # Now the convolution kernel is initialized and has shape (window_size, n_basis_funcs) - >>> transformer_fitted.kernel.shape - (200, 10) - + >>> # Before calling `fit` the convolution kernel is not set + >>> transformer.kernel_ + + >>> transformer_fitted = transformer.fit(X) # input must be a 2d array + >>> # Now the convolution kernel is initialized and has shape (window_size, n_basis_funcs) + >>> transformer_fitted.kernel.shape + (200, 10) + >>> # Transform basis >>> feature_transformed = transformer.transform(X[:, 0:1]) # input must be a 2d array, (num_samples, 1) """ @@ -287,7 +287,7 @@ def fit_transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: -------- >>> # Example input >>> import numpy as np - >>> X, y = np.random.normal(size=(100, 1)), np.random.uniform(size=100) + >>> X, y = np.random.normal(size=(100, 1)), np.random.uniform(size=100) >>> # Define tranformation basis >>> from nemos.basis import MSplineBasis, TransformerBasis @@ -295,7 +295,7 @@ def fit_transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: >>> transformer = TransformerBasis(basis) >>> # Fit and transform basis - >>> feature_transformed = transformer.fit_transform(X) # input must be a 2d array, (num_samples, 1) + >>> feature_transformed = transformer.fit_transform(X) # input must be a 2d array, (num_samples, 1) """ return self._basis.compute_features(*self._unpack_inputs(X)) @@ -1142,7 +1142,7 @@ class AdditiveBasis(Basis): >>> import numpy as np >>> import nemos as nmo >>> X, y = np.random.normal(size=(30, 2)), np.random.poisson(size=30) - >>> # X.shape is (n_samples, n_inputs), where n_inputs is the number required by the basis + >>> # X.shape is (n_samples, n_inputs), where n_inputs is the number required by the basis >>> # define two basis objects and add them >>> basis_1 = nmo.basis.BSplineBasis(10) @@ -1269,7 +1269,7 @@ class MultiplicativeBasis(Basis): ---------- n_basis_funcs : int Number of basis functions. - + Examples -------- >>> # Generate sample data @@ -1722,7 +1722,7 @@ class BSplineBasis(SplineBasis): ------------ [1] Prautzsch, H., Boehm, W., Paluszny, M. (2002). B-spline representation. In: Bézier and B-Spline Techniques. Mathematics and Visualization. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-662-04919-8_5 - + Examples -------- >>> from numpy import linspace From d85917ab475586b76c06e7198f78071905ba7512 Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Wed, 23 Oct 2024 10:31:52 -0700 Subject: [PATCH 3/9] fixed failing doc test --- src/nemos/basis.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 791a5ed4..78820518 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -240,19 +240,18 @@ def transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: -------- >>> # Example input >>> import numpy as np - >>> X, y = np.random.normal(size=(100, 2)), np.random.uniform(size=100) + >>> X, y = np.random.normal(size=(10000, 2)), np.random.uniform(size=100) >>> # Define and fit tranformation basis >>> from nemos.basis import MSplineBasis, TransformerBasis >>> basis = MSplineBasis(10, mode="conv", window_size=200) >>> transformer = TransformerBasis(basis) - >>> transformer_fitted = transformer.fit(X) # input must be a 2d array >>> # Before calling `fit` the convolution kernel is not set >>> transformer.kernel_ >>> transformer_fitted = transformer.fit(X) # input must be a 2d array >>> # Now the convolution kernel is initialized and has shape (window_size, n_basis_funcs) - >>> transformer_fitted.kernel.shape + >>> transformer_fitted.kernel_.shape (200, 10) >>> # Transform basis From 5c5a8dac70dbca4ca9935de4dc78d8a01b5c43fb Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Wed, 23 Oct 2024 17:40:37 -0700 Subject: [PATCH 4/9] fixed import statements ordering --- src/nemos/basis.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 78820518..d341812a 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -207,12 +207,13 @@ def fit(self, X: FeatureMatrix, y=None): Examples -------- - # Example input >>> import numpy as np + >>> from nemos.basis import MSplineBasis, TransformerBasis + + # Example input >>> X, y = np.random.normal(size=(100, 2)), np.random.uniform(size=100) # Define and fit tranformation basis - >>> from nemos.basis import MSplineBasis, TransformerBasis >>> basis = MSplineBasis(10) >>> transformer = TransformerBasis(basis) >>> transformer_fitted = transformer.fit(X) # input must be a 2d array @@ -238,12 +239,13 @@ def transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: Examples -------- - >>> # Example input >>> import numpy as np + >>> from nemos.basis import MSplineBasis, TransformerBasis + + >>> # Example input >>> X, y = np.random.normal(size=(10000, 2)), np.random.uniform(size=100) >>> # Define and fit tranformation basis - >>> from nemos.basis import MSplineBasis, TransformerBasis >>> basis = MSplineBasis(10, mode="conv", window_size=200) >>> transformer = TransformerBasis(basis) >>> # Before calling `fit` the convolution kernel is not set @@ -284,12 +286,13 @@ def fit_transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: Examples -------- - >>> # Example input >>> import numpy as np + >>> from nemos.basis import MSplineBasis, TransformerBasis + + >>> # Example input >>> X, y = np.random.normal(size=(100, 1)), np.random.uniform(size=100) >>> # Define tranformation basis - >>> from nemos.basis import MSplineBasis, TransformerBasis >>> basis = MSplineBasis(10) >>> transformer = TransformerBasis(basis) From 4eb8663e3c02c0512b89d57f50b3e330e250d7bd Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Wed, 23 Oct 2024 18:43:00 -0700 Subject: [PATCH 5/9] fixed tox and added examples to call functions --- src/nemos/basis.py | 81 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index d341812a..57a87928 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -288,7 +288,7 @@ def fit_transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: -------- >>> import numpy as np >>> from nemos.basis import MSplineBasis, TransformerBasis - + >>> # Example input >>> X, y = np.random.normal(size=(100, 1)), np.random.uniform(size=100) @@ -755,6 +755,19 @@ def compute_features(self, *xi: ArrayLike) -> FeatureMatrix: input samples with the basis functions. The output shape varies based on the subclass and mode. + Examples + ------- + >>> import numpy as np + >>> from nemos.basis import BSplineBasis + + >>> # Generate data + >>> num_samples = 10000 + >>> X = np.random.normal(size=(num_samples, )) # raw time series + >>> basis = BSplineBasis(10) + >>> features = basis.compute_features(X) # basis transformed time series + >>> features.shape + (10000, 10) + Notes ----- Subclasses should implement how to handle the transformation specific to their @@ -1409,7 +1422,6 @@ class SplineBasis(Basis, abc.ABC): ---------- order : int Spline order. - """ def __init__( @@ -1849,6 +1861,19 @@ class CyclicBSplineBasis(SplineBasis): Number of basis functions. order : int Order of the splines used in basis functions. + + Examples + -------- + >>> from numpy import linspace + >>> from nemos.basis import CyclicBSplineBasis + >>> X = np.random.normal(size=(1000, 1)) + + >>> cyclic_basis = CyclicBSplineBasis(n_basis_funcs=5, order=3, mode="conv", window_size=10) + >>> sample_points = linspace(0, 1, 100) + >>> basis_functions = cyclic_basis(sample_points) + >>> X_transformed = cyclic_basis.to_transformer().fit_transform(X) + >>> X_transformed.shape + (1000, 5) """ def __init__( @@ -1985,6 +2010,19 @@ class RaisedCosineBasisLinear(Basis): Only used in "conv" mode. Additional keyword arguments that are passed to `nemos.convolve.create_convolutional_predictor` + Examples + -------- + >>> from numpy import linspace + >>> from nemos.basis import RaisedCosineBasisLinear + >>> X = np.random.normal(size=(1000, 1)) + + >>> cosine_basis = RaisedCosineBasisLinear(n_basis_funcs=5, mode="conv", window_size=10) + >>> sample_points = linspace(0, 1, 100) + >>> basis_functions = cosine_basis(sample_points) + >>> X_transformed = cosine_basis.to_transformer().fit_transform(X) + >>> X_transformed.shape + (1000, 5) + # References ------------ [1] Pillow, J. W., Paninski, L., Uzzel, V. J., Simoncelli, E. P., & J., @@ -2178,6 +2216,19 @@ class RaisedCosineBasisLog(RaisedCosineBasisLinear): Only used in "conv" mode. Additional keyword arguments that are passed to `nemos.convolve.create_convolutional_predictor` + Examples + -------- + >>> from numpy import linspace + >>> from nemos.basis import RaisedCosineBasisLog + >>> X = np.random.normal(size=(1000, 1)) + + >>> cosine_basis = RaisedCosineBasisLog(n_basis_funcs=5, mode="conv", window_size=10) + >>> sample_points = linspace(0, 1, 100) + >>> basis_functions = cosine_basis(sample_points) + >>> X_transformed = cosine_basis.to_transformer().fit_transform(X) + >>> X_transformed.shape + (1000, 5) + # References ------------ [1] Pillow, J. W., Paninski, L., Uzzel, V. J., Simoncelli, E. P., & J., @@ -2331,6 +2382,21 @@ class OrthExponentialBasis(Basis): **kwargs : Only used in "conv" mode. Additional keyword arguments that are passed to `nemos.convolve.create_convolutional_predictor` + + Examples + -------- + >>> from numpy import linspace + >>> from nemos.basis import OrthExponentialBasis + >>> X = np.random.normal(size=(1000, 1)) + >>> n_basis_funcs = 5 + >>> decay_rates = [0.01, 0.02, 0.03, 0.04, 0.05] # sample decay rates + >>> window_size=10 + >>> ortho_basis = OrthExponentialBasis(n_basis_funcs, decay_rates, "conv", window_size) + >>> sample_points = linspace(0, 1, 100) + >>> basis_functions = ortho_basis(sample_points) + >>> X_transformed = ortho_basis.to_transformer().fit_transform(X) + >>> X_transformed.shape + (1000, 5) """ def __init__( @@ -2508,6 +2574,17 @@ def mspline(x: NDArray, k: int, i: int, T: NDArray) -> NDArray: ------- spline M-spline basis function, shape (n_sample_points, ). + + Examples + -------- + >>> import numpy as np + >>> from numpy import linspace + >>> from nemos.basis import mspline + + >>> sample_points = linspace(0, 1, 100) + >>> mspline_eval = mspline(x=sample_points, k=3, i=2, T=np.random.rand(7)) # define a cubic M-spline + >>> mspline_eval.shape + (100,) """ # Boundary conditions. if (T[i + k] - T[i]) < 1e-6: From e2cf5dcc6b0ed4141cf31c9eb3c47ccedff55003 Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Wed, 23 Oct 2024 19:49:22 -0700 Subject: [PATCH 6/9] added evaluate_on_grid examples --- src/nemos/basis.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 57a87928..2a9e12dc 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -1826,6 +1826,14 @@ def evaluate_on_grid(self, n_samples: int) -> Tuple[NDArray, NDArray]: ----- The evaluation is performed by looping over each element and using `splev` from SciPy to compute the basis values. + + Examples + -------- + >>> import numpy as np + >>> import matplotlib.pyplot as plt + >>> from nemos.basis import BSplineBasis + >>> bspline_basis = BSplineBasis(n_basis_funcs=4, order=3) + >>> sample_points, basis_values = bspline_basis.evaluate_on_grid(100) """ return super().evaluate_on_grid(n_samples) @@ -1981,6 +1989,14 @@ def evaluate_on_grid(self, n_samples: int) -> Tuple[NDArray, NDArray]: ----- The evaluation is performed by looping over each element and using `splev` from SciPy to compute the basis values. + + Examples + -------- + >>> import numpy as np + >>> import matplotlib.pyplot as plt + >>> from nemos.basis import CyclicBSplineBasis + >>> cyclic_basis = CyclicBSplineBasis(n_basis_funcs=4, order=3) + >>> sample_points, basis_values = cyclic_basis.evaluate_on_grid(100) """ return super().evaluate_on_grid(n_samples) @@ -2162,6 +2178,13 @@ def evaluate_on_grid(self, n_samples: int) -> Tuple[NDArray, NDArray]: basis_funcs : Raised cosine basis functions, shape (n_samples, n_basis_funcs) + Examples + -------- + >>> import numpy as np + >>> import matplotlib.pyplot as plt + >>> from nemos.basis import RaisedCosineBasisLinear + >>> cosine_basis = RaisedCosineBasisLinear(n_basis_funcs=5, mode="conv", window_size=10) + >>> sample_points, basis_values = cosine_basis.evaluate_on_grid(100) """ return super().evaluate_on_grid(n_samples) @@ -2552,6 +2575,16 @@ def evaluate_on_grid(self, n_samples: int) -> Tuple[NDArray, NDArray]: Evaluated exponentially decaying basis functions, numerically orthogonalized, shape (n_samples, n_basis_funcs) + Examples + -------- + >>> import numpy as np + >>> import matplotlib.pyplot as plt + >>> from nemos.basis import OrthExponentialBasis + >>> n_basis_funcs = 5 + >>> decay_rates = [0.01, 0.02, 0.03, 0.04, 0.05] # sample decay rates + >>> window_size=10 + >>> ortho_basis = OrthExponentialBasis(n_basis_funcs, decay_rates, "conv", window_size) + >>> sample_points, basis_values = ortho_basis.evaluate_on_grid(100) """ return super().evaluate_on_grid(n_samples) From c65383cc129d0bbe210d77d6acc119caafb8c260 Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Sat, 26 Oct 2024 14:02:52 -0700 Subject: [PATCH 7/9] last few comment fixes --- src/nemos/basis.py | 65 ++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 2a9e12dc..05a2258a 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -210,13 +210,13 @@ def fit(self, X: FeatureMatrix, y=None): >>> import numpy as np >>> from nemos.basis import MSplineBasis, TransformerBasis - # Example input - >>> X, y = np.random.normal(size=(100, 2)), np.random.uniform(size=100) + >>> # Example input + >>> X = np.random.normal(size=(100, 2)) - # Define and fit tranformation basis + >>> # Define and fit tranformation basis >>> basis = MSplineBasis(10) >>> transformer = TransformerBasis(basis) - >>> transformer_fitted = transformer.fit(X) # input must be a 2d array + >>> transformer_fitted = transformer.fit(X) """ self._basis._set_kernel(*self._unpack_inputs(X)) return self @@ -243,7 +243,7 @@ def transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: >>> from nemos.basis import MSplineBasis, TransformerBasis >>> # Example input - >>> X, y = np.random.normal(size=(10000, 2)), np.random.uniform(size=100) + >>> X = np.random.normal(size=(10000, 2)) >>> # Define and fit tranformation basis >>> basis = MSplineBasis(10, mode="conv", window_size=200) @@ -251,13 +251,13 @@ def transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: >>> # Before calling `fit` the convolution kernel is not set >>> transformer.kernel_ - >>> transformer_fitted = transformer.fit(X) # input must be a 2d array + >>> transformer_fitted = transformer.fit(X) >>> # Now the convolution kernel is initialized and has shape (window_size, n_basis_funcs) >>> transformer_fitted.kernel_.shape (200, 10) >>> # Transform basis - >>> feature_transformed = transformer.transform(X[:, 0:1]) # input must be a 2d array, (num_samples, 1) + >>> feature_transformed = transformer.transform(X[:, 0:1]) """ # transpose does not work with pynapple # can't use func(*X.T) to unwrap @@ -290,14 +290,14 @@ def fit_transform(self, X: FeatureMatrix, y=None) -> FeatureMatrix: >>> from nemos.basis import MSplineBasis, TransformerBasis >>> # Example input - >>> X, y = np.random.normal(size=(100, 1)), np.random.uniform(size=100) + >>> X = np.random.normal(size=(100, 1)) >>> # Define tranformation basis >>> basis = MSplineBasis(10) >>> transformer = TransformerBasis(basis) >>> # Fit and transform basis - >>> feature_transformed = transformer.fit_transform(X) # input must be a 2d array, (num_samples, 1) + >>> feature_transformed = transformer.fit_transform(X) """ return self._basis.compute_features(*self._unpack_inputs(X)) @@ -953,14 +953,10 @@ def evaluate_on_grid(self, *n_samples: int) -> Tuple[Tuple[NDArray], NDArray]: >>> from nemos.basis import MSplineBasis >>> mspline_basis = MSplineBasis(n_basis_funcs=4, order=3) >>> sample_points, basis_values = mspline_basis.evaluate_on_grid(100) - >>> for i in range(4): - ... p = plt.plot(sample_points, basis_values[:, i], label=f'Function {i+1}') - >>> plt.title('M-Spline Basis Functions') - Text(0.5, 1.0, 'M-Spline Basis Functions') - >>> plt.xlabel('Domain') - Text(0.5, 0, 'Domain') - >>> plt.ylabel('Basis Function Value') - Text(0, 0.5, 'Basis Function Value') + >>> p = plt.plot(sample_points, basis_values, label=f'Function {i+1}') + >>> plt.title('M-Spline Basis Functions'); + >>> plt.xlabel('Domain'); + >>> plt.ylabel('Basis Function Value'); >>> l = plt.legend() """ self._check_input_dimensionality(n_samples) @@ -1156,24 +1152,17 @@ class AdditiveBasis(Basis): >>> # Generate sample data >>> import numpy as np >>> import nemos as nmo - >>> X, y = np.random.normal(size=(30, 2)), np.random.poisson(size=30) - >>> # X.shape is (n_samples, n_inputs), where n_inputs is the number required by the basis + >>> X = np.random.normal(size=(30, 2)) >>> # define two basis objects and add them >>> basis_1 = nmo.basis.BSplineBasis(10) >>> basis_2 = nmo.basis.RaisedCosineBasisLinear(15) >>> additive_basis = nmo.basis.AdditiveBasis(basis1=basis_1, basis2=basis_2) - >>> transformed_X = additive_basis.to_transformer().transform(X) - >>> print(transformed_X.shape) - (30, 25) >>> # can add another basis to the AdditiveBasis object >>> X = np.random.normal(size=(30, 3)) >>> basis_3 = nmo.basis.RaisedCosineBasisLog(100) >>> additive_basis_2 = additive_basis + basis_3 - >>> transformed_X = additive_basis_2.to_transformer().transform(X) - >>> print(transformed_X.shape) - (30, 125) """ def __init__(self, basis1: Basis, basis2: Basis) -> None: @@ -1290,23 +1279,17 @@ class MultiplicativeBasis(Basis): >>> # Generate sample data >>> import numpy as np >>> import nemos as nmo - >>> X, y = np.random.normal(size=(30, 3)), np.random.poisson(size=30) + >>> X = np.random.normal(size=(30, 3)) >>> # define two basis and multiply >>> basis_1 = nmo.basis.BSplineBasis(10) >>> basis_2 = nmo.basis.RaisedCosineBasisLinear(15) >>> multiplicative_basis = nmo.basis.MultiplicativeBasis(basis1=basis_1, basis2=basis_2) - >>> transformed_X = multiplicative_basis.to_transformer().transform(X[:, 0:2]) - >>> print(transformed_X.shape) - (30, 150) >>> # Can multiply or add another basis to the AdditiveBasis object >>> # This will cause the number of output features of the result basis to grow accordingly >>> basis_3 = nmo.basis.RaisedCosineBasisLog(100) >>> multiplicative_basis_2 = multiplicative_basis * basis_3 - >>> transformed_X = multiplicative_basis_2.to_transformer().transform(X) - >>> print(transformed_X.shape) - (30, 15000) """ def __init__(self, basis1: Basis, basis2: Basis) -> None: @@ -1743,8 +1726,6 @@ class BSplineBasis(SplineBasis): >>> from nemos.basis import BSplineBasis >>> bspline_basis = BSplineBasis(n_basis_funcs=5, order=3) - >>> bspline_transformer = bspline_basis.to_transformer() - >>> sample_points = linspace(0, 1, 100) >>> basis_functions = bspline_basis(sample_points) """ @@ -1879,9 +1860,6 @@ class CyclicBSplineBasis(SplineBasis): >>> cyclic_basis = CyclicBSplineBasis(n_basis_funcs=5, order=3, mode="conv", window_size=10) >>> sample_points = linspace(0, 1, 100) >>> basis_functions = cyclic_basis(sample_points) - >>> X_transformed = cyclic_basis.to_transformer().fit_transform(X) - >>> X_transformed.shape - (1000, 5) """ def __init__( @@ -2035,9 +2013,6 @@ class RaisedCosineBasisLinear(Basis): >>> cosine_basis = RaisedCosineBasisLinear(n_basis_funcs=5, mode="conv", window_size=10) >>> sample_points = linspace(0, 1, 100) >>> basis_functions = cosine_basis(sample_points) - >>> X_transformed = cosine_basis.to_transformer().fit_transform(X) - >>> X_transformed.shape - (1000, 5) # References ------------ @@ -2248,9 +2223,6 @@ class RaisedCosineBasisLog(RaisedCosineBasisLinear): >>> cosine_basis = RaisedCosineBasisLog(n_basis_funcs=5, mode="conv", window_size=10) >>> sample_points = linspace(0, 1, 100) >>> basis_functions = cosine_basis(sample_points) - >>> X_transformed = cosine_basis.to_transformer().fit_transform(X) - >>> X_transformed.shape - (1000, 5) # References ------------ @@ -2412,14 +2384,11 @@ class OrthExponentialBasis(Basis): >>> from nemos.basis import OrthExponentialBasis >>> X = np.random.normal(size=(1000, 1)) >>> n_basis_funcs = 5 - >>> decay_rates = [0.01, 0.02, 0.03, 0.04, 0.05] # sample decay rates + >>> decay_rates = [0.01, 0.02, 0.03, 0.04, 0.05] # sample decay rates >>> window_size=10 >>> ortho_basis = OrthExponentialBasis(n_basis_funcs, decay_rates, "conv", window_size) >>> sample_points = linspace(0, 1, 100) >>> basis_functions = ortho_basis(sample_points) - >>> X_transformed = ortho_basis.to_transformer().fit_transform(X) - >>> X_transformed.shape - (1000, 5) """ def __init__( @@ -2692,7 +2661,7 @@ def bspline( >>> from nemos.basis import bspline >>> sample_points = linspace(0, 1, 100) - >>> knots = knots = BSplineBasis(10)._generate_knots(sample_points) + >>> knots = np.array([0, 0, 0, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1, 1, 1, 1]) >>> bspline_eval = bspline(sample_points, knots) # define a cubic B-spline >>> bspline_eval.shape (100, 10) From dffec5aaf8d2d5e4641481d72fb94afb5eca8d4a Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Sat, 26 Oct 2024 18:29:55 -0700 Subject: [PATCH 8/9] fixed plot for loop --- src/nemos/basis.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 05a2258a..49b08bb1 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -953,11 +953,11 @@ def evaluate_on_grid(self, *n_samples: int) -> Tuple[Tuple[NDArray], NDArray]: >>> from nemos.basis import MSplineBasis >>> mspline_basis = MSplineBasis(n_basis_funcs=4, order=3) >>> sample_points, basis_values = mspline_basis.evaluate_on_grid(100) - >>> p = plt.plot(sample_points, basis_values, label=f'Function {i+1}') - >>> plt.title('M-Spline Basis Functions'); - >>> plt.xlabel('Domain'); - >>> plt.ylabel('Basis Function Value'); - >>> l = plt.legend() + >>> p = plt.plot(sample_points, basis_values) + >>> _ = plt.title('M-Spline Basis Functions') + >>> _ = plt.xlabel('Domain') + >>> _ = plt.ylabel('Basis Function Value') + >>> _ = plt.legend([f'Function {i+1}' for i in range(4)]); """ self._check_input_dimensionality(n_samples) From e90185678d1255c2d98a84a9f2a66a1d7d55752f Mon Sep 17 00:00:00 2001 From: pranmod01 Date: Mon, 28 Oct 2024 12:43:47 -0700 Subject: [PATCH 9/9] init additive and mult basis example changed --- src/nemos/basis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nemos/basis.py b/src/nemos/basis.py index 49b08bb1..92c3871b 100644 --- a/src/nemos/basis.py +++ b/src/nemos/basis.py @@ -1157,7 +1157,7 @@ class AdditiveBasis(Basis): >>> # define two basis objects and add them >>> basis_1 = nmo.basis.BSplineBasis(10) >>> basis_2 = nmo.basis.RaisedCosineBasisLinear(15) - >>> additive_basis = nmo.basis.AdditiveBasis(basis1=basis_1, basis2=basis_2) + >>> additive_basis = basis_1 + basis_2 >>> # can add another basis to the AdditiveBasis object >>> X = np.random.normal(size=(30, 3)) @@ -1284,7 +1284,7 @@ class MultiplicativeBasis(Basis): >>> # define two basis and multiply >>> basis_1 = nmo.basis.BSplineBasis(10) >>> basis_2 = nmo.basis.RaisedCosineBasisLinear(15) - >>> multiplicative_basis = nmo.basis.MultiplicativeBasis(basis1=basis_1, basis2=basis_2) + >>> multiplicative_basis = basis_1 * basis_2 >>> # Can multiply or add another basis to the AdditiveBasis object >>> # This will cause the number of output features of the result basis to grow accordingly