GitHub

R API Reference

Complete reference for the koopman.dmd R package -- Rust-powered Koopman DMD with idiomatic S3 classes.

Installation

The koopman.dmd package is an R wrapper around the Rust koopman-dmd library. Building from source requires a working Rust toolchain (cargo and rustc) in addition to the standard R development tools.

# Install from the local source directory
R CMD INSTALL koopman-dmd-r

Verify the installation by loading the package in an R session:

library(koopman.dmd)
cat("koopman.dmd loaded successfully\n")
Requirements. You need cargo and rustc installed and available on your PATH. The package build process compiles the Rust library automatically using Cargo. On Linux, ensure libR-dev (Debian/Ubuntu) or R-devel (Fedora/RHEL) is installed.

DMD Functions

dmd

Perform Dynamic Mode Decomposition on a numeric matrix. This is the primary entry point for standard and extended DMD analysis. Returns an S3 object of class "dmd".

Argument Type Default Description
data numeric matrix -- Data matrix with dimensions n_vars x n_time. Each row is a state variable; each column is a time snapshot.
rank integer or NULL NULL Truncation rank for the SVD. NULL selects rank automatically via singular-value threshold.
center logical FALSE If TRUE, subtract the temporal mean from each row before decomposition. The mean is stored and added back during reconstruction.
lifting character or NULL NULL Optional nonlinear lifting function. One of "polynomial", "trigonometric", or "delay".
lifting_param integer or NULL NULL Parameter for the lifting function: polynomial degree, number of harmonics, or number of delay embeddings.

Return value. An S3 object of class "dmd" with the following components:

Component Type Description
eigenvalues_re numeric vector Real parts of the DMD eigenvalues.
eigenvalues_im numeric vector Imaginary parts of the DMD eigenvalues.
rank integer Truncation rank used in the decomposition.
n_vars integer Number of state variables (rows of the input).
n_time integer Number of time snapshots (columns of the input).
.result_ptr externalptr Internal pointer to the Rust result object. Used by downstream functions; do not modify.
library(koopman.dmd)

# Generate sample data: 3 variables, 100 time steps
t <- seq(0, 2 * pi, length.out = 100)
data <- rbind(
  sin(t),
  cos(t),
  sin(2 * t)
)

# Standard DMD with auto-rank
result <- dmd(data)

# DMD with explicit rank and centering
result <- dmd(data, rank = 4, center = TRUE)

# Extended DMD with polynomial lifting
result <- dmd(data, lifting = "polynomial", lifting_param = 3L)

# Extended DMD with trigonometric lifting
result <- dmd(data, lifting = "trigonometric", lifting_param = 5L)

# Extended DMD with delay embedding
result <- dmd(data, lifting = "delay", lifting_param = 10L)

S3 print method for "dmd" objects. Displays a concise summary including the rank, number of variables, and number of time steps.

print(result)
# DMD Result
#   Rank:       4
#   Variables:  3
#   Time steps: 100

summary.dmd

S3 summary method for "dmd" objects. Prints a table of eigenvalues with their real parts, imaginary parts, moduli, and frequencies.

summary(result)
# DMD Eigenvalues:
#   Re(lambda)  Im(lambda)  |lambda|  Frequency
#   0.9998      0.0175      1.0000    0.0028
#   0.9998     -0.0175      1.0000   -0.0028
#   ...

predict.dmd

S3 predict method for "dmd" objects. Extrapolates the fitted DMD model forward in time.

Argument Type Default Description
object dmd -- A fitted DMD result.
n_ahead integer -- Number of future time steps to predict.
x0 numeric vector or NULL NULL Optional initial condition. If NULL, uses the first snapshot from the original data.

Return value. A numeric matrix of dimensions n_vars x n_ahead containing the predicted states.

# Predict 50 future time steps
forecast <- predict(result, n_ahead = 50)
cat("Forecast dimensions:", dim(forecast), "\n")

# Predict from a custom initial condition
x0 <- c(0.5, 0.5, 0.5)
forecast <- predict(result, n_ahead = 50, x0 = x0)

dmd_reconstruct

Reconstruct the original data from the DMD decomposition. Produces the fitted values by combining modes, eigenvalues, and amplitudes. If centering was used, the stored mean is added back automatically.

