61 const real aMaxCondition,
73 const uint tNumGradients = tNumCoefficients - 1 ;
74 const real tWeightSum = aGram( 0, 0 );
77 "recovery Gram matrix must be square with at least two coefficients" );
78 BELFEM_ASSERT( tWeightSum > 0.0,
"recovery Gram matrix with patch weight %g", tWeightSum );
79 BELFEM_ASSERT( aMaxCondition > 0.0,
"recovery truncation limit must be positive, is %g", aMaxCondition );
81 && aCoupling.
length() == tNumGradients && aSchurCoupling.
length() == tNumGradients
82 && aInverse.
n_rows() == tNumCoefficients && aInverse.
n_cols() == tNumCoefficients,
83 "recovery_block_inverse: scratch not sized for %u coefficients", tNumCoefficients );
85 for (
uint r=0; r<tNumGradients; ++r )
87 aCoupling( r ) = aGram( 0, r+1 ) / tWeightSum ;
89 for (
uint c=0; c<tNumGradients; ++c )
91 for (
uint r=0; r<tNumGradients; ++r )
93 aSchur( r, c ) = aGram( r+1, c+1 ) - aGram( r+1, 0 ) * aCoupling( c );
99 gesvd( aSchur, aSvdS, aSvdU, aSvdVT, aSvdWork );
104 for (
uint r=0; r<tNumGradients; ++r )
106 tScale = std::max( tScale, std::abs( aGram( r+1, r+1 ) ) );
108 const real tCut = std::max( aSvdS( 0 ) / aMaxCondition,
109 64.0 * std::numeric_limits< real >::epsilon() * tScale );
111 aCondition = aSvdS( tNumGradients - 1 ) > 0.0 ?
114 bool tTruncated = false ;
116 aInverse.
fill( 0.0 );
117 for (
uint j=0; j<tNumGradients; ++j )
119 if ( aSvdS( j ) <= tCut )
124 for (
uint c=0; c<tNumGradients; ++c )
126 for (
uint r=0; r<tNumGradients; ++r )
128 aInverse( r+1, c+1 ) += aSvdVT( j, r ) * aSvdU( c, j ) / aSvdS( j );
133 for (
uint r=0; r<tNumGradients; ++r )
135 aSchurCoupling( r ) = 0.0 ;
136 for (
uint c=0; c<tNumGradients; ++c )
138 aSchurCoupling( r ) += aInverse( r+1, c+1 ) * aCoupling( c );
141 aInverse( 0, 0 ) = 1.0 / tWeightSum +
dot( aCoupling, aSchurCoupling );
142 for (
uint r=0; r<tNumGradients; ++r )
144 aInverse( 0, r+1 ) = -aSchurCoupling( r );
145 aInverse( r+1, 0 ) = -aSchurCoupling( r );
auto dot(const Vector< T > &aA, const Vector< T > &aB) -> decltype(arma::dot(aA.vector_data(), aB.vector_data()))
Scalar product of two vectors.
Definition fn_AR_dot.hpp:24
bool recovery_block_inverse(const Matrix< real > &aGram, const real aMaxCondition, Matrix< real > &aInverse, real &aCondition, Matrix< real > &aSchur, Vector< real > &aCoupling, Vector< real > &aSchurCoupling, Matrix< real > &aSvdU, Matrix< real > &aSvdVT, Vector< real > &aSvdS, Vector< real > &aSvdWork)
Inverse of the Gram matrix of a patch-recovery fit whose basis is one in slot 0 at the node ( postpro...
Definition fn_FEM_recovery_inverse.hpp:59
int_t gesvd(Matrix< T > &A, Vector< lapack::real_t< T > > &S, Matrix< T > &U, Matrix< T > &VT, Vector< lapack::real_t< T > > &Work, const char jobu='A', const char jobvt='A', const bool AbortOnError=true)
singular value decomposition A = U * diag( S ) * VT via LAPACK ?gesvd
Definition fn_gesvd.hpp:340