% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/bpc.R
\name{bpc}
\alias{bpc}
\title{Basis Profile Curve (\verb{BPC}) identification}
\usage{
bpc(
  x,
  groups,
  time = NULL,
  time_window = NULL,
  n_bpc = NULL,
  initial_rank = NULL,
  zeta_threshold = 1,
  null_class = TRUE,
  nmf_max_iters = 10000,
  nmf_tol = c(1e-04, 1e-08),
  verbose = TRUE
)
}
\arguments{
\item{x}{numeric matrix of single-trial evoked voltages with shape
\code{time x trials} (rows are timepoints, columns are trials). All trials
across all stimulation groups are stacked column-wise.}

\item{groups}{vector of length \code{ncol(x)} (integer, character or factor)
giving the stimulation subgroup of each column of \code{x}. At least two
subgroups are required and each subgroup needs at least two trials.}

\item{time}{optional numeric vector of length \code{nrow(x)} giving the
stimulus-aligned time (in seconds) of each row of \code{x}. Only used to crop
to \code{time_window} and as the plotting axis; the method itself does not
require it.}

\item{time_window}{optional numeric \code{c(lo, hi)} analysis window (seconds);
requires \code{time}. An \code{NA} extends to the corresponding data edge.
\code{NULL} (the default) uses all rows.}

\item{n_bpc}{integer or \code{NULL}; if given, fixes the number of basis
curves and skips automatic rank selection.}

\item{initial_rank}{integer or \code{NULL}; the starting \verb{NMF} rank for
automatic selection. \code{NULL} uses \code{min(n - 1L, 10L)} where \eqn{n} is
the number of subgroups.}

\item{zeta_threshold}{numeric \eqn{> 0}; rank-selection cutoff on \eqn{\zeta}
(see \sQuote{Details}); smaller values give fewer curves. Defaults to \code{1},
matching the \verb{BPC} reference.}

\item{null_class}{logical; if \code{TRUE} (the default) subgroups whose
winner-take-all loading falls below \eqn{1/(2\sqrt{n})} are left unassigned
(\code{NA}); if \code{FALSE} every subgroup is forced into a curve.}

\item{nmf_max_iters, nmf_tol}{passed to \code{\link{naive_nmf}}.}

\item{verbose}{logical; whether to report progress.}
}
\value{
A named list of class \code{ravetools_bpc}:
\describe{
\item{\code{curves}}{Numeric matrix, time \eqn{\times} number of \verb{BPCs};
  column \eqn{q} is the basis profile curve \eqn{B_q(t)}, the first
  linear-kernel \verb{PCA} component of its member trials (unit-norm,
  sign-oriented to a positive mean projection).}
\item{\code{time}}{Numeric vector, the (windowed) time axis for \code{curves};
  the sample index when \code{time} was not supplied.}
\item{\code{group_labels}}{The unique stimulation subgroup labels, in the order
  used by \code{clusters} and \code{xi}.}
\item{\code{clusters}}{Integer vector, the \verb{BPC} index assigned to each
  subgroup; \code{NA} for subgroups left in the null class.}
\item{\code{excluded_groups}}{The labels of subgroups not represented by any
  \verb{BPC}.}
\item{\code{weights}}{A \code{data.frame} with one row per (\verb{BPC},
  subgroup) membership: \code{bpc}, \code{group}, \code{n_trials},
  \code{weight} (mean residual-normalized \eqn{\alpha}) and \code{p_value}.}
\item{\code{alpha}}{Numeric matrix, trials \eqn{\times} number of \verb{BPCs};
  the per-trial projection \eqn{\alpha} of every trial onto each basis curve.}
\item{\code{xi}}{Numeric matrix, the \eqn{n \times n} significance matrix
  \eqn{\Xi}.}
\item{\code{nmf}}{The \code{\link{naive_nmf}} result for the selected rank, with
  \code{H} (raw loadings) and \code{H0} (winner-take-all, thresholded).}
\item{\code{n_bpc}}{Integer, the number of basis curves found.}
\item{\code{time_window}}{The effective analysis window used (or \code{NULL}).}
}
}
\description{
Identifies a small set of canonical temporal response shapes - \emph{basis
profile curves} (\verb{BPCs}) - from the single-trial stimulation-evoked
responses recorded at one measurement electrode, where the trials are grouped
by stimulation site (or any other condition). Each stimulation group is
assigned to the \verb{BPC} that best explains its trials, and the projection
strength of every group is quantified. This is the across-stimulation-site
\verb{BPC} method (see \sQuote{References}); the related
\code{\link{crp_cluster}} applies the same idea across electrodes.
}
\details{
Let \eqn{V} be the (windowed) \eqn{T \times K} matrix of all single trials and
let \code{groups} map each of the \eqn{K} columns to one of \eqn{n} stimulation
subgroups.
\enumerate{
\item \strong{Window.} When \code{time} and \code{time_window} are supplied the
  rows of \code{x} are cropped to that window; otherwise all rows are used.
  Rows with non-finite values are dropped.
\item \strong{Internal projections.} Each trial is \eqn{L_2}-normalized into
  \eqn{V_0}, and \eqn{P = V_0^\top V} collects the projection of every native
  trial onto every normalized trial.
\item \strong{Significance matrix.} For each ordered pair of subgroups
  \eqn{(k, l)} the set of relevant entries of \eqn{P} is gathered (the
  off-diagonal of the within-group block when \eqn{k = l}, the whole cross
  block otherwise) and reduced to a one-sample t-statistic versus zero. These
  form the \eqn{n \times n} significance matrix \eqn{\Xi}.
\item \strong{Rank selection.} \eqn{\Xi} is made non-negative and rescaled, then
  factorized with \code{\link{naive_nmf}} at decreasing inner rank while the
  degeneracy score \eqn{\zeta} - the sum of the upper off-diagonal of the
  row-normalized \eqn{HH^\top} - exceeds \code{zeta_threshold}.
\item \strong{Assignment.} Each subgroup takes its winner-take-all \verb{BPC}
  over the normalized \verb{NMF} loadings; with \code{null_class}, loadings
  below \eqn{1/(2\sqrt{n})} are left unassigned (the \dQuote{null} class).
\item \strong{Basis curves.} Per \verb{BPC}, the first linear-kernel \verb{PCA}
  component of all trials in its member subgroups, sign-oriented to a positive
  mean projection.
\item \strong{Weights.} For each member subgroup the per-trial coefficient
  \eqn{\alpha} (projection onto the basis curve) is normalized by the residual
  magnitude; the mean is the projection weight and a one-sample t-test gives a
  significance value.
}
}
\examples{
# Three response shapes, several stimulation groups per shape.
\donttest{
set.seed(1)
n_time <- 300L
tt <- seq(-0.2, 1, length.out = n_time)
shapes <- list(
  exp(-((tt - 0.08) / 0.03)^2) - 0.5 * exp(-((tt - 0.18) / 0.04)^2),
  exp(-((tt - 0.38) / 0.03)^2) - 0.5 * exp(-((tt - 0.50) / 0.04)^2),
  exp(-((tt - 0.70) / 0.04)^2)
)

# 3 stimulation groups per shape, 12 trials each
V <- NULL
groups <- NULL
g <- 0L
for (s in seq_along(shapes)) {
  for (rep in seq_len(3L)) {
    g <- g + 1L
    trials <- outer(shapes[[s]], runif(12L, 0.5, 1.5)) +
      matrix(rnorm(n_time * 12L, sd = 0.2), n_time, 12L)
    V <- cbind(V, trials)
    groups <- c(groups, rep(g, 12L))
  }
}

res <- bpc(V, groups, time = tt, time_window = c(0, 1), verbose = TRUE)
res$n_bpc
res$clusters
plot(res)
}

}
\references{
The \verb{BPC} method is described in \doi{10.1371/journal.pcbi.1008710}, with
a reference Python implementation at
\url{https://github.com/MultimodalNeuroimagingLab/bpc_jupyter}.
}
\seealso{
\code{\link{crp}}, \code{\link{crp_cluster}}, \code{\link{naive_nmf}}
}
