% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/DISTANCES-lb-improved.R
\name{lb_improved}
\alias{lb_improved}
\title{Lemire's improved DTW lower bound}
\usage{
lb_improved(
  x,
  y,
  window.size = NULL,
  norm = "L1",
  lower.env = NULL,
  upper.env = NULL,
  force.symmetry = FALSE,
  error.check = TRUE
)
}
\arguments{
\item{x}{A time series (reference).}

\item{y}{A time series with the same length as \code{x} (query).}

\item{window.size}{Window size for envelope calculation. See details.}

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

\item{lower.env}{Optionally, a pre-computed lower envelope for \strong{\code{y}} can be provided (non-proxy
version only). See \code{\link[=compute_envelope]{compute_envelope()}}.}

\item{upper.env}{Optionally, a pre-computed upper envelope for \strong{\code{y}} can be provided (non-proxy
version only). See \code{\link[=compute_envelope]{compute_envelope()}}.}

\item{force.symmetry}{If \code{TRUE}, a second lower bound is calculated by swapping \code{x} and \code{y}, and
whichever result has a \emph{higher} distance value is returned. The proxy version can only work if
a square matrix is obtained, but use carefully.}

\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.}
}
\value{
The improved lower bound for the DTW distance.
}
\description{
This function calculates an improved lower bound (LB) on the Dynamic Time Warp (DTW) distance
between two time series. It uses a Sakoe-Chiba constraint.
}
\details{
The reference time series should go in \code{x}, whereas the query time series should go in \code{y}.

If the envelopes are provided, they should be provided together. If either one is missing, both
will be computed.

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.
}
\section{Proxy version}{


The version registered with \code{\link[proxy]{dist}} is custom (\code{loop = FALSE} in
\code{\link[proxy]{pr_DB}}). The custom function handles multi-threaded parallelization
directly (with \code{\link[RcppParallel:RcppParallel-package]{RcppParallel}}). 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 it 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")}).
}

\section{Note}{


The lower bound is only defined for time series of equal length and is \strong{not} symmetric.

If you wish to calculate the lower bound between several time series, it would be better to use
the version registered with the \code{proxy} package, since it includes some small optimizations. The
convention mentioned above for references and queries still holds. See the examples.

The proxy version of \code{force.symmetry} should only be used when only \code{x} is provided or both \code{x}
and \code{y} are identical. It compares the lower and upper triangular of the resulting distance
matrix and forces symmetry in such a way that the tightest lower bound is obtained.
}

\examples{

# Sample data
data(uciCT)

# Lower bound distance between two series
d.lbi <- lb_improved(CharTraj[[1]], CharTraj[[2]], window.size = 20)

# Corresponding true DTW distance
d.dtw <- dtw(CharTraj[[1]], CharTraj[[2]],
             window.type = "sakoechiba", window.size = 20)$distance

d.lbi <= d.dtw

# Calculating the LB between several time series using the 'proxy' package
# (notice how both argments must be lists)
D.lbi <- proxy::dist(CharTraj[1], CharTraj[2:5], method = "LB_Improved",
                     window.size = 20, norm = "L2")

# Corresponding true DTW distance
D.dtw <- proxy::dist(CharTraj[1], CharTraj[2:5], method = "dtw_basic",
                     norm = "L2", window.size = 20)

D.lbi <= D.dtw

}
\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}.
}
