Problem & API
Problem Definition
Use TVProblem to define a denoising/reconstruction task:
problem = TotalVariationImageFiltering.TVProblem(
f;
lambda,
spacing = nothing,
data_fidelity = TotalVariationImageFiltering.L2Fidelity(),
tv_mode = TotalVariationImageFiltering.IsotropicTV(),
boundary = TotalVariationImageFiltering.Neumann(),
constraint = TotalVariationImageFiltering.NoConstraint(),
)Key inputs:
f:AbstractArray{<:AbstractFloat,N}data.lambda: TV weight (>= 0).spacing:nothing, scalar,NTuple{N}, or length-Nvector.data_fidelity:L2Fidelity()orPoissonFidelity().tv_mode:IsotropicTV()orAnisotropicTV().boundary: currentlyNeumann().constraint:NoConstraint(),NonnegativeConstraint(), orBoxConstraint(lower, upper).
TVProblem is immutable, but it stores f by reference. For repeated solves with the same shape/eltype, update f in place (for example copyto!) and reuse the same TVProblem.
Solving a Single Input
Allocate output internally:
u, stats = TotalVariationImageFiltering.solve(problem, TotalVariationImageFiltering.ROFConfig())Or in place:
u = copy(problem.f)
stats = TotalVariationImageFiltering.solve!(u, problem, TotalVariationImageFiltering.ROFConfig())stats is:
TotalVariationImageFiltering.SolverStats(iterations, converged, rel_change)Supported solvers:
ROFConfig(ROF model withL2Fidelity).PDHGConfig(L2FidelityandPoissonFidelity, with optional primal constraints).
ROFConfig currently supports only constraint = NoConstraint().
Warm Starts and State Reuse
For repeated solves, pass reusable workspace:
state = TotalVariationImageFiltering.ROFState(problem.f) # or PDHGState(problem.f)
u = copy(problem.f)
stats = TotalVariationImageFiltering.solve!(u, problem, TotalVariationImageFiltering.ROFConfig(); state = state)Behavior:
- For
PDHGConfig,uprovides primal warm start. - For
ROFConfig,state.pis the effective warm start;uis copied into the solver buffer and mainly affects the first relative-change check. state.p(dual variable) is retained across calls.- State shape/eltype must match the solve buffer.
Batch API
For arrays shaped (spatial..., batch):
u_batch, stats = TotalVariationImageFiltering.solve_batch(
f_batch,
TotalVariationImageFiltering.PDHGConfig();
lambda = 0.1,
data_fidelity = TotalVariationImageFiltering.L2Fidelity(),
constraint = TotalVariationImageFiltering.BoxConstraint(0.0, 1.0),
)TV operators act on spatial axes only; the last axis is batch index.
The batch stats aggregate per-sample results:
iterations: max iterations across samples.converged: true only if all samples converged.rel_change: max relative change across samples.