Argument Type Default Description
result dmd -- A fitted DMD result.
n_time integer -- Number of time steps to reconstruct.
x0 numeric vector or NULL NULL Optional initial condition. If NULL, uses the first snapshot from the original data.

Return value. A numeric matrix of dimensions n_vars x n_time containing the reconstructed data.

# Reconstruct the original 100 time steps
recon <- dmd_reconstruct(result, n_time = 100)
cat("Reconstruction dimensions:", dim(recon), "\n")

dmd_spectrum

Compute the spectral properties of the DMD decomposition. Returns a data frame summarizing the frequency content, growth rates, damping, and stability of each mode.

Argument Type Default Description
result dmd -- A fitted DMD result.
dt numeric 1.0 Time step between snapshots. Used to convert discrete eigenvalues to continuous-time frequencies.

Return value. A data.frame with the following columns:

Column Type Description
frequency numeric Angular frequency of each mode (radians per unit time).
magnitude numeric Modulus of the eigenvalue (distance from origin).
growth_rate numeric Continuous-time growth rate (log of modulus divided by dt).
damping_ratio numeric Damping ratio of each mode.
stability character One of "stable", "unstable", or "neutral".
# Compute spectrum with default time step
spec <- dmd_spectrum(result)
print(spec)

# Compute spectrum with explicit time step
spec <- dmd_spectrum(result, dt = 0.01)
print(spec)

dmd_stability

Assess the stability of the DMD model by examining the eigenvalue spectrum.

Argument Type Default Description
result dmd -- A fitted DMD result.
tol numeric 1e-6 Tolerance for classifying eigenvalues as neutral (on the unit circle).

Return value. A list with the following components:

Component Type Description
spectral_radius numeric Maximum modulus among all eigenvalues.
is_stable logical TRUE if all eigenvalues lie inside or on the unit circle (within tolerance).
is_unstable logical TRUE if any eigenvalue lies outside the unit circle.
n_growing integer Number of eigenvalues with modulus greater than 1 + tol.
n_decaying integer Number of eigenvalues with modulus less than 1 - tol.
n_neutral integer Number of eigenvalues with modulus within tol of 1.
stab <- dmd_stability(result)
cat("Spectral radius:", stab$spectral_radius, "\n")
cat("Stable:", stab$is_stable, "\n")
cat("Growing modes:", stab$n_growing, "\n")
cat("Decaying modes:", stab$n_decaying, "\n")
cat("Neutral modes:", stab$n_neutral, "\n")

dmd_error

Compute reconstruction error metrics for a DMD result against the original data.

Argument Type Default Description
result dmd -- A fitted DMD result.
data numeric matrix -- The original data matrix used for fitting.

Return value. A list with the following components:

Component Type Description
rmse numeric Root mean squared error across all entries.
relative_error numeric Frobenius norm of the residual divided by the Frobenius norm of the original data.
max_error numeric Maximum absolute error across all entries.
err <- dmd_error(result, data)
cat("RMSE:          ", err$rmse, "\n")
cat("Relative error:", err$relative_error, "\n")
cat("Max error:     ", err$max_error, "\n")

dmd_dominant_modes

Extract the dominant DMD modes ranked by a specified criterion.

Argument Type Default Description
result dmd -- A fitted DMD result.
criterion character "amplitude" Ranking criterion. One of "amplitude" (mode amplitude) or other supported criteria.
n integer 3 Number of top modes to return.

Return value. A data.frame with one row per dominant mode, including eigenvalue, frequency, amplitude, and growth rate columns.

# Get top 3 modes by amplitude
top <- dmd_dominant_modes(result, criterion = "amplitude", n = 3)
print(top)

dmd_residual

Compute residuals for each DMD mode, measuring how well each mode satisfies the linear operator relationship.

Argument Type Default Description
result dmd -- A fitted DMD result.

Return value. A list with the following components:

Component Type Description
mode_residuals numeric vector Residual norm for each individual mode.
max_residual numeric Maximum residual across all modes.
mean_residual numeric Mean residual across all modes.
resid <- dmd_residual(result)
cat("Max residual: ", resid$max_residual, "\n")
cat("Mean residual:", resid$mean_residual, "\n")
print(resid$mode_residuals)

