MADNESS 0.10.1
madness::LowRankFunctionFactory< T, NDIM, LDIM > Class Template Reference

#include <lowrankfunction.h>

Collaboration diagram for madness::LowRankFunctionFactory< T, NDIM, LDIM >:

Classes

struct  ProjectionState
struct  ThreshGuard
 RAII guard for temporarily changing FunctionDefaults and functor thresh. More...
struct  YFormationResult

Public Member Functions

 LowRankFunctionFactory ()=default
 LowRankFunctionFactory (const LowRankFunctionFactory &other)=default
 LowRankFunctionFactory (const LowRankFunctionParameters param, const Molecule &molecule)
 LowRankFunctionFactory (const LowRankFunctionParameters param, const std::vector< Vector< double, LDIM > > origins={})
std::vector< Vector< double, LDIM > > build_grid (double ve, long max_points=0) const
 Build a grid around the given origins (or uniform random if no origins).
std::string diagnose_error (double error, double prev_error, long rank, double tol, double thresh, const Tensor< T > &ovlp_h) const
std::vector< Function< T, LDIM > > form_Y (const LRFunctorBase< T, NDIM > &lrfunctor, const std::vector< Vector< double, LDIM > > &grid, const LowRankFunctionParameters &params) const
 Form Y basis from grid, with fallback to loose significance threshold.
LowRankFunction< T, NDIM > project (const LRFunctorBase< T, NDIM > &lrfunctor, const double target_l2error=FunctionDefaults< NDIM >::get_thresh(), const int max_iter=5) const
LowRankFunction< T, NDIM > project_from_operator (const LRFunctorF12< T, NDIM > &functor, const double target_error=FunctionDefaults< NDIM >::get_thresh(), const int max_taylor_order=15) const
LowRankFunction< T, NDIM > project_from_Y_stable (const LRFunctorBase< T, NDIM > &lrfunctor, const std::vector< Function< T, LDIM > > &Y, const double tol) const
ProjectionState project_stable (const LRFunctorBase< T, NDIM > &lrfunctor, const std::vector< Function< T, LDIM > > &Y, const double tol, const ProjectionState &prev) const
LowRankFunctionFactory & set_adaptive_coarse_factor (const double factor)
LowRankFunctionFactory & set_adaptive_max_centers (const int max_centers)
LowRankFunctionFactory & set_adaptive_min_centers (const int min_centers)
LowRankFunctionFactory & set_adaptive_refine_radius (const double ratio)
LowRankFunctionFactory & set_adaptive_significance_ratio (const double ratio)
LowRankFunctionFactory & set_centers (const std::vector< Vector< double, LDIM > > centers)
LowRankFunctionFactory & set_gridtype (const std::string &gridtype)
LowRankFunctionFactory & set_radius (const double radius)
LowRankFunctionFactory & set_rank_revealing_tol (const double rrtol)
LowRankFunctionFactory & set_volume_element (const double volume_element)
YFormationResult Yformer (const LRFunctorBase< T, NDIM > &lrfunctor1, const std::vector< Vector< double, LDIM > > &grid, const LowRankFunctionParameters &parameters, const double exponent=30.0, const double significance_tol=-1.0) const

Static Public Member Functions

static std::vector< Function< T, LDIM > > harmonic_basis (World &world, const std::vector< double > zeta_range, const int lmax, const std::vector< Vector< double, LDIM > > centers)
 return a set of solid harmonic functions up to lmax with a zeta range on the given (atomic) centers

Public Attributes

std::vector< Vector< double, LDIM > > origins
 origins of the molecular grid
const particle< LDIM > p1 =particle<LDIM>::particle1()
const particle< LDIM > p2 =particle<LDIM>::particle2()
LowRankFunctionParameters parameters

Private Member Functions

std::vector< Function< T, LDIM > > build_taylor_y (const LRFunctorF12< T, NDIM > &functor, const int max_order, const double coeff_cutoff) const
std::vector< Vector< double, LDIM > > make_uniform_random_grid_in_cell (const double volume_element) const

Static Private Member Functions

static std::vector< std::array< int, LDIM > > generate_multi_indices (int max_order)
 Generate all multi-indices k = (k_1, ..., k_LDIM) with total degree |k| <= max_order.

