Multi-resolution DMD

Derived module from dmdbase.py for multi-resolution dmd.

Reference: - Kutz, J. Nathan, Xing Fu, and Steven L. Brunton. Multiresolution Dynamic Mode Decomposition. SIAM Journal on Applied Dynamical Systems 15.2 (2016): 713-735.

class MrDMD(dmd, max_level=2, max_cycles=1)[source]

Bases: DMDBase

Multi-resolution Dynamic Mode Decomposition

Parameters:
  • dmd (DMDBase or list or tuple or function) – DMD instance(s) used to analyze the snapshots provided. See also the documentation for _dmd_builder().

  • max_cycles (int) – the maximum number of mode oscillations in any given time scale. Default is 1.

  • max_level (int) – the maximum level (inclusive). For instance, max_level=4 means that we are going to have levels 0, 1, 2, 3 and 4. Default is 2.

_build_tree()[source]

Build the internal binary tree that contain the DMD subclasses.

_dmd_builder()[source]

Builds a function which takes in input a level and a leaf count (i.e. coordinates inside the binary tree) and produces an appropriate DMD instance according to the criteria specified in self.dmd.

Criteria supported:

  • A function which takes two parameters level and leaf;

  • List/tuple of DMD instances (length must be equal to max_level+1);

  • A DMD instance (which is used for all the levels and leaves).

Example 0 (one DMD):

>>> # this SpDMD is used for all the levels, for all the leaves
>>> MrDMD(dmd=SpDMD(), max_level=5).fit(X)

Example 1 (simple function which adapts the parameter d of HankelDMD to the current level of the tree):

>>> def build_dmds(level, leaf):
...     d = 30 - 2*level
...     return HankelDMD(d=d)
>>> MrDMD(dmd=build_dmds, max_level=5).fit(X)

Example 2 (we use a different kind of DMD if we are near the middle part of the time window):

