% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/DISTANCES-dtw-lb.R
\name{dtw_lb}
\alias{dtw_lb}
\title{DTW distance matrix guided by Lemire's improved lower bound}
\usage{
dtw_lb(
  x,
  y = NULL,
  window.size = NULL,
  norm = "L1",
  error.check = TRUE,
  pairwise = FALSE,
  dtw.func = "dtw_basic",
  nn.margin = 1L,
  ...
)
}
\arguments{
\item{x, y}{A matrix or data frame where rows are time series, or a list of time series.}

\item{window.size}{Window size to use with the LB and DTW calculation. See details.}

\item{norm}{Either \code{"L1"} for Manhattan distance or \code{"L2"} for Euclidean.}

\item{error.check}{Logical indicating whether the function should try to detect inconsistencies
and give more informative errors messages. Also used internally to avoid repeating checks.}

\item{pairwise}{Calculate pairwise distances?}

\item{dtw.func}{Which function to use for the core DTW calculations, either "dtw" or "dtw_basic".
See \code{\link[dtw:dtw]{dtw::dtw()}} and \code{\link[=dtw_basic]{dtw_basic()}}.}

\item{nn.margin}{Either 1 to search for nearest neighbors row-wise, or 2 to search column-wise.
Only implemented for \code{dtw.func} = "dtw_basic".}

\item{...}{Further arguments for \code{dtw.func} or \code{\link[=lb_improved]{lb_improved()}}.}
}
\value{
The distance matrix with class \code{crossdist}.
}
\description{
Calculation of a distance matrix with the Dynamic Time Warping (DTW) distance guided by Lemire's
improved lower bound (LB_Improved).
}
\details{
This function first calculates an initial estimate of a distance matrix between two sets of time
series using \code{\link[=lb_improved]{lb_improved()}} (the \code{\link[proxy:dist]{proxy::dist()}} version). Afterwards, it uses the estimate to
calculate the corresponding true DTW distance between \emph{only} the nearest neighbors of each series
in \code{x} found in \code{y}, and it continues iteratively until no changes in the nearest neighbors
occur.

If only \code{x} is provided, the distance matrix is calculated between all its time series,
effectively returning a matrix filled with the LB_Improved values.

This could be useful in case one is interested in only the nearest neighbor of one or more series
within a dataset.

The windowing constraint uses a centered window. The calculations expect a value in
\code{window.size} that represents the distance between the point considered and one of the edges
of the window. Therefore, if, for example, \code{window.size = 10}, the warping for an
observation \eqn{x_i} considers the points between \eqn{x_{i-10}} and \eqn{x_{i+10}}, resulting
in \code{10(2) + 1 = 21} observations falling within the window.
}
\note{
This function uses a lower bound that is only defined for time series of equal length.

The \code{\link[proxy:dist]{proxy::dist()}} version simply calls this function.

A considerably large dataset is probably necessary before this is faster than using \code{\link[=dtw_basic]{dtw_basic()}}
with \code{\link[proxy:dist]{proxy::dist()}}. Also note that \code{\link[=lb_improved]{lb_improved()}} calculates warping envelopes for the series
in \code{y}, so be careful with the provided order and \code{nn.margin} (see examples).
}
\section{Parallel Computing}{


Please note that running tasks in parallel does \strong{not} guarantee faster computations. The
overhead introduced is sometimes too large, and it's better to run tasks sequentially.

This function uses the \code{\link[RcppParallel:RcppParallel-package]{RcppParallel}} package
for parallelization. It uses all available threads by default (see
\code{\link[RcppParallel:defaultNumThreads]{RcppParallel::defaultNumThreads()}}), but this can
be changed by the user with
\code{\link[RcppParallel:setThreadOptions]{RcppParallel::setThreadOptions()}}.

An exception to the above is when this function is called within a
\code{\link[foreach:foreach]{foreach}} parallel loop \strong{made by dtwclust}. If the parallel
workers do not have the number of threads explicitly specified, this function will default to 1
thread per worker. See the parallelization vignette for more information
(\code{browseVignettes("dtwclust")}).
}

\examples{

# Load data
data(uciCT)

# Reinterpolate to same length
data <- reinterpolate(CharTraj, new.length = max(lengths(CharTraj)))

# Calculate the DTW distance between a certain subset aided with the lower bound
system.time(d <- dtw_lb(data[1:5], data[6:50], window.size = 20L))

# Nearest neighbors
NN1 <- apply(d, 1L, which.min)

# Calculate the DTW distances between all elements (slower)
system.time(d2 <- proxy::dist(data[1:5], data[6:50], method = "DTW",
                              window.type = "sakoechiba", window.size = 20L))

# Nearest neighbors
NN2 <- apply(d2, 1L, which.min)

# Calculate the DTW distances between all elements using dtw_basic
# (might be faster, see notes)
system.time(d3 <- proxy::dist(data[1:5], data[6:50], method = "DTW_BASIC",
                              window.size = 20L))

# Nearest neighbors
NN3 <- apply(d3, 1L, which.min)

# Change order and margin for nearest neighbor search
# (usually fastest, see notes)
system.time(d4 <- dtw_lb(data[6:50], data[1:5],
                         window.size = 20L, nn.margin = 2L))

# Nearest neighbors *column-wise*
NN4 <- apply(d4, 2L, which.min)

# Same results?
identical(NN1, NN2)
identical(NN1, NN3)
identical(NN1, NN4)

}
\references{
Lemire D (2009). ``Faster retrieval with a two-pass dynamic-time-warping lower bound .'' \emph{Pattern
Recognition}, \strong{42}(9), pp. 2169 - 2180. ISSN 0031-3203,
\doi{10.1016/j.patcog.2008.11.030},
\url{https://www.sciencedirect.com/science/article/pii/S0031320308004925}.
}
\seealso{
\code{\link[=lb_keogh]{lb_keogh()}}, \code{\link[=lb_improved]{lb_improved()}}
}
\author{
Alexis Sarda-Espinosa
}