Detailed Description

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
class madness::LowRankFunctionFactory< T, NDIM, LDIM >

Factory class to compute a low-rank approximation of a given hi-dimensional function f(r1,r2) using randomized projection and rank-revealing Cholesky decomposition (RRCD).

The approximation takes the canonical form f(r1,r2) ≈ Σ_i g_i(r1) h_i(r2) where h are orthonormalized backprojected functions and g their reprojections.

Error analysis

The L2 error ||f - f_approx|| has three independent sources that add in quadrature:

ε_total² ≈ ε_sampling² + ε_truncation² + ε_conditioning²

1. Sampling error (grid coverage)

The grid probes f's column space via localized Gaussians. If the grid misses regions where f has significant weight, those contributions cannot be represented. Controlled by: volume_element (ve), radius, center placement.

Heuristic: for well-localized functions (Gaussians on atomic centers), ve ≈ 0.1 with radius ≈ 2-3 suffices for errors down to ~1e-3. Finer grids increase Y-formation cost linearly (O(grid_size) functor applications) but the rank saturates quickly — most extra grid points are linearly dependent.

2. Truncation error (rank reduction)

The RRCD with tolerance tol discards Y components with overlap eigenvalues < tol. For Gaussian kernels the eigenvalues decay rapidly, giving truncation error that scales roughly as tol^(0.3-0.5) (empirically). Setting tol = ε² gives truncation error ~ ε.

3. Conditioning (eliminated by power-iteration algorithm)

The current algorithm orthonormalizes h = f·Y (not Y), so the overlap <h|h> has eigenvalues weighted by σ_k² (singular values of f). Rank reduction on <h|h> is always well-conditioned — no half-metric or full-metric amplification. The result is canonical by construction (no coupling metric), and conditioning is not an error source.

Parameter heuristics for a target error ε

tol = ε² (truncation error ~ √tol ~ ε) ve ~ C · ε^(2/LDIM) with C = 2/1/0.5 for LDIM=1/2/3

Algorithm (project())

  1. Build grid around origins (Gaussian-distributed, σ² = 0.5·radius)
  2. Form Y basis: multi-scale Gaussian RHS at grid points
  3. Power-iteration projection: Y → h_raw → rr_cholesky(<h|h>) → h_ortho → g
  4. Tol sweep: incrementally tighten rr_cholesky tolerance, reuse cached <h|h>
  5. If grid-limited: halve ve, rebuild Y, re-project from scratch
  6. If thresh-limited: tighten MRA thresh, rebuild Y, re-project
  7. L2 error via Pythagoras: ||f||² − Σ||g_k||² (no functor applications)

The project() method automates parameter selection from a single target L2 error.

Constructor & Destructor Documentation

◆ LowRankFunctionFactory() [1/4]

◆ LowRankFunctionFactory() [2/4]

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
madness::LowRankFunctionFactory< T, NDIM, LDIM >::LowRankFunctionFactory ( const LowRankFunctionParameters param,
const std::vector< Vector< double, LDIM > > origins = {} )
inline

References origins, and param.

◆ LowRankFunctionFactory() [3/4]

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
madness::LowRankFunctionFactory< T, NDIM, LDIM >::LowRankFunctionFactory ( const LowRankFunctionParameters param,
const Molecule & molecule )
inline

◆ LowRankFunctionFactory() [4/4]

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
madness::LowRankFunctionFactory< T, NDIM, LDIM >::LowRankFunctionFactory ( const LowRankFunctionFactory< T, NDIM, LDIM > & other)
default

Member Function Documentation

◆ build_grid()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::vector< Vector< double, LDIM > > madness::LowRankFunctionFactory< T, NDIM, LDIM >::build_grid ( double ve,
long max_points = 0 ) const
inline

Build a grid around the given origins (or uniform random if no origins).

References madness::molecular_grid< NDIM >::get_grid(), madness::grid(), make_uniform_random_grid_in_cell(), origins, and parameters.

Referenced by project().

◆ build_taylor_y()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::vector< Function< T, LDIM > > madness::LowRankFunctionFactory< T, NDIM, LDIM >::build_taylor_y ( const LRFunctorF12< T, NDIM > & functor,
const int max_order,
const double coeff_cutoff ) const
inlineprivate