Hankel-DMD Functions

hankel_dmd

Perform Hankel-DMD, which augments the data with time-delay embeddings before applying DMD. This is particularly effective for scalar time series or systems where a single observable does not fully capture the underlying dynamics. Returns an S3 object of class "hankel_dmd".

Argument Type Default Description
data numeric matrix -- Data matrix with dimensions n_vars x n_time.
delays integer or NULL NULL Number of delay embeddings. NULL selects automatically.
rank integer or NULL NULL Truncation rank. NULL selects automatically.
dt numeric 1.0 Time step between snapshots.

Return value. An S3 object of class "hankel_dmd" with components similar to the standard "dmd" class, plus delay embedding metadata.

library(koopman.dmd)

# Scalar time series: 1 x 500 matrix
t <- seq(0, 10 * pi, length.out = 500)
data <- matrix(sin(t) + 0.5 * sin(3 * t), nrow = 1)

# Hankel-DMD with 20 delays
hresult <- hankel_dmd(data, delays = 20)
print(hresult)

S3 print method for "hankel_dmd" objects. Displays a concise summary including the rank, delay embedding depth, and data dimensions.

print(hresult)
# Hankel-DMD Result
#   Rank:    10
#   Delays:  20
#   Vars:    1
#   Steps:   500

predict.hankel_dmd

S3 predict method for "hankel_dmd" objects. Extrapolates the fitted Hankel-DMD model forward in time.

Argument Type Default Description
object hankel_dmd -- A fitted Hankel-DMD result.
n_ahead integer -- Number of future time steps to predict.

Return value. A numeric matrix containing the predicted states in the original (non-embedded) variable space.

# Predict 100 steps ahead
hforecast <- predict(hresult, n_ahead = 100)
cat("Forecast dimensions:", dim(hforecast), "\n")

hankel_reconstruct

Reconstruct the original data from the Hankel-DMD decomposition, projecting back from the delay-embedded space to the original variable space.

Argument Type Default Description
result hankel_dmd -- A fitted Hankel-DMD result.

Return value. A numeric matrix containing the reconstructed data.

hrecon <- hankel_reconstruct(hresult)
cat("Reconstruction dimensions:", dim(hrecon), "\n")

GLA Functions

gla

Perform Generalized Laplace Analysis (GLA) to extract Koopman eigenvalues and eigenfunctions from trajectory data. GLA is an iterative algorithm that converges to the dominant Koopman modes. Returns an S3 object of class "gla".

Argument Type Default Description
data numeric matrix -- Data matrix with dimensions n_vars x n_time.
n_eigenvalues integer 2 Number of Koopman eigenvalues to extract.
tol numeric 1e-6 Convergence tolerance for the iterative algorithm.
max_iter integer or NULL NULL Maximum number of iterations. NULL uses a library default.

Return value. An S3 object of class "gla" containing the extracted Koopman eigenvalues and associated data.

library(koopman.dmd)

# Generate trajectory data
t <- seq(0, 4 * pi, length.out = 200)
data <- rbind(sin(t), cos(t))

# Extract 4 Koopman eigenvalues
gresult <- gla(data, n_eigenvalues = 4, tol = 1e-8)
print(gresult)

S3 print method for "gla" objects. Displays a summary of the GLA result including the number of extracted eigenvalues and convergence information.

print(gresult)
# GLA Result
#   Eigenvalues: 4
#   Converged:   TRUE

predict.gla

S3 predict method for "gla" objects. Extrapolates the fitted GLA model forward in time using the extracted Koopman modes.

Argument Type Default Description
object gla -- A fitted GLA result.
n_ahead integer -- Number of future time steps to predict.

Return value. A numeric matrix containing the predicted states.

# Predict 50 steps ahead
gforecast <- predict(gresult, n_ahead = 50)
cat("Forecast dimensions:", dim(gforecast), "\n")

gla_reconstruct

Reconstruct the original data from the GLA decomposition.

Argument Type Default Description
result gla -- A fitted GLA result.

Return value. A numeric matrix containing the reconstructed data.

grecon <- gla_reconstruct(gresult)
cat("Reconstruction dimensions:", dim(grecon), "\n")

