Title: | Elastic Analysis of Sparse, Dense and Irregular Curves |
---|---|
Description: | Provides functions to align curves and to compute mean curves based on the elastic distance defined in the square-root-velocity framework. For more details on this framework see Srivastava and Klassen (2016, <doi:10.1007/978-1-4939-4020-2>). For more theoretical details on our methods and algorithms see Steyer et al. (2023, <doi:10.1111/biom.13706>) and Steyer et al. (2023, <arXiv:2305.02075>). |
Authors: | Lisa Steyer <[email protected]> |
Maintainer: | Lisa Steyer <[email protected]> |
License: | GPL-3 |
Version: | 1.1.3 |
Built: | 2025-02-19 06:31:52 UTC |
Source: | CRAN |
Finds the optimal reparametrization of the second curve (stored in
data_curve2
) to the first one (stored in data_curve1
) with respect
to the elastic distance. Constructor function for class aligned_curves
.
align_curves(data_curve1, data_curve2, closed = FALSE, eps = 0.01)
align_curves(data_curve1, data_curve2, closed = FALSE, eps = 0.01)
data_curve1 |
|
data_curve2 |
same as |
closed |
|
eps |
convergence tolerance |
an object of class aligned_curves
, which is a list
with entries
data_curve1 |
|
data_curve2_aligned |
|
elastic_dist |
elastic distance between curve1 and curve2 |
closed |
|
#open curves data_curve1 <- data.frame(x1 = c(1, 0.5, -1, -1), x2 = c(1, -0.5, -1, 1)) data_curve2 <- data.frame(x1 = c(0.1,0.7)*sin(1:6), x2 = cos(1:6)) aligned_curves <- align_curves(data_curve1, data_curve2) plot(aligned_curves) #different parametrization of the first curve data_curve1$t <- 0:3/3 align_curves(data_curve1, data_curve2) #closed curves data_curve1 <- data.frame(x1 = sin(0:12/5), x2 = cos(0:12/5)) data_curve2 <- data.frame(x1 = c(1, 0.5, -1, -1), x2 = c(1, -0.5, -1, 1)) aligned_curves_closed <- align_curves(data_curve1, data_curve2, closed = TRUE) plot(aligned_curves_closed, asp = 1)
#open curves data_curve1 <- data.frame(x1 = c(1, 0.5, -1, -1), x2 = c(1, -0.5, -1, 1)) data_curve2 <- data.frame(x1 = c(0.1,0.7)*sin(1:6), x2 = cos(1:6)) aligned_curves <- align_curves(data_curve1, data_curve2) plot(aligned_curves) #different parametrization of the first curve data_curve1$t <- 0:3/3 align_curves(data_curve1, data_curve2) #closed curves data_curve1 <- data.frame(x1 = sin(0:12/5), x2 = cos(0:12/5)) data_curve2 <- data.frame(x1 = c(1, 0.5, -1, -1), x2 = c(1, -0.5, -1, 1)) aligned_curves_closed <- align_curves(data_curve1, data_curve2, closed = TRUE) plot(aligned_curves_closed, asp = 1)
Centers curves for plotting
center_curve(data_curve)
center_curve(data_curve)
data_curve |
curve data |
a data.frame
with evaluations of the curve
centered at the origin
Computes a Fréchet mean for the curves stored in data_curves
) with respect
to the elastic distance. Constructor function for class elastic_mean
.
compute_elastic_mean( data_curves, knots = seq(0, 1, len = 5), type = c("smooth", "polygon"), closed = FALSE, eps = 0.01, pen_factor = 100, max_iter = 50 )
compute_elastic_mean( data_curves, knots = seq(0, 1, len = 5), type = c("smooth", "polygon"), closed = FALSE, eps = 0.01, pen_factor = 100, max_iter = 50 )
data_curves |
list of |
knots |
set of knots for the mean spline curve |
type |
if "smooth" linear srv-splines are used which results in a differentiable mean curve if "polygon" the mean will be piecewise linear. |
closed |
|
eps |
the algorithm stops if L2 norm of coefficients changes less |
pen_factor |
penalty factor forcing the mean to be closed |
max_iter |
maximal number of iterations |
an object of class elastic_mean
, which is a list
with entries
type |
"smooth" if mean was modeled using linear srv-splines or "polygon" if constant srv-splines are used |
coefs |
spline coeffiecients |
knots |
spline knots |
data_curves |
list of |
closed |
|
curve <- function(t){ rbind(t*cos(13*t), t*sin(13*t)) } set.seed(18) data_curves <- lapply(1:4, function(i){ m <- sample(10:15, 1) delta <- abs(rnorm(m, mean = 1, sd = 0.05)) t <- cumsum(delta)/sum(delta) data.frame(t(curve(t)) + 0.07*t*matrix(cumsum(rnorm(2*length(delta))), ncol = 2)) }) #compute elastic means knots <- seq(0,1, length = 11) smooth_elastic_mean <- compute_elastic_mean(data_curves, knots = knots) plot(smooth_elastic_mean) knots <- seq(0,1, length = 15) polygon_elastic_mean <- compute_elastic_mean(data_curves, knots = knots, type = "poly") lines(get_evals(polygon_elastic_mean), col = "blue", lwd = 2) #compute closed smooth mean, takes a little longer knots <- seq(0,1, length = 11) closed_elastic_mean <- compute_elastic_mean(data_curves, knots = knots, closed = TRUE) plot(closed_elastic_mean)
curve <- function(t){ rbind(t*cos(13*t), t*sin(13*t)) } set.seed(18) data_curves <- lapply(1:4, function(i){ m <- sample(10:15, 1) delta <- abs(rnorm(m, mean = 1, sd = 0.05)) t <- cumsum(delta)/sum(delta) data.frame(t(curve(t)) + 0.07*t*matrix(cumsum(rnorm(2*length(delta))), ncol = 2)) }) #compute elastic means knots <- seq(0,1, length = 11) smooth_elastic_mean <- compute_elastic_mean(data_curves, knots = knots) plot(smooth_elastic_mean) knots <- seq(0,1, length = 15) polygon_elastic_mean <- compute_elastic_mean(data_curves, knots = knots, type = "poly") lines(get_evals(polygon_elastic_mean), col = "blue", lwd = 2) #compute closed smooth mean, takes a little longer knots <- seq(0,1, length = 11) closed_elastic_mean <- compute_elastic_mean(data_curves, knots = knots, closed = TRUE) plot(closed_elastic_mean)
The elasdics package provides functions to align observed curves and to compute elastic means for collections of curves.
Align two observed curves: align_curves
Compute a mean for a set of observed curves: compute_elastic_mean
Finds optimal alignment for a discrete open srv curve to a smooth curve
find_optimal_t(srv_curve, s, q, initial_t = s, eps = 10 * .Machine$double.eps)
find_optimal_t(srv_curve, s, q, initial_t = s, eps = 10 * .Machine$double.eps)
srv_curve |
srv transformation of the smooth curve, needs to be vectorized |
s |
time points for q, first has to be 0, last has to be 1 |
q |
square root velocity vectors, one less than time points in s |
initial_t |
starting value for the optimization algorithm |
eps |
convergence tolerance |
optimal time points for q, without first value 0 and last value 1, optimal time points have the distance of the observation to the srv_curve as an attribute
Finds optimal aligned time points for srv curve q to srv curve p using coordinate wise optimization.
find_optimal_t_discrete(r, p, s, q, initial_t = s, eps = 10^-3)
find_optimal_t_discrete(r, p, s, q, initial_t = s, eps = 10^-3)
r |
time points for p, first has to be 0, last has to be 1 |
p |
square root velocity vectors, one less than time points in r |
s |
time points for q, first has to be 0, last has to be 1 |
q |
square root velocity vectors, one less than time points in s |
initial_t |
starting value for the optimization algorithm |
eps |
convergence tolerance |
optimal time points for q, without first value 0 and last value 1 optimal time points have the distance of the observation to the srv_curve as an attribute
Finds optimal aligned time points for srv curve q to srv curve p using coordinate wise optimization.
find_optimal_t_discrete_closed(r, p, s, q, initial_t, eps = 10^-3)
find_optimal_t_discrete_closed(r, p, s, q, initial_t, eps = 10^-3)
r |
time points for p, first is last - 1 |
p |
square root velocity vectors, one less than time points in r |
s |
time points for q, first is last - 1 |
q |
square root velocity vectors, one less than time points in s |
initial_t |
starting value for the optimization algorithm |
eps |
convergence tolerance |
optimal time points for q, first is last -1
Computes a Fréchet mean for the curves stored in data_curves
with respect
to the elastic distance. Constructor function for class elastic_reg_model
.
fit_elastic_regression( formula, data_curves, x_data, knots = seq(0, 1, 0.2), type = "smooth", closed = FALSE, max_iter = 10, eps = 0.001, pre_align = FALSE )
fit_elastic_regression( formula, data_curves, x_data, knots = seq(0, 1, 0.2), type = "smooth", closed = FALSE, max_iter = 10, eps = 0.001, pre_align = FALSE )
formula |
an object of class "formula" of the form data_curves ~ ...". |
data_curves |
list of |
x_data |
a |
knots |
set of knots for the parameter curves of the regression model |
type |
if "smooth" linear srv-splines are used which results in a differentiable mean curve if "polygon" the mean will be piecewise linear. |
closed |
|
max_iter |
maximal number of iterations |
eps |
the algorithm stops if L2 norm of coefficients changes less |
pre_align |
TRUE if curves should be pre aligned to the mean |
an object of class elastic_reg_model
, which is a list
with entries
type |
"smooth" if linear srv-splines or "polygon" if constant srv-splines were used |
coefs |
spline coeffiecients |
knots |
spline knots |
data_curves |
list of |
closed |
|
curve <- function(x_1, x_2, t){ rbind(2*t*cos(6*t) - x_1*t , x_2*t*sin(6*t)) } set.seed(18) x_data <- data.frame(x_1 = runif(10,-1,1), x_2 = runif(10,-1,1)) data_curves <- apply(x_data, 1, function(x){ m <- sample(10:15, 1) delta <- abs(rnorm(m, mean = 1, sd = 0.05)) t <- cumsum(delta)/sum(delta) data.frame(t(curve((x[1] + 1), (x[2] + 2), t)) + 0.07*t*matrix(cumsum(rnorm(2*length(delta))), ncol = 2)) }) reg_model <- fit_elastic_regression(data_curves ~ x_1 + x_2, data_curves = data_curves, x_data = x_data) plot(reg_model)
curve <- function(x_1, x_2, t){ rbind(2*t*cos(6*t) - x_1*t , x_2*t*sin(6*t)) } set.seed(18) x_data <- data.frame(x_1 = runif(10,-1,1), x_2 = runif(10,-1,1)) data_curves <- apply(x_data, 1, function(x){ m <- sample(10:15, 1) delta <- abs(rnorm(m, mean = 1, sd = 0.05)) t <- cumsum(delta)/sum(delta) data.frame(t(curve((x[1] + 1), (x[2] + 2), t)) + 0.07*t*matrix(cumsum(rnorm(2*length(delta))), ncol = 2)) }) reg_model <- fit_elastic_regression(data_curves ~ x_1 + x_2, data_curves = data_curves, x_data = x_data) plot(reg_model)
Fits an elastic mean for open curves. Is usually called from
compute_elastic_mean
.
fit_mean(srv_data_curves, knots, max_iter, type, eps)
fit_mean(srv_data_curves, knots, max_iter, type, eps)
srv_data_curves |
list of |
knots |
set of knots for the mean spline curve |
max_iter |
maximal number of iterations |
type |
if "smooth" linear srv-splines are used which results in a differentiable mean curve if "polygon" the mean will be piecewise linear. |
eps |
the algorithm stops if L2 norm of coefficients changes less |
a list
with entries
type |
"smooth" or "polygon" |
coefs |
|
knots |
spline knots |
t_optims |
optimal parametrization |
Fits an elastic mean for open curves. Is usually called from
compute_elastic_mean
.
fit_mean_closed(srv_data_curves, knots, max_iter, type, eps, pen_factor)
fit_mean_closed(srv_data_curves, knots, max_iter, type, eps, pen_factor)
srv_data_curves |
list of |
knots |
set of knots for the mean spline curve |
max_iter |
maximal number of iterations |
type |
if "smooth" linear srv-splines are used which results in a differentiable mean curve |
eps |
the algorithm stops if L2 norm of coefficients changes less |
pen_factor |
penalty factor forcing the mean to be closed if "polygon" the mean will be piecewise linear. |
a list
with entries
type |
"smooth" or "polygon" |
coefs |
|
knots |
spline knots |
t_optims |
optimal parametrization |
shift_idxs |
index of the starting point of the closed curve after alignment |
Evaluate a curve on a grid
get_evals(curve, t_grid = NULL, ...) ## S3 method for class 'data.frame' get_evals(curve, t_grid = NULL, ...) ## S3 method for class 'elastic_mean' get_evals(curve, t_grid = NULL, centering = TRUE, ...)
get_evals(curve, t_grid = NULL, ...) ## S3 method for class 'data.frame' get_evals(curve, t_grid = NULL, ...) ## S3 method for class 'elastic_mean' get_evals(curve, t_grid = NULL, centering = TRUE, ...)
curve |
a one parameter function which is to be evaluated on a grid |
t_grid |
the curve is evaluated at the values in t_grid, first value needs to be 0, last value needs to be 1. If t_grid = NULL, a default regular grid with grid length 0.01 is chosen |
... |
other arguments |
centering |
TRUE if curves shall be centered |
a data.frame
with evaluations of the curve
at the values in t_grid
in its rows.
curve <- function(t){c(t*sin(10*t), t*cos(10*t))} plot(get_evals(curve), type = "b")
curve <- function(t){c(t*sin(10*t), t*cos(10*t))} plot(get_evals(curve), type = "b")
Compute the square-root-velocity transformation or the parametrization with respect to arc length for a curve observed at discrete points.
get_srv_from_points(data_curve) get_points_from_srv(srv_data) get_arc_length_param(data_curve)
get_srv_from_points(data_curve) get_points_from_srv(srv_data) get_arc_length_param(data_curve)
data_curve |
A |
srv_data |
A |
get_srv_from_points
returns a data.frame
with
first column t
corresponding to the parametrization and square-root-velocity
vectors in the remaining columns. If no parametrization is given, the curve will
be parametrized with respect to arc length. This parametrization will be
computed by a call to get_arc_length_param
as well.
get_srv_from_points()
: Compute square-root-velocity transformation
for curve data measured at discrete points. The inverse transformation can
be computed with get_points_from_s
get_points_from_srv()
: The inverse transformation to
get_srv_from_points
. Transforms square-root-velocity data to
points representing a curve (with no parametrization).
get_arc_length_param()
: Compute arc length parametrization.
data_curve1 <- data.frame(x1 = 1:6*sin(1:6), x2 = cos(1:6)) get_arc_length_param(data_curve1) #same parametrization as in get_srv_from_points(data_curve1) data_curve2 <- data.frame(t = seq(0,1, length = 6), data_curve1) plot(data_curve2[,2:3], type = "l", xlim = c(-6, 2), ylim = c(-2, 1)) srv_data <- get_srv_from_points(data_curve2) #back transformed curve starts at (0,0) lines(get_points_from_srv(srv_data), col = "red")
data_curve1 <- data.frame(x1 = 1:6*sin(1:6), x2 = cos(1:6)) get_arc_length_param(data_curve1) #same parametrization as in get_srv_from_points(data_curve1) data_curve2 <- data.frame(t = seq(0,1, length = 6), data_curve1) plot(data_curve2[,2:3], type = "l", xlim = c(-6, 2), ylim = c(-2, 1)) srv_data <- get_srv_from_points(data_curve2) #back transformed curve starts at (0,0) lines(get_points_from_srv(srv_data), col = "red")
Does optimization in one parameter direction
optimise_one_coord_analytic(t, i, r, p, s, q)
optimise_one_coord_analytic(t, i, r, p, s, q)
t |
current time points, first has to be 0, last has to be 1 |
i |
index of t that should be updated |
r |
time points for p, first has to be 0, last has to be 1 |
p |
square root velocity vectors, one less than time points in r |
s |
time points for q, first has to be 0, last has to be 1 |
q |
square root velocity vectors, one less than time points in s |
optimal time points for q with respect to optimization only in the i-th coordinate direction
Does optimization in one parameter direction
optimise_one_coord_analytic_closed(t, i, r, p, s, q)
optimise_one_coord_analytic_closed(t, i, r, p, s, q)
t |
current time points, first has to be 0, last has to be 1 |
i |
index of t that should be updated |
r |
time points for p, first is last - 1 |
p |
square root velocity vectors, one less than time points in r |
s |
time points for q, first is last - 1 |
q |
square root velocity vectors, one less than time points in s |
optimal time points for q with respect to optimization only in the i-th coordinate direction
Plots objects of class aligned_curves
.
Points of same color correspond after the second curve is optimally aligned to the first curve.
## S3 method for class 'aligned_curves' plot(x, points_col = rainbow, ...)
## S3 method for class 'aligned_curves' plot(x, points_col = rainbow, ...)
x |
object of class |
points_col |
which color palette is used for points on the curves,
default is rainbow, see |
... |
further plotting parameters. |
No value
For examples see documentation of align_curves
.
Plots objects of class elastic_mean
.
## S3 method for class 'elastic_mean' plot(x, asp = 1, col = "red", ...)
## S3 method for class 'elastic_mean' plot(x, asp = 1, col = "red", ...)
x |
object of class |
asp |
numeric, giving the aspect ratio of the two coordinates,
see |
col |
color of the mean curve. |
... |
further plotting parameters. |
No value
For examples see documentation of compute_elastic_mean
.
Plots objects of class elastic_reg_model
.
## S3 method for class 'elastic_reg_model' plot(x, asp = 1, col = "red", ...)
## S3 method for class 'elastic_reg_model' plot(x, asp = 1, col = "red", ...)
x |
object of class |
asp |
numeric, giving the aspect ratio of the two coordinates,
see |
col |
color of the predicted curves. |
... |
further plotting parameters. |
No value
For examples see documentation of fit_elastic_regression
.
predicted curves for elastic regression model objects.
## S3 method for class 'elastic_reg_model' predict(object, newdata = NULL, t_grid = seq(0, 1, 0.01), ...)
## S3 method for class 'elastic_reg_model' predict(object, newdata = NULL, t_grid = seq(0, 1, 0.01), ...)
object |
object of class |
newdata |
an optional |
t_grid |
grid on which the predicted curves are evaluated. |
... |
further arguments passed to or from other methods. |
a list
of data.frame
s with predicted curves
For examples see documentation of fit_elastic_regression
.
Close open curve via projection on derivative level.
project_curve_on_closed(data_curve)
project_curve_on_closed(data_curve)
data_curve |
|
a data.frame
with closed curve.
Re-transform srv curve back to curve
srvf_to_curve(t, srv_curve)
srvf_to_curve(t, srv_curve)
t |
time points at which the resulting curve shall be evaluated. |
srv_curve |
srv curve as a function of one parameter, needs to be vectorized. |
a matrix
with curve evaluations at time points t in its columns,
rows correspond to coordinate directions