Build a Taylor-expansion-based Y basis spanning the range of an F12 operator.

For each Gaussian term c_m exp(-alpha_m r^2) in the operator's GFit expansion and each multi-index k with |k| <= max_order, emits phi_{m,k}(r) = r^k * exp(-alpha_m |r|^2) when the Taylor coefficient |c_m * prod_d (2 alpha_m)^{k_d}/k_d!| exceeds coeff_cutoff. These monomial-Gaussians probe the operator's range analytically rather than by random sampling.

References std::abs(), d, madness::BaseTensor::dim(), fit(), generate_multi_indices(), madness::LRFunctorF12< T, NDIM, LDIM >::get_f12(), madness::inner(), m, p(), print(), madness::BaseTensor::size(), madness::FunctionFactory< T, NDIM >::special_points(), and madness::LRFunctorF12< T, NDIM, LDIM >::world().

Referenced by project_from_operator().

◆ diagnose_error()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::string madness::LowRankFunctionFactory< T, NDIM, LDIM >::diagnose_error ( double error,
double prev_error,
long rank,
double tol,
double thresh,
const Tensor< T > & ovlp_h ) const
inline

Diagnose the dominant error source. With the stable (canonical) algorithm, conditioning is not an issue. Thresh-limited only if:

  • the last tol-tightening did not improve the error by at least 20% (error >= 0.8 * prev_error), AND
  • sqrt(rank) * thresh > 0.3 * error (realistic noise combination), AND
  • tol is at the floor (~1e-14), i.e. tol-tightening has no more room. The sqrt(rank) factor replaces the worst-case rank factor: for canonical form with uncorrelated truncation noise, combined error scales like sqrt(rank) * thresh, not rank * thresh. The rank-linear bound triggers spuriously at moderate rank. The tol-floor guard prevents switching to expensive thresh work when grid augmentation hasn't been tried yet. Tol-limited: tol probe on ovlp_h shows rank increase (preferred when available). Grid-limited: neither of the above — try more grid points.

References copy(), madness::error(), madness::FunctionDefaults< NDIM >::thresh, print(), madness::rr_cholesky(), and madness::BaseTensor::size().

Referenced by project().

◆ form_Y()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::vector< Function< T, LDIM > > madness::LowRankFunctionFactory< T, NDIM, LDIM >::form_Y ( const LRFunctorBase< T, NDIM > & lrfunctor,
const std::vector< Vector< double, LDIM > > & grid,
const LowRankFunctionParameters & params ) const
inline

Form Y basis from grid, with fallback to loose significance threshold.

References madness::grid(), and Yformer().

Referenced by project().

◆ generate_multi_indices()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::vector< std::array< int, LDIM > > madness::LowRankFunctionFactory< T, NDIM, LDIM >::generate_multi_indices ( int max_order)
inlinestaticprivate

Generate all multi-indices k = (k_1, ..., k_LDIM) with total degree |k| <= max_order.

References madness::FunctionDefaults< NDIM >::k.

Referenced by build_taylor_y().

◆ harmonic_basis()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::vector< Function< T, LDIM > > madness::LowRankFunctionFactory< T, NDIM, LDIM >::harmonic_basis ( World & world,
const std::vector< double > zeta_range,
const int lmax,
const std::vector< Vector< double, LDIM > > centers )
inlinestatic

return a set of solid harmonic functions up to lmax with a zeta range on the given (atomic) centers

Parameters
[in]World
[in]zeta_rangerange of the Gaussian exponent zeta, given as {zeta_min, zeta_max, zeta_step} for even-tempered progression
[in]lmaxmaximum angular momentum of the solid harmonics
[in]centersthe centers of the solid harmonics, typically the atomic positions

References d, madness::f, madness::FunctionFactory< T, NDIM >::functor(), madness::inner(), print(), and zeta.

Referenced by Yformer().

◆ make_uniform_random_grid_in_cell()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::vector< Vector< double, LDIM > > madness::LowRankFunctionFactory< T, NDIM, LDIM >::make_uniform_random_grid_in_cell ( const double volume_element) const
inlineprivate