Map Functions

generate_trajectory

Iterate a dynamical map from a given initial condition and return a matrix of states. Each column of the returned matrix is a snapshot of the system state at a single time step.

Argument Type Default Description
ic numeric vector -- Initial condition vector. Length must match the dimensionality of the selected map.
map character -- Map name. One of "standard", "froeschle", "extended_standard", "henon", or "logistic".
n_steps integer -- Number of iterations to compute.
... various -- Map-specific parameters. See helper constructors below.

Return value. A numeric matrix of dimensions n_dim x n_steps where n_dim is the dimensionality of the map.

library(koopman.dmd)

# Standard map
traj <- generate_trajectory(
  ic = c(0.1, 0.2),
  map = "standard",
  n_steps = 1000,
  epsilon = 0.12
)
cat("Trajectory shape:", dim(traj), "\n")  # 2 x 1000

# Henon map
traj <- generate_trajectory(
  ic = c(0.0, 0.0),
  map = "henon",
  n_steps = 5000,
  a = 1.4,
  b = 0.3
)

# Logistic map
traj <- generate_trajectory(
  ic = 0.4,
  map = "logistic",
  n_steps = 500,
  r = 3.9
)

Helper Constructors

Convenience functions that return named lists of map parameters with sensible defaults. These can be expanded with do.call or used for documentation purposes.

Function Parameters Defaults
standard_map(epsilon) epsilon 0.12
froeschle_map(epsilon1, epsilon2, epsilon3) epsilon1, epsilon2, epsilon3 0.12, 0.12, 0.05
extended_standard_map(epsilon, alpha) epsilon, alpha --
henon_map(a, b) a, b 1.4, 0.3
logistic_map(r) r 3.9
# Using helper constructors
params <- standard_map(epsilon = 0.25)
print(params)
# $map
# [1] "standard"
# $epsilon
# [1] 0.25

params <- henon_map()  # uses defaults a=1.4, b=0.3
params <- logistic_map(r = 3.7)

# Use with do.call
traj <- do.call(generate_trajectory, c(
  list(ic = c(0.1, 0.2), n_steps = 1000),
  standard_map(epsilon = 0.3)
))

Harmonic Analysis Functions

harmonic_time_average

Compute the harmonic time average (HTA) of an observable along a trajectory generated by a dynamical map. The HTA is a key tool in Koopman operator theory for extracting frequency-specific information from orbits.

Argument Type Default Description
ic numeric vector -- Initial condition for the trajectory.
map character -- Map name (same choices as generate_trajectory).
observable character -- Observable function. One of "identity", "sin_pi", "cos_pi", "sin_pi_xy", or "quadratic".
omega numeric -- Frequency parameter for the harmonic average.
n_iter integer -- Number of iterations for the time average.
... various -- Map-specific parameters (e.g., epsilon).

Return value. A list with the following components:

Component Type Description
magnitude numeric Magnitude (absolute value) of the harmonic time average.
phase numeric Phase angle of the harmonic time average (radians).
real numeric Real part of the harmonic time average.
imag numeric Imaginary part of the harmonic time average.
library(koopman.dmd)

# HTA of identity observable on standard map
hta <- harmonic_time_average(
  ic = c(0.1, 0.2),
  map = "standard",
  observable = "identity",
  omega = 0.0,
  n_iter = 10000,
  epsilon = 0.12
)
cat("Magnitude:", hta$magnitude, "\n")
cat("Phase:    ", hta$phase, "\n")

mesochronic_compute

Compute harmonic time averages over a grid of initial conditions, producing a mesochronic map of the phase space. This reveals the structure of Koopman eigenfunctions and distinguishes regular from chaotic regions.

Argument Type Default Description
map character -- Map name.
x_range numeric(2) -- Range of x-coordinates as c(x_min, x_max).
y_range numeric(2) -- Range of y-coordinates as c(y_min, y_max).
resolution integer -- Number of grid points along each axis.
observable character -- Observable function (same choices as harmonic_time_average).
omega numeric -- Frequency parameter.
n_iter integer -- Number of iterations for each initial condition.
... various -- Map-specific parameters.

Return value. A list with the following components:

Component Type Description
hta_matrix numeric matrix Matrix of HTA magnitudes over the grid (resolution x resolution).
phase_matrix numeric matrix Matrix of HTA phases over the grid (resolution x resolution).
x_coords numeric vector Vector of x-coordinates for the grid.
y_coords numeric vector Vector of y-coordinates for the grid.
# Mesochronic analysis of the standard map
meso <- mesochronic_compute(
  map = "standard",
  x_range = c(0, 1),
  y_range = c(0, 1),
  resolution = 200,
  observable = "identity",
  omega = 0.0,
  n_iter = 5000,
  epsilon = 0.12
)

# Plot with base R
image(
  meso$x_coords,
  meso$y_coords,
  meso$hta_matrix,
  col = hcl.colors(256, "viridis"),
  xlab = "x",
  ylab = "y",
  main = "Mesochronic Map"
)

classify_phase_space

Classify an initial condition as belonging to a regular or chaotic region of phase space, based on the convergence behavior of the harmonic time average.

Argument Type Default Description
ic numeric vector -- Initial condition.
map character -- Map name.
omega numeric -- Frequency parameter.
n_iter integer -- Number of iterations.
... various -- Map-specific parameters.

Return value. A list with the following components:

Component Type Description
classification character One of "regular", "chaotic", or "boundary".
hta_magnitude numeric Magnitude of the harmonic time average at convergence.
hta_phase numeric Phase of the harmonic time average at convergence.
# Classify a point on the standard map
cls <- classify_phase_space(
  ic = c(0.1, 0.2),
  map = "standard",
  omega = 0.0,
  n_iter = 10000,
  epsilon = 0.12
)
cat("Classification:", cls$classification, "\n")
cat("HTA magnitude: ", cls$hta_magnitude, "\n")

hta_convergence

Track the convergence of the harmonic time average as a function of the number of iterations. Useful for determining the required iteration depth and for visualizing the convergence behavior of regular versus chaotic orbits.

Argument Type Default Description
ic numeric vector -- Initial condition.
map character -- Map name.
observable character -- Observable function.
omega numeric -- Frequency parameter.
max_iter integer -- Maximum number of iterations.
step integer -- Record the HTA magnitude every step iterations.
... various -- Map-specific parameters.

Return value. A data.frame with two columns:

Column Type Description
iteration integer Iteration number at which the magnitude was recorded.
magnitude numeric HTA magnitude at this iteration.
# Track HTA convergence for a regular orbit
conv <- hta_convergence(
  ic = c(0.1, 0.2),
  map = "standard",
  observable = "identity",
  omega = 0.0,
  max_iter = 50000,
  step = 500,
  epsilon = 0.12
)
plot(conv$iteration, conv$magnitude,
     type = "l", xlab = "Iteration", ylab = "HTA Magnitude")

Examples

Complete DMD Workflow

library(koopman.dmd)

# -- Generate synthetic data --
t <- seq(0, 4 * pi, length.out = 200)
data <- rbind(
  sin(t) + 0.1 * sin(5 * t),
  cos(t) + 0.1 * cos(5 * t)
)

# -- Fit DMD --
result <- dmd(data, rank = 4)
print(result)
summary(result)

# -- Prediction --
forecast <- predict(result, n_ahead = 100)
matplot(t(forecast), type = "l", main = "DMD Forecast")

# -- Reconstruction error --
err <- dmd_error(result, data)
cat("RMSE:          ", err$rmse, "\n")
cat("Relative error:", err$relative_error, "\n")

# -- Spectrum --
spec <- dmd_spectrum(result, dt = 0.01)
print(spec)

# -- Stability --
stab <- dmd_stability(result)
cat("Stable:", stab$is_stable, "\n")

# -- Dominant modes --
top <- dmd_dominant_modes(result, n = 3)
print(top)

Hankel-DMD for Scalar Time Series

library(koopman.dmd)

# Scalar time series with two frequencies
t <- seq(0, 20 * pi, length.out = 1000)
data <- matrix(sin(t) + 0.5 * sin(3 * t), nrow = 1)

# Fit Hankel-DMD
hresult <- hankel_dmd(data, delays = 30, rank = 4)
print(hresult)

# Predict and reconstruct
hforecast <- predict(hresult, n_ahead = 200)
hrecon <- hankel_reconstruct(hresult)

