kinamax.hbm

Helpers for Harmonic Balance Method (HBM) coefficient manipulations.

The real Fourier coefficient layout used across this module is:

X = [a0, a1, …, aN, b1, …, bN]

which represents the real periodic signal

x(t) = a0 + sum_n (a_n cos(n * wd * t) + b_n sin(n * wd * t))

class kinamax.hbm.FourierCoeffs(values, frequency)[source]

Bases: NamedTuple

Real Fourier coefficients paired with the fundamental frequency in Hz.

Examples

>>> import jax.numpy as jnp
>>> coeffs = FourierCoeffs(
...     values=jnp.array([0.0, 1.0, 0.5]),
...     frequency=jnp.float32(5.0),
... )
>>> print(coeffs)
FourierCoeffs
...
│ frequency ┆ scalar ┆ float32 ┆ 5.0...
│ values    ┆ (3,)   ┆ float32 ┆ [0. , 1. , 0.5]...
...
Parameters:
  • values (Array)

  • frequency (float | Array)

values: Array

Alias for field number 0

frequency: float | Array

Alias for field number 1

class kinamax.hbm.SampledSignal(values, frequency)[source]

Bases: NamedTuple

Uniformly sampled signal over one period, tagged by its frequency in Hz.

Examples

>>> import jax.numpy as jnp
>>> signal = SampledSignal(
...     values=jnp.array([0.0, 1.0, 0.0, -1.0]),
...     frequency=jnp.float32(5.0),
... )
>>> print(signal)
SampledSignal
...
│ frequency ┆ scalar ┆ float32 ┆ 5.0...
│ values    ┆ (4,)   ┆ float32 ┆ [ 0.,  1.,  0., -1.]...
...
>>> print(signal.time_step)
0.05
>>> print(signal.time_grid)
[0.   0.05 0.1  0.15]
Parameters:
  • values (Array)

  • frequency (float | Array)

values: Array

Alias for field number 0

frequency: float | Array

Alias for field number 1

property time_step: Array

Return the uniform time step over one period.

property time_grid: Array

Return the evenly spaced time grid over one period.

kinamax.hbm.coeffs_to_complex(X)[source]

Convert stacked real Fourier coefficients to positive-frequency phasors.

Parameters:

X (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | FourierCoeffs)

Return type:

Array

kinamax.hbm.complex_to_coeffs(C, frequency=None)[source]

Convert positive-frequency phasors back to stacked real coefficients.

Parameters:
  • C (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray)

  • frequency (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | None)

Return type:

Array | FourierCoeffs

kinamax.hbm.coeffs_derivative(X, wd=None, order=1)[source]

Differentiate a coefficient vector with respect to time.

Examples

>>> import jax.numpy as jnp
>>> coeffs = FourierCoeffs(values=jnp.array([0.0, 1.0, 0.0]), frequency=5.0)
>>> velocity = coeffs_derivative(coeffs, order=1)
>>> print(velocity)
FourierCoeffs
...
│ frequency ┆ scalar ┆ float32 ┆ 5.0...
│ values    ┆ (3,)   ┆ float32 ┆ [  0.      ,   0.      , -31.4...
...
Parameters:
  • X (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | FourierCoeffs)

  • wd (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | None)

  • order (int)

Return type:

Array | FourierCoeffs

kinamax.hbm.coeffs_to_table(X)[source]

Return a JAX table with stacked real and imaginary phasor parts.

Parameters:

X (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | FourierCoeffs)

Return type:

Array

kinamax.hbm.time_grid(wd, n, oversample=1)[source]

Build an evenly spaced grid over one forcing period.

Parameters:
  • wd (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray)

  • n (int)

  • oversample (int)

Return type:

Array

kinamax.hbm.coeffs_to_time_signal(X, oversample=1)[source]

Synthesize a real time signal from stacked real Fourier coefficients.

Examples

>>> import jax.numpy as jnp
>>> coeffs = FourierCoeffs(values=jnp.array([0.0, 1.0, 0.0]), frequency=5.0)
>>> signal = coeffs_to_time_signal(coeffs, oversample=4)
>>> print(signal)
SampledSignal
...
│ frequency ┆ scalar ┆ float32 ┆ 5.0...
│ values    ┆ (8,)   ┆ float32 ┆ [1.        , 0.70710677, 0.   ...
...
Parameters:
  • X (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | FourierCoeffs)

  • oversample (int)

Return type:

Array | SampledSignal

kinamax.hbm.time_to_coeffs(x, downsample=1)[source]

Project a sampled real time signal back onto the HBM basis.

Examples

>>> import jax.numpy as jnp
>>> signal = SampledSignal(
...     values=jnp.cos(2.0 * jnp.pi * jnp.arange(16) / 16),
...     frequency=5.0,
... )
>>> coeffs = time_to_coeffs(signal, downsample=4)
>>> print(coeffs)
FourierCoeffs
...
│ frequency ┆ scalar ┆ float32 ┆ 5.0...
│ values    ┆ (5,)   ┆ float32 ┆ [ 4.0854182e-08,  1.0000000e+0...
...
Parameters:
  • x (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | SampledSignal)

  • downsample (int)

Return type:

Array | FourierCoeffs

kinamax.hbm.coeffs_pow(X, p, oversample=1)[source]

Raise a periodic signal to a power and re-project it onto the HBM basis.

Parameters:
  • X (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray | FourierCoeffs)

  • p (Array | ndarray | bool | number | bool | int | float | complex | TypedNdArray)

  • oversample (int)

Return type:

Array | FourierCoeffs