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

feat: change default value of parameter normalized #207

Merged
merged 1 commit into from
Sep 1, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion xeofs/models/_base_model_cross_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def transform(
X, Y: DataObject | None
Data to be transformed. At least one of them must be provided.
normalized: bool, default=False
Whether to return normalized scores.
Whether to return L2 normalized scores.

Returns
-------
Expand Down
30 changes: 20 additions & 10 deletions xeofs/models/_base_model_single_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,14 @@ def _fit_algorithm(self, data: DataArray) -> Self:
"""
raise NotImplementedError

def transform(self, data: DataObject, normalized=True) -> DataArray:
def transform(self, data: DataObject, normalized=False) -> DataArray:
"""Project data onto the components.

Parameters
----------
data: DataObject
Data to be transformed.
normalized: bool, default=True
normalized: bool, default=False
Whether to normalize the scores by the L2 norm.

Returns
Expand Down Expand Up @@ -250,7 +250,7 @@ def fit_transform(
return self.fit(data, dim, weights).transform(data, **kwargs)

def inverse_transform(
self, scores: DataArray, normalized: bool = True
self, scores: DataArray, normalized: bool = False
) -> DataObject:
"""Reconstruct the original data from transformed data.

Expand All @@ -260,7 +260,7 @@ def inverse_transform(
Transformed data to be reconstructed. This could be a subset
of the `scores` data of a fitted model, or unseen data. Must
have a 'mode' dimension.
normalized: bool, default=True
normalized: bool, default=False
Whether the scores data have been normalized by the L2 norm.

Returns
Expand Down Expand Up @@ -305,12 +305,23 @@ def _inverse_transform_algorithm(self, scores: DataArray) -> DataArray:
"""
raise NotImplementedError

def components(self) -> DataObject:
"""Get the components."""
def components(self, normalized: bool = True) -> DataObject:
"""Get the components.

Parameters
----------
normalized: bool, default=True
Whether to normalize the components by the L2 norm.

"""
components = self.data["components"]
if not normalized:
name = components.name
components = components * self.data["norms"]
components.name = name
return self.preprocessor.inverse_transform_components(components)

def scores(self, normalized=True) -> DataArray:
def scores(self, normalized: bool = False) -> DataArray:
"""Get the scores.

Parameters
Expand All @@ -320,8 +331,7 @@ def scores(self, normalized=True) -> DataArray:
"""
scores = self.data["scores"].copy()
if normalized:
attrs = scores.attrs.copy()
name = scores.name
scores = scores / self.data["norms"]
scores.attrs.update(attrs)
scores.name = "scores"
scores.name = name
return self.preprocessor.inverse_transform_scores(scores)
14 changes: 7 additions & 7 deletions xeofs/models/cpcca_rotator.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,19 +310,19 @@ def transform(
Y: DataObject | None = None,
normalized: bool = False,
) -> DataArray | List[DataArray]:
"""Project new "unseen" data onto the rotated singular vectors.
"""Transform the data.

Parameters
----------
X : DataObject
Data to be projected onto the rotated singular vectors of the first dataset.
Y : DataObject
Data to be projected onto the rotated singular vectors of the second dataset.
X, Y: DataObject | None
Data to be transformed. At least one of them must be provided.
normalized: bool, default=False
Whether to return L2 normalized scores.

Returns
-------
DataArray | List[DataArray]
Projected data.
Sequence[DataArray] | DataArray
Transformed data.

"""
# raise error if no data is provided
Expand Down
22 changes: 15 additions & 7 deletions xeofs/models/eof.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,20 @@ def _inverse_transform_algorithm(self, scores: DataArray) -> DataArray:

return reconstructed_data

def components(self) -> DataObject:
"""Return the (EOF) components.
def components(self, normalized: bool = True) -> DataObject:
"""Return the components.

The components in EOF anaylsis are the eigenvectors of the covariance/correlation matrix.
Other names include the principal components or EOFs.
The components are also refered to as eigenvectors, EOFs or loadings depending on the context.

Returns
-------
components: DataArray | Dataset | List[DataArray]
Components of the fitted model.

"""
return super().components()
return super().components(normalized=normalized)

def scores(self, normalized: bool = True) -> DataArray:
def scores(self, normalized: bool = False) -> DataArray:
"""Return the (PC) scores.

The scores in EOF anaylsis are the projection of the data matrix onto the
Expand Down Expand Up @@ -341,7 +340,7 @@ def _fit_algorithm(self, X: DataArray) -> Self:

return super()._fit_algorithm(X)

def components_amplitude(self) -> DataObject:
def components_amplitude(self, normalized=True) -> DataObject:
"""Return the amplitude of the (EOF) components.

The amplitude of the components are defined as
Expand All @@ -352,13 +351,22 @@ def components_amplitude(self) -> DataObject:
where :math:`C_{ij}` is the :math:`i`-th entry of the :math:`j`-th component and
:math:`|\\cdot|` denotes the absolute value.

Parameters
----------
normalized : bool, default=True
Whether to normalize the components by the singular values

Returns
-------
components_amplitude: DataArray | Dataset | List[DataArray]
Amplitude of the components of the fitted model.

"""
amplitudes = abs(self.data["components"])

if not normalized:
amplitudes = amplitudes * self.data["norms"]

amplitudes.name = "components_amplitude"
return self.preprocessor.inverse_transform_components(amplitudes)

Expand Down
4 changes: 2 additions & 2 deletions xeofs/models/sparse_pca.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def components(self) -> DataObject:
"""
return super().components()

def scores(self, normalized: bool = True) -> DataArray:
def scores(self, normalized: bool = False) -> DataArray:
"""Return the component scores.

The component scores :math:`U` are defined as the projection of the fitted
Expand All @@ -309,7 +309,7 @@ def scores(self, normalized: bool = True) -> DataArray:

Parameters
----------
normalized : bool, default=True
normalized : bool, default=False
Whether to normalize the scores by the L2 norm.

Returns
Expand Down
Loading