# Compare reconstruction to original
plot(data[1, ], type = "l", col = "black", ylab = "x",
     main = "Hankel-DMD Reconstruction")
lines(hrecon[1, ], col = "red", lty = 2)
legend("topright", c("Original", "Reconstructed"),
       col = c("black", "red"), lty = c(1, 2))

GLA Eigenvalue Extraction

library(koopman.dmd)

# Oscillatory data
t <- seq(0, 8 * pi, length.out = 500)
data <- rbind(sin(t), cos(t))

# Extract 4 Koopman eigenvalues with GLA
gresult <- gla(data, n_eigenvalues = 4, tol = 1e-8)
print(gresult)

# Predict and reconstruct
gforecast <- predict(gresult, n_ahead = 100)
grecon <- gla_reconstruct(gresult)

matplot(t(grecon), type = "l", main = "GLA Reconstruction")

Trajectory Generation and Phase Portraits

library(koopman.dmd)

# Standard map phase portrait
par(mfrow = c(1, 2))

# Regular orbit
traj1 <- generate_trajectory(
  ic = c(0.1, 0.2),
  map = "standard",
  n_steps = 5000,
  epsilon = 0.12
)
plot(traj1[1, ], traj1[2, ],
     pch = ".", xlab = "x", ylab = "y",
     main = "Standard Map (regular)")

# Chaotic orbit
traj2 <- generate_trajectory(
  ic = c(0.5, 0.5),
  map = "standard",
  n_steps = 50000,
  epsilon = 0.97
)
plot(traj2[1, ], traj2[2, ],
     pch = ".", xlab = "x", ylab = "y",
     main = "Standard Map (chaotic)")

# Henon attractor
par(mfrow = c(1, 1))
henon <- generate_trajectory(
  ic = c(0.0, 0.0),
  map = "henon",
  n_steps = 10000,
  a = 1.4,
  b = 0.3
)
plot(henon[1, ], henon[2, ],
     pch = ".", xlab = "x", ylab = "y",
     main = "Henon Attractor")

# Logistic map bifurcation diagram
rs <- seq(2.5, 4.0, by = 0.005)
plot(NULL, xlim = c(2.5, 4), ylim = c(0, 1),
     xlab = "r", ylab = "x", main = "Logistic Map Bifurcation")
for (r in rs) {
  traj <- generate_trajectory(
    ic = 0.4, map = "logistic", n_steps = 300, r = r
  )
  points(rep(r, 50), traj[1, 251:300], pch = ".", cex = 0.5)
}

Harmonic Time Averages and Mesochronic Analysis

library(koopman.dmd)

# -- Single-point HTA --
hta <- harmonic_time_average(
  ic = c(0.1, 0.2),
  map = "standard",
  observable = "sin_pi",
  omega = 0.0,
  n_iter = 20000,
  epsilon = 0.12
)
cat("HTA magnitude:", hta$magnitude, "\n")
cat("HTA phase:    ", hta$phase, "\n")

# -- Mesochronic map --
meso <- mesochronic_compute(
  map = "standard",
  x_range = c(0, 1),
  y_range = c(0, 1),
  resolution = 300,
  observable = "cos_pi",
  omega = 0.0,
  n_iter = 10000,
  epsilon = 0.12
)

image(
  meso$x_coords, meso$y_coords, meso$hta_matrix,
  col = hcl.colors(256, "viridis"),
  xlab = "x", ylab = "y",
  main = "Mesochronic Map (cos_pi, omega=0)"
)

# -- Phase space classification --
cls <- classify_phase_space(
  ic = c(0.5, 0.5),
  map = "standard",
  omega = 0.0,
  n_iter = 50000,
  epsilon = 0.97
)
cat("Classification:", cls$classification, "\n")

# -- Convergence tracking --
conv <- hta_convergence(
  ic = c(0.1, 0.2),
  map = "standard",
  observable = "quadratic",
  omega = 0.0,
  max_iter = 100000,
  step = 1000,
  epsilon = 0.12
)
plot(conv$iteration, conv$magnitude,
     type = "l", log = "x",
     xlab = "Iteration", ylab = "HTA Magnitude",
     main = "HTA Convergence")