◆ project()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunction< T, NDIM > madness::LowRankFunctionFactory< T, NDIM, LDIM >::project ( const LRFunctorBase< T, NDIM > & lrfunctor,
const double target_l2error = FunctionDefaults<NDIM>::get_thresh(),
const int max_iter = 5 ) const
inline

Adaptively project a high-dimensional functor to a low-rank representation.

Uses the numerically stable power-iteration algorithm: Y → h = f·Y → orthonormalize h → g = f·h_ortho → canonical LRF

Single refinement loop with three actions:

  • tol-limited: tighten tol on <h|h>, incrementally extend h_ortho and g
  • grid-limited: halve ve and re-project from scratch (denser Y sampling)
  • thresh-limited: tighten MRA thresh, reform everything
  • tol-degraded: revert to best state, route to thresh or grid
Parameters
[in]lrfunctorthe high-dimensional functor to approximate
[in]target_l2errorthe desired L2 error (default: FunctionDefaults thresh)
[in]max_itermaximum refinement iterations (default: 5)
Returns
canonical low-rank approximation

References madness::WorldGopInterface::broadcast_serializable(), build_grid(), diagnose_error(), madness::timer::do_print, form_Y(), madness::FunctionDefaults< NDIM >::get_thresh(), madness::World::gop, madness::grid(), MADNESS_CHECK_THROW, matrix_inner(), parameters, print(), project_stable(), madness::World::rank(), madness::QCCalculationParametersBase::set_derived_value(), madness::timer::tag(), and madness::LRFunctorBase< T, NDIM, LDIM >::world().

Referenced by madness::ExchangeCommutator::apply_KffK_lowrank_three_range(), madness::ExchangeCommutator::compute_lrf_exchange_operator(), test_adaptive_grid_projection(), test_arithmetic(), test_inner(), test_lowrank_function(), and test_remove_lindep().

◆ project_from_operator()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunction< T, NDIM > madness::LowRankFunctionFactory< T, NDIM, LDIM >::project_from_operator ( const LRFunctorF12< T, NDIM > & functor,
const double target_error = FunctionDefaults<NDIM>::get_thresh(),
const int max_taylor_order = 15 ) const
inline

Construct LRF directly from the Gaussian expansion of an F12 operator.

Instead of random-Y probing, uses the known separable structure: each Gaussian term c_m exp(-alpha_m |r1-r2|^2) is Taylor-expanded via exp(2 alpha_m r1.r2) = sum_k (2 alpha)^|k| r1^k r2^k / k! giving explicit g and h basis functions. After rr_cholesky rank reduction, yields a canonical LRF accurate to the operator's Gaussian fit precision (~1e-8), bypassing the O(1/r^{3/2}) error floor of random probing for Slater-type kernels.

Parameters
[in]functorthe F12 functor with operator and a,b functions
[in]target_errorcontrols coefficient cutoff and rank reduction tol
[in]max_taylor_ordermax total degree of Taylor expansion per Gaussian term
Returns
canonical LowRankFunction

References build_taylor_y(), madness::timer::do_print, madness::FunctionDefaults< NDIM >::get_thresh(), print(), project_stable(), madness::timer::tag(), and madness::LRFunctorF12< T, NDIM, LDIM >::world().

◆ project_from_Y_stable()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunction< T, NDIM > madness::LowRankFunctionFactory< T, NDIM, LDIM >::project_from_Y_stable ( const LRFunctorBase< T, NDIM > & lrfunctor,
const std::vector< Function< T, LDIM > > & Y,
const double tol ) const
inline

Numerically stable projection using power-iteration.

this method orthonormalizes h = f·Y. The overlap <h|h> has eigenvalues weighted by σ_k² (singular values of f), making the rank reduction well-conditioned. The result is canonical by construction (no metric).

Algorithm:

  1. rr_cholesky(<Y|Y>, tol_coarse) → pY (coarse rank reduction)
  2. h_raw = inner(f, pY, p1, p1) (backproject to r2)
  3. rr_cholesky(<h_raw|h_raw>, tol) → ph (well-conditioned rank)
  4. orthonormalize ph → h_ortho (via Cholesky factor)
  5. g = inner(f, h_ortho, p2, p1) (reproject to r1)
  6. return LowRankFunction(g, h_ortho) (canonical)