>>> # you can name the function however you prefer
>>> def my_dmds(level, leaf):
...     level_size = pow(2,level)
...     distance_from_middle = abs(leaf - level_size // 2)
...     # we choose 2 as a random threshold
...     if distance_from_middle < 2:
...         return HankelDMD(d=5)
...     else:
...         return DMD(svd_rank=3)
>>> MrDMD(dmd=my_dmds, max_level=5).fit(X)

Example 3 (tuple of DMDs):

>>> dmds_list = [DMD(svd_rank=10) for i in range(6) if i < 3
                    else DMD(svd_rank=2)]
>>> MrDMD(dmd=dmds_list, max_level=5).fit(X)
Returns:

A function which can be used to spawn DMD instances according to the level and leaf.

Return type:

func

property dynamics

Get the time evolution of each mode.

Returns:

the matrix that contains all the time evolution, stored by row.

Return type:

numpy.ndarray

property eigs

Get the eigenvalues of A tilde.

Returns:

the eigenvalues from the eigendecomposition of atilde.

Return type:

numpy.ndarray

enumerate()[source]

Example:

>>> mrdmd = MrDMD(DMD())
>>> mrdmd.fit(X)
>>> for level, leaf, dmd in mrdmd:
>>>     print(level, leaf, dmd.eigs)
fit(X)[source]

Compute the Dynamic Modes Decomposition to the input data.

Parameters:

X (numpy.ndarray or iterable) – the input snapshots.

property modes

Get the matrix containing the DMD modes, stored by column.

Returns:

the matrix containing the DMD modes.

Return type:

numpy.ndarray

property modes_activation_bitmask

Get the bitmask which controls which DMD modes are enabled at the moment in this DMD instance.

The DMD instance must be fitted before this property becomes valid. After fit() is called, the defalt value of modes_activation_bitmask is an array of True values of the same shape of amplitudes().

The array returned is read-only (this allow us to react appropriately to changes in the bitmask). In order to modify the bitmask you need to set the field to a brand-new value (see example below).

Example:

>>> # this is an error
>>> dmd.modes_activation_bitmask[[1,2]] = False
ValueError: assignment destination is read-only
>>> tmp = np.array(dmd.modes_activation_bitmask)
>>> tmp[[1,2]] = False
>>> dmd.modes_activation_bitmask = tmp
Returns:

The DMD modes activation bitmask.

Return type:

numpy.ndarray

partial_amplitudes(level, node=None)[source]

Return the amplitudes of the specific level and of the specific node; if node is not specified, the method returns the amplitudes of the given level (all the nodes).

Parameters:
  • level (int) – the index of the level from where the amplitudes are extracted.

  • node (int) – the index of the node from where the amplitudes are extracted; if None, the amplitudes are extracted from all the nodes of the given level. Default is None.

Returns:

the selected eigs

Return type:

numpy.ndarray

partial_dynamics(level, node=None)[source]

Return the time evolution of the specific level and of the specific node; if node is not specified, the method returns the time evolution of the given level (all the nodes). The dynamics are always reported to the original time window.

Parameters:
  • level (int) – the index of the level from where the time evolution is extracted.

  • node (int) – the index of the node from where the time evolution is extracted; if None, the time evolution is extracted from all the nodes of the given level. Default is None.

Returns:

the selected dynamics stored by row

Return type:

numpy.ndarray

partial_eigs(level, node=None)[source]

Return the eigenvalues of the specific level and of the specific node; if node is not specified, the method returns the eigenvalues of the given level (all the nodes).

Parameters:
  • level (int) – the index of the level from where the eigenvalues is extracted.

  • node (int) – the index of the node from where the eigenvalues is extracted; if None, the time evolution is extracted from all the nodes of the given level. Default is None.

Returns:

the selected eigs

Return type:

numpy.ndarray

partial_modes(level, node=None)[source]

Return the modes at the specific level and at the specific node; if node is not specified, the method returns all the modes of the given level (all the nodes).

Parameters:
  • level (int) – the index of the level from where the modes are extracted.

  • node (int) – the index of the node from where the modes are extracted; if None, the modes are extracted from all the nodes of the given level. Default is None.

Returns:

the selected modes stored by columns

Return type:

numpy.ndarray

partial_reconstructed_data(level, node=None)[source]

Return the reconstructed data computed using the modes and the time evolution at the specific level and at the specific node; if node is not specified, the method returns the reconstructed data of the given level (all the nodes).

Parameters:
  • level (int) – the index of the level.

  • node (int) – the index of the node from where the time evolution is extracted; if None, the time evolution is extracted from all the nodes of the given level. Default is None.

Returns:

the selected reconstruction from dmd operators

Return type:

numpy.ndarray

partial_time_interval(level, leaf)[source]

Evaluate the start and end time and the period of a given bin.

Parameters:
  • level (int) – the level in the binary tree.

  • node (int) – the node id.

Returns:

the start and end time and the period of the bin

Return type:

dictionary

property reconstructed_data

Get the reconstructed data.

Returns:

the matrix that contains the reconstructed snapshots.

Return type:

numpy.ndarray

time_window_amplitudes(t0, tend)[source]

Get the amplitudes relative to the modes of the bins embedded (partially or totally) in a given time window.

Parameters:
  • t0 (float) – start time of the window.

  • tend (float) – end time of the window.

Returns:

the amplitude of the modes for that time window.

Return type:

numpy.ndarray

time_window_bins(t0, tend)[source]

Find which bins are embedded (partially or totally) in a given time window.

Parameters:
  • t0 (float) – start time of the window.

  • tend (float) – end time of the window.

Returns:

indexes of the bins seen by the time window.

Return type:

numpy.ndarray

time_window_eigs(t0, tend)[source]

Get the eigenvalues relative to the modes of the bins embedded (partially or totally) in a given time window.

Parameters:
  • t0 (float) – start time of the window.

  • tend (float) – end time of the window.

Returns:

the eigenvalues for that time window.

Return type:

numpy.ndarray

time_window_frequency(t0, tend)[source]

Get the frequencies relative to the modes of the bins embedded (partially or totally) in a given time window.

Parameters:
  • t0 (float) – start time of the window.

  • tend (float) – end time of the window.

Returns:

the frequencies for that time window.

Return type:

numpy.ndarray

time_window_growth_rate(t0, tend)[source]

Get the growth rate values relative to the modes of the bins embedded (partially or totally) in a given time window.

Parameters:
  • t0 (float) – start time of the window.

  • tend (float) – end time of the window.

Returns:

the Floquet values for that time window.

Return type:

numpy.ndarray