Block Term Decomposition
A block term decomposition (BTD) with r blocks writes
\[\hat A = \sum_{i=1}^r A_i,\]
where each block $A_i$ is represented as a Tucker decomposition. At present, only homogeneous BTDs are supported, that is, all blocks must have the same multilinear rank.
To compute a block term decomposition of A with 10 blocks, each of multilinear rank (5, 4, 3), use
julia> r = 10
julia> mlrank = (5, 4, 3)
julia> btd_res = btd(A, r, mlrank)
BTDResult{Float64}
Blocks: 10
Rel. error: 0.2551559591470521The blocks of btd_res can be obtained as follows:
blocks = blocks(btd_res)Each block is represented as a Tucker decomposition, so we can access its core and factor matrices via:
blk = blocks[1]
core(blk)
factors(blk)BTD Docs
TensorKitchen.btd — Function
btd(A, blocks, ranks; kwargs...) returns a BTDResultComputes a block-term decomposition of A with blocks Tucker blocks, each with multilinear rank ranks. The solver first finds an initial point, then refines it. Returns a BTDResult.
Main Options
init = :auto: Sets the algorithm to find the initial point. Possible options are::auto: Uses a default BTD initializer. Forsolver = :als, this usesBTDHOSVDMultistartInit; otherwise, it uses an ALS warm start.:alswarm: Runs ALS first and uses the result as the initial point for manifold solver refinement.- custom initializer objects, e.g.
BTDHOSVDMultistartInit(...).
solver = :rgd: Sets the algorithm for refinement. Possible options are::rgd(default): Riemannian gradient descent.:als: Alternating least squares.:rcg: Riemannian conjugate gradient.:lbfgs: Limited-memory quasi-Newton refinement.
Extended Options
init_point = nothing: Explicit initial point. If provided, it overrides the default initial point.warm_init = BTDHOSVDMultistartInit(...): Searches for initial points using HOSVD for :alswarm, optionally screens them with short ALS runs, and returns the lowest-cost candidate.warm_steps = 200: Once finding the best initial point, it runs this many ALS iterations to refine the initial point.warm_block_method = :hooior:sthosvd: Block update method used during warm start.warm_block_maxiter = 20: Maximum number of inner iterations for each block update during warm start.warm_rel_error_gate = 5e-2: Skips manifold refinement if the warm-start error is above this threshold.maxiter = 500: Maximum number of Riemannian gradient descent iterations.stepsize = 0.01: Initial step size for line search in Riemannian gradient descent.tol = 1e-6: Convergence tolerance.gradient_mode = :riemannian: rgrad can be directly applied for manifold solvers.- If the model has a direct rgrad, it uses that.
- Otherwise it computes egrad and projects it to the tangent space.
- This behavior is in src/solvers/abstract.jl (line 289).
verbose = true: Enables progress output.block_method = :hooior:sthosvd: Block update method used for manifold solvers.block_maxiter = 30: Maximum number of inner block-update iterations for manifold solvers.btd_als_polish_maxiter = nothing: Number of final ALS polishing iterations. Ifnothing, an automatic budget is selected.These settings are a robustness/quality feature for BTD-ALS. They are not used for manifold solvers.
max_stagnation_restarts = 1: More retries after a bad stagnated ALS pass. Higher values can improve solution quality, but increases runtime.stagnation_rel_error = 1e-4: This is a “bad final error” cutoff, not an improvement threshold. Lower value means restarts trigger more easily.restart_candidates = 24: It usually improves chance of finding a better basin, but cost grows roughly linearly.restart_screening_steps = 5: It uses this many quick ALS steps to screen restart candidates.restart_block_maxiter = 20: Inner block-update limit during restart screening for BTD-ALS.restart_seed = nothing: Optional random seed for restart generation for BTD-ALS.
Example
julia> using Random
julia> Random.seed!(0)
julia> A = randn(20, 15, 10); blocks = 10; ranks = (5, 4, 3)
julia> res = btd(A, blocks, ranks; verbose = false)
BTDResult{Float64}
Blocks: 10
Rel. error: 0.2625821087015455TensorKitchen.BTDResult — Type
BTDResult{T}Result of block-term decomposition (btd); block components expose Tucker structure through accessors like core(blk), factors(blk), and blk.tensor.
solver_info: solver-specific diagnostics/metadata (NamedTuple). Typical keys include BTD-ALS restart diagnostics (total_iterations,stagnation_restarts,restart_rel_error_history) and BTD-TSD run settings (schedule,block_repeats,block_count,stepsize).
TensorKitchen.blocks — Function
blocks(r::BTDResult)Return the Tucker block components of a block-term decomposition result.
TensorKitchen.reconstruct — Method
reconstruct(res::BTDResult)Reconstruct the dense tensor represented by a block-term decomposition result by summing the reconstructed Tucker blocks.