bcam.indar.ema.RealModes

class bcam.indar.ema.RealModes(poles: array - like, amps: array - like, ns: int, response: str = 'a', fs: float = 1.0)

Fit mode shapes with proportional damping.

After estimating the amplitudes \(A^l_{ij}\) with Amplitudes, this class can be used to fit mode shapes assuming proportional damping. The mode shapes are stored as an array \(\varphi\) of shape (n_outputs, dof), and they satisfy

\[A^l_{ij} \approx \varphi_{il} \varphi_{jl},\]

where \(i=0, \ldots, n_\mathrm{out}-1\), \(j=0, \ldots, n_\mathrm{in}-1\), and \(l=0, \ldots, \mathrm{dof}-1\).

Parameters:
polesarray-like, shape (dof,)

Natural frequencies.

ampsarray-like, shape (n_outputs, n_inputs, dof)

Amplitudes for each measured output-input pair and mode.

nsint

Number of time samples in the fitted IRF.

responsestr, default ‘a’

Type of response. Must be one of ‘a’, ‘v’, or ‘d’, for accelerance, velocity, or displacement, respectively.

fsfloat, default 1.

Sampling frequency (\(1/dt\)) of the IRF.

Attributes:
modes_np.ndarray, shape (n_outputs, dof)

Fitted (partial) mode shapes.

success_bool

Whether the optimization was successful.

message_str

Description of the cause of the termination.

Methods

fit([options_ncg, dual_annealing_kwargs])

Fit the mode shapes.

predict(X)

Predict the impulse response function (IRF).

Notes

To compare amplitudes with mode shapes, we use a loss-function based on the Hilbert–Schmidt norm

\[L(\varphi) = \sum_{i,j}\sum_{k=0}^{N-1} (N - k)\Big\lvert \im\Big(\sum_l(A^l_{ij}-\varphi_{il} \varphi_{jl})\lambda_l^\nu s_l^k\Big) \Big\rvert^2,\]

where \(N\) is the number of time samples, \(s_l = e^{\lambda_l\,dt}\) are the poles of the structure, and the exponent \(\nu\) depends on the type of IRF (accelerance (2), velocity (1), or displacement (0)).

Since the loss-function is not convex, the optimization is performed with the global minimizer scipy.optimize.dual_annealing() with local search by trust-ncg. To define an initial guesss, a determined subset of equations from the system \(A^l_{ij} = \varphi_{il} \varphi_{jl}\) is solved.

fit(options_ncg: dict | None = None, dual_annealing_kwargs: dict | None = None) RealModes

Fit the mode shapes.

Parameters:
options_ncgdict, optional

Options for the local optimization by trust-ncg. The options ‘jac’ and ‘hessp’ are ignored since they are passed in this class. See scipy.optimize.minimize() for details. Default is None.

dual_annealing_kwargsdict, optional

Options for scipy.optimize.dual_annealing. The options ‘x0’, ‘bounds’, and ‘minimizer_kwargs’ are ignored since they are defined in this class. See scipy.optimize.dual_annealing() for details. Default is None.

Returns:
selfRealModes

Fitted model.

predict(X: array - like) ndarray

Predict the impulse response function (IRF).

Parameters:
Xarray-like, shape (n_samples,)

Times at which to predict the IRF.

Returns:
irfnp.ndarray, shape (n_outputs, n_inputs, n_samples)

Predicted IRF at the given times.