Source code for pyhdtoolkit.maths.utils

"""
.. _maths-utils:

Utilities
---------

Module with utility functions used throughout the `~.maths.nonconvex_phase_sync`
and `~.maths.stats_fitting` modules.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

from loguru import logger

if TYPE_CHECKING:
    import pandas as pd

# ----- Miscellaneous Utilites ----- #


[docs] def get_magnitude(value: float) -> int: """ .. versionadded:: 0.8.2 Returns the determined magnitude of the provided *value*. This corresponds to the power of 10 that would be necessary to reduce *value* to a :math:`X \\cdot 10^{n}` form. In this case, *n* is the result. Parameters ---------- value : float Value to determine the magnitude of. Returns ------- int The magnitude of the provided *value*, as an `int`. Examples -------- .. code-block:: python get_magnitude(10) # returns 1 .. code-block:: python get_magnitude(0.0311) # returns -2 .. code-block:: python get_magnitude(1e-7) # returns -7 """ return int(np.floor(np.log10(np.abs(value))))
[docs] def get_scaled_values_and_magnitude_string( values_array: pd.DataFrame | np.ndarray, force_magnitude: float | None = None ) -> tuple[pd.DataFrame | np.ndarray, str]: """ .. versionadded:: 0.8.2 Conveniently scales the provided values to the best determined magnitude, and returns the scaled values and the magnitude string to use in plots labels. Parameters ---------- values_array : Union[pd.DataFrame, np.ndarray] Vectorised structure containing the values to scale. force_magnitude : float, optional A specific magnitude value to use for the scaling, if desired. Returns ------- tuple[pandas.DataFrame | numpy.ndarray, str] A `tuple` of the scaled values (same type as the provided ones) and the string to use for the scale in plots labels and legends. Example ------- .. code-block:: python import numpy as np q = np.array([-330, 230, 430, -720, 750, -110, 410, -340, -950, -630]) get_scaled_values_and_magnitude_string(q) # returns (array([-3.3, 2.3, 4.3, -7.2, 7.5, -1.1, 4.1, -3.4, -9.5, -6.3]), '{-2}') """ magnitude = get_magnitude(max(values_array)) if force_magnitude is None else force_magnitude applied_magnitude = -magnitude logger.trace(f"Scaling data by {applied_magnitude} orders of magnitude") scaled_values = values_array * (10**applied_magnitude) magnitude_string = "{" + f"{applied_magnitude}" + "}" return scaled_values, magnitude_string