DMatrix orthonormalize(const matrix_T& mat) { // after the method of Augustin A. Dubrulle: // "An Optimum Iteration for the Matrix Polar Decomposition", Elect. Trans. Num. Anal, 1999 BOOST_ASSERT(mat.size1() == mat.size2()); // std::cout << "fixing " << ublas::prod(mat,ublas::trans(mat)) << " with det " << determinant(mat) << std::flush; DMatrix A = mat; DMatrix W = A; double eps = 1e-15; double limit = (1+eps)*sqrt(mat.size1()); A = inv(ublas::trans(W)); double g = sqrt(norm_frobenius(A)/norm_frobenius(W)); // frobenius norm W = 0.5*(g*W+(1/g)*A); double f = norm_frobenius(W); double pf = DBL_MAX; while ((f > limit) && (f < pf)) { // std::cout << "." << std::flush; pf = f; A = inv(ublas::trans(W)); g = sqrt(norm_frobenius(A)/f); W = 0.5*(g*W+(1/g)*A); f = norm_frobenius(W); } // now, W^T*W=I, i.e. W^T = inv(W) //W /= determinant(W); ?? Necessary?? // std::cout << "to " << ublas::prod(mat,ublas::trans(W)) << " with det " << determinant(W) << std::flush; return W; }
int do_memory_type(int n, W workspace) { typedef typename boost::numeric::bindings::traits::type_traits<T>::real_type real_type ; typedef std::complex< real_type > complex_type ; typedef ublas::matrix<T, ublas::column_major> matrix_type ; typedef ublas::vector<T> vector_type ; // Set matrix matrix_type a( n, n ); vector_type tau( n ); randomize( a ); matrix_type a2( a ); matrix_type a3( a ); // Compute QR factorization. lapack::geqrf( a, tau, workspace ) ; // Apply the orthogonal transformations to a2 lapack::ormqr( 'L', transpose<T>::value, a, tau, a2, workspace ); // The upper triangular parts of a and a2 must be equal. if (norm_frobenius( upper_part( a - a2 ) ) > std::numeric_limits<real_type>::epsilon() * 10.0 * norm_frobenius( upper_part( a ) ) ) return 255 ; // Generate orthogonal matrix lapack::orgqr( a, tau, workspace ); // The result of lapack::ormqr and the equivalent matrix product must be equal. if (norm_frobenius( a2 - prod(herm(a), a3) ) > std::numeric_limits<real_type>::epsilon() * 10.0 * norm_frobenius( a2 ) ) return 255 ; return 0 ; } // do_value_type()
void cofi::NormEvaluator::eval(cofi::Problem& p, std::map<std::string, double>& results){ results[NU] = norm_frobenius(p.getU()); results[NM] = norm_frobenius(p.getM()); if(p.usingGraphKernel()){ results[NA] = norm_frobenius(p.getA()); } else{ results[NA] = -1.0; } }