% 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]{proxy::dist()}} is custom (\code{loop = FALSE} in \link[proxy:registry]{proxy::pr_DB}).
The custom function handles multi-threaded parallelization directly with \link[RcppParallel:RcppParallel-package]{RcppParallel}.
It uses all available threads by default (see \code{\link[RcppParallel:setThreadOptions]{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}.
}
