% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/dfspa.R
\name{dfspa}
\alias{dfspa}
\title{Denoised functional Successive Projection Algorithm (d-fSPA)}
\usage{
dfspa(F_hat, K, grid_weights = NULL, N = NULL, Delta = NULL, denoise = TRUE)
}
\arguments{
\item{F_hat}{An \code{m}-by-\code{G} numeric matrix where row \code{i} is the evaluation
of the estimated function \eqn{\hat f^{(i)}} at \code{G} grid points.}

\item{K}{Integer number of basis functions to recover. Must satisfy
\verb{1 <= K <= m} after denoising.}

\item{grid_weights}{Optional length-\code{G} non-negative numeric vector of
grid weights defining the \eqn{L^2(\mu)} inner product. Defaults to
uniform weights \code{1 / G}.}

\item{N, Delta}{Optional numeric tuning parameters controlling denoising.
See Details.}

\item{denoise}{Logical; if \code{FALSE}, the denoising step is skipped and
plain fSPA is run. Defaults to \code{TRUE}.}
}
\value{
An object of class \code{"dfspa"}: a list containing
\describe{
\item{\code{bases}}{A \code{K}-by-\code{G} matrix whose rows are the recovered basis
functions evaluated on the grid (denoised, if applicable).}
\item{\code{selected}}{Length-\code{K} integer vector of the selected row indices
into the post-denoising function matrix.}
\item{\code{original_indices}}{Length-\code{K} integer vector of the selected
study indices in the original input \code{F_hat} (before any rows were
dropped by denoising).}
\item{\code{kept}}{Integer vector of row indices of \code{F_hat} that survived
denoising.}
\item{\code{F_denoised}}{The post-denoising function matrix
(\code{length(kept)}-by-\code{G}).}
\item{\code{grid_weights}}{Grid weights used.}
\item{\code{N}, \code{Delta}}{Tuning parameters actually used (or \code{NA} when
\code{denoise = FALSE}).}
\item{\code{K}}{Number of bases requested.}
\item{\code{call}}{The matched call.}
}
}
\description{
Recovers a set of \code{K} latent basis functions from a collection of
study-level function estimates under the low-rank cross-study heterogeneity
assumption of Shi, Imai, and Zhang. Implements Algorithm 1 of the paper
("The d-fSPA Algorithm for basis hunting").
}
\details{
Each study-level function is represented by its evaluations on a shared
grid of \code{G} points. The (weighted) \eqn{L^2(\mu)} inner product is
\eqn{\langle f,g\rangle = \sum_{j=1}^G w_j f(x_j) g(x_j)}, where the
\code{grid_weights} \code{w_j} are proportional to the measure \eqn{\mu}. If not
supplied, uniform weights \code{1 / G} are used.

Denoising follows Jin (2024): for each study \code{i}, let
\eqn{B_\Delta(\hat f^{(i)}) = \{j : \|\hat f^{(j)} - \hat f^{(i)}\| \le
\Delta\}}. If \eqn{|B_\Delta(\hat f^{(i)})| < N}, study \code{i} is discarded;
otherwise \eqn{\hat f^{(i)}} is replaced by the average of the functions
in \eqn{B_\Delta}.
After denoising, the functional SPA step iteratively selects, at each of
the \code{K} iterations, the remaining function with the largest norm after
projecting out the span of previously selected bases.

Default tuning parameters follow the heuristics of the paper:
\code{N = 0.5 * log(m)} and
\eqn{\Delta = \max_{ij} \|\hat f^{(i)} - \hat f^{(j)}\| / 10}.
}
\examples{
set.seed(1)
G <- 50
x <- seq(0, 1, length.out = G)
basis <- rbind(sin(pi * x), cos(pi * x), x)          # 3 true bases
pi_mat <- rbind(diag(3),                              # 3 pure studies
                c(0.5, 0.3, 0.2),
                c(0.2, 0.5, 0.3),
                c(0.3, 0.3, 0.4))
F_hat <- pi_mat \%*\% basis                             # m = 6, G = 50
fit <- dfspa(F_hat, K = 3, denoise = FALSE)
fit$original_indices    # should be a permutation of 1, 2, 3

}