Parameters
[in]lrfunctorthe functor
[in]Ythe probe basis from Yformer
[in]tolthe target Cholesky tolerance
Returns
canonical LowRankFunction

References madness::timer::do_print, madness::g, madness::FunctionDefaults< NDIM >::get_thresh(), inner(), matrix_inner(), p1, p2, print(), madness::LowRankFunction< T, NDIM, LDIM >::rr_cholesky_matrix_and_reorder(), madness::timer::tag(), transform(), truncate(), and madness::LRFunctorBase< T, NDIM, LDIM >::world().

◆ project_stable()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
ProjectionState madness::LowRankFunctionFactory< T, NDIM, LDIM >::project_stable ( const LRFunctorBase< T, NDIM > & lrfunctor,
const std::vector< Function< T, LDIM > > & Y,
const double tol,
const ProjectionState & prev ) const
inline

◆ set_adaptive_coarse_factor()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_adaptive_coarse_factor ( const double factor)
inline

◆ set_adaptive_max_centers()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_adaptive_max_centers ( const int max_centers)
inline

◆ set_adaptive_min_centers()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_adaptive_min_centers ( const int min_centers)
inline

◆ set_adaptive_refine_radius()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_adaptive_refine_radius ( const double ratio)
inline

◆ set_adaptive_significance_ratio()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_adaptive_significance_ratio ( const double ratio)
inline

◆ set_centers()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_centers ( const std::vector< Vector< double, LDIM > > centers)
inline

◆ set_gridtype()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_gridtype ( const std::string & gridtype)
inline

◆ set_radius()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_radius ( const double radius)
inline

References LowRankFunctionFactory(), and parameters.

Referenced by test_arithmetic(), and test_inner().

◆ set_rank_revealing_tol()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_rank_revealing_tol ( const double rrtol)
inline

References LowRankFunctionFactory(), and parameters.

Referenced by test_arithmetic(), and test_inner().

◆ set_volume_element()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
LowRankFunctionFactory & madness::LowRankFunctionFactory< T, NDIM, LDIM >::set_volume_element ( const double volume_element)
inline

References LowRankFunctionFactory(), and parameters.

Referenced by test_arithmetic(), and test_inner().

◆ Yformer()

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
YFormationResult madness::LowRankFunctionFactory< T, NDIM, LDIM >::Yformer ( const LRFunctorBase< T, NDIM > & lrfunctor1,
const std::vector< Vector< double, LDIM > > & grid,
const LowRankFunctionParameters & parameters,
const double exponent = 30.0,
const double significance_tol = -1.0 ) const
inline

apply a rhs on grid points to the hi-dim function and form Y = A_ij w_j (in Halko's language). The RHS selection (localized Gaussian/exponential vs harmonics) is controlled by the single gridtype parameter: values "random"/"adaptive"/"twostage" use localized Gaussian RHS (the previous "exponential" behavior), whereas "harmonics" uses the RI harmonics-based RHS.

References madness::FunctionFactory< T, NDIM >::functor(), madness::grid(), harmonic_basis(), inner(), madness::inner(), madness::norm2s(), madness::normalize(), omega, origins, p1, p2, parameters, madness::constants::pi, and madness::LRFunctorBase< T, NDIM, LDIM >::world().

Referenced by form_Y().

Member Data Documentation

◆ origins

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
std::vector<Vector<double,LDIM> > madness::LowRankFunctionFactory< T, NDIM, LDIM >::origins

origins of the molecular grid

Referenced by LowRankFunctionFactory(), build_grid(), set_centers(), and Yformer().

◆ p1

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
const particle<LDIM> madness::LowRankFunctionFactory< T, NDIM, LDIM >::p1 =particle<LDIM>::particle1()

◆ p2

template<typename T, std::size_t NDIM, std::size_t LDIM = NDIM/2>
const particle<LDIM> madness::LowRankFunctionFactory< T, NDIM, LDIM >::p2 =particle<LDIM>::particle2()

◆ parameters


The documentation for this class was generated from the following file: