38 #ifndef GMM_RANGE_BASIS_H 
   39 #define GMM_RANGE_BASIS_H 
   52   template <
typename T, 
typename VECT, 
typename MAT1>
 
   53   void tridiag_qr_algorithm
 
   54   (std::vector<
typename number_traits<T>::magnitude_type> diag,
 
   55    std::vector<T> sdiag, 
const VECT &eigval_, 
const MAT1 &eigvect_,
 
   56    bool compvect, tol_type_for_qr tol = default_tol_for_qr) {
 
   57     VECT &eigval = 
const_cast<VECT &
>(eigval_);
 
   58     MAT1 &eigvect = 
const_cast<MAT1 &
>(eigvect_);
 
   59     typedef typename number_traits<T>::magnitude_type R;
 
   61     if (compvect) 
gmm::copy(identity_matrix(), eigvect);
 
   63     size_type n = diag.size(), q = 0, p, ite = 0;
 
   65     if (n == 1) { eigval[0] = gmm::real(diag[0]); 
return; }
 
   67     symmetric_qr_stop_criterion(diag, sdiag, p, q, tol);
 
   70       sub_interval SUBI(p, n-p-q), SUBJ(0, mat_ncols(eigvect)), SUBK(p, n-p-q);
 
   71       if (!compvect) SUBK = sub_interval(0,0);
 
   73       symmetric_Wilkinson_qr_step(sub_vector(diag, SUBI),
 
   74                                   sub_vector(sdiag, SUBI),
 
   75                                   sub_matrix(eigvect, SUBJ, SUBK), compvect);
 
   77       symmetric_qr_stop_criterion(diag, sdiag, p, q, tol*R(3));
 
   79       GMM_ASSERT1(ite < n*100, 
"QR algorithm failed.");
 
   86   template <
typename Mat>
 
   87   void range_basis_eff_Lanczos(
const Mat &BB, std::set<size_type> &columns,
 
   89     typedef std::set<size_type> TAB;
 
   90     typedef typename linalg_traits<Mat>::value_type T;
 
   91     typedef typename number_traits<T>::magnitude_type R;
 
   94     col_matrix< rsvector<T> > B(mat_nrows(BB), mat_ncols(BB));
 
   97     for (TAB::iterator it = columns.begin(); it!=columns.end(); ++it, ++k){
 
  101     std::vector<T> w(mat_nrows(B));
 
  103     std::vector<T> sdiag(restart);
 
  104     std::vector<R> eigval(restart), diag(restart);
 
  105     dense_matrix<T> eigvect(restart, restart);
 
  110       std::vector<T> v(nc_r), v0(nc_r), wl(nc_r);
 
  111       dense_matrix<T> lv(nc_r, restart);
 
  119           for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k)
 
  120             add(scaled(mat_col(B, *it), v[k]), w);
 
  122           for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k)
 
  123             v[k] = 
vect_hp(w, mat_col(B, *it));
 
  135         R beta = R(0), 
alpha;
 
  138     if (sdiag.size() != restart) {
 
  139       sdiag.resize(restart); eigval.resize(restart); diag.resize(restart); 
gmm::resize(eigvect, restart, restart);
 
  143         for (
size_type i = 0; i < restart; ++i) { 
 
  147           for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k)
 
  148             add(scaled(mat_col(B, *it), v[k]), w);
 
  151           for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k)
 
  152             wl[k] = v[k]*rho - 
vect_hp(w, mat_col(B, *it)) - beta*v0[k];
 
  155           gmm::add(gmm::scaled(v, -alpha), wl);
 
  158       if (beta < EPS) { eff_restart = i+1; 
break; }
 
  159       gmm::copy(gmm::scaled(wl, T(1) / beta), v);
 
  161     if (eff_restart != restart) {
 
  162       sdiag.resize(eff_restart); eigval.resize(eff_restart); diag.resize(eff_restart);
 
  165         tridiag_qr_algorithm(diag, sdiag, eigval, eigvect, 
true);
 
  169         for (
size_type j = 0; j < eff_restart; ++j)
 
  170           { R nvp=gmm::abs(eigval[j]); 
if (nvp > rho2) { rho2=nvp; num=j; }}
 
  172         GMM_ASSERT1(num != 
size_type(-1), 
"Internal error");
 
  176         if (gmm::abs(rho2-rho_old) < rho_old*R(EPS)) 
break;
 
  178         if (gmm::abs(rho-rho2) < rho*R(EPS)*R(100)) 
break;
 
  181       if (gmm::abs(rho-rho2) < rho*R(EPS*10.)) {
 
  184         for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++j)
 
  185           if (gmm::abs(v[j]) > val_max)
 
  186             { val_max = gmm::abs(v[j]); j_max = *it; }
 
  187         columns.erase(j_max); nc_r = columns.size();
 
  195   template <
typename Mat>
 
  196   void range_basis_eff_lu(
const Mat &B, std::set<size_type> &columns,
 
  197                           std::vector<bool> &c_ortho, 
double EPS) {
 
  199     typedef std::set<size_type> TAB;
 
  200     typedef typename linalg_traits<Mat>::value_type T;
 
  201     typedef typename number_traits<T>::magnitude_type R;
 
  203     size_type nc_r = 0, nc_o = 0, nc = mat_ncols(B), nr = mat_nrows(B), i, j;
 
  205     for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it)
 
  206       if (!(c_ortho[*it])) ++nc_r; 
else nc_o++;
 
  210       gmm::row_matrix< gmm::rsvector<T> > Hr(nc, nc_r), Ho(nc, nc_o);
 
  211       gmm::row_matrix< gmm::rsvector<T> > BBr(nr, nc_r), BBo(nr, nc_o);
 
  214       for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it)
 
  216           { Hr(*it, i) = T(1)/ 
vect_norminf(mat_col(B, *it)); ++i; }
 
  218           { Ho(*it, j) = T(1)/ 
vect_norm2(mat_col(B, *it)); ++j; }
 
  222       gmm::dense_matrix<T> M(nc_r, nc_r), BBB(nc_r, nc_o), MM(nc_r, nc_r);
 
  224       gmm::mult(gmm::conjugated(BBr), BBo, BBB);
 
  225       gmm::mult(BBB, gmm::conjugated(BBB), MM);
 
  226       gmm::add(gmm::scaled(MM, T(-1)), M);
 
  228       std::vector<int> ipvt(nc_r);
 
  232       for (i = 0; i < nc_r; ++i) emax = std::max(emax, gmm::abs(M(i,i)));
 
  235       std::set<size_type> c = columns;
 
  236       for (TAB::iterator it = c.begin(); it != c.end(); ++it)
 
  237         if (!(c_ortho[*it])) {
 
  238           if (gmm::abs(M(i,i)) <= R(EPS)*emax) columns.erase(*it);
 
  249   template <
typename Mat>
 
  250   void range_basis_eff_Gram_Schmidt_sparse(
const Mat &BB,
 
  251                                            std::set<size_type> &columns,
 
  252                                            std::vector<bool> &c_ortho,
 
  255     typedef std::set<size_type> TAB;
 
  256     typedef typename linalg_traits<Mat>::value_type T;
 
  257     typedef typename number_traits<T>::magnitude_type R;
 
  259     size_type nc = mat_ncols(BB), nr = mat_nrows(BB);
 
  260     std::set<size_type> c = columns, rc = columns;
 
  262     gmm::col_matrix< rsvector<T> > B(nr, nc);
 
  263     for (std::set<size_type>::iterator it = columns.begin();
 
  264          it != columns.end(); ++it) {
 
  265       gmm::copy(mat_col(BB, *it), mat_col(B, *it));
 
  266       gmm::scale(mat_col(B, *it), T(1)/
vect_norm2(mat_col(B, *it)));
 
  269     for (std::set<size_type>::iterator it = c.begin(); it != c.end(); ++it)
 
  271         for (std::set<size_type>::iterator it2 = rc.begin();
 
  272              it2 != rc.end(); ++it2)
 
  273           if (!(c_ortho[*it2])) {
 
  274             T r = -
vect_hp(mat_col(B, *it2), mat_col(B, *it));
 
  275             if (r != T(0)) 
add(scaled(mat_col(B, *it), r), mat_col(B, *it2));
 
  282       for (std::set<size_type>::iterator it=rc.begin(); it != rc.end();) {
 
  283         TAB::iterator itnext = it; ++itnext;
 
  285         if (nmax < n) { nmax = n; cmax = *it; }
 
  286         if (n < R(EPS)) { columns.erase(*it); rc.erase(*it); }
 
  290       if (nmax < R(EPS)) 
break;
 
  292       gmm::scale(mat_col(B, cmax), T(1)/
vect_norm2(mat_col(B, cmax)));
 
  294       for (std::set<size_type>::iterator it=rc.begin(); it!=rc.end(); ++it) {
 
  295         T r = -
vect_hp(mat_col(B, *it), mat_col(B, cmax));
 
  296         if (r != T(0)) 
add(scaled(mat_col(B, cmax), r), mat_col(B, *it));
 
  299     for (std::set<size_type>::iterator it=rc.begin(); it!=rc.end(); ++it)
 
  305   template <
typename Mat>
 
  306   void range_basis_eff_Gram_Schmidt_dense(
const Mat &B,
 
  307                                           std::set<size_type> &columns,
 
  308                                           std::vector<bool> &c_ortho,
 
  311     typedef std::set<size_type> TAB;
 
  312     typedef typename linalg_traits<Mat>::value_type T;
 
  313     typedef typename number_traits<T>::magnitude_type R;
 
  315     size_type nc_r = columns.size(), nc = mat_ncols(B), nr = mat_nrows(B), i;
 
  316     std::set<size_type> rc;
 
  318     row_matrix< gmm::rsvector<T> > H(nc, nc_r), BB(nr, nc_r);
 
  319     std::vector<T> v(nc_r);
 
  320     std::vector<size_type> ind(nc_r);
 
  323     for (TAB::iterator it = columns.begin(); it != columns.end(); ++it, ++i)
 
  324       H(*it, i) = T(1) / 
vect_norm2(mat_col(B, *it));
 
  327     dense_matrix<T> M(nc_r, nc_r);
 
  328     mult(gmm::conjugated(BB), BB, M);
 
  331     for (TAB::iterator it = columns.begin(); it != columns.end(); ++it, ++i)
 
  334         rank_one_update(M, scaled(v, T(-1)), v);
 
  337       else { rc.insert(i); ind[i] = *it; }
 
  339     while (rc.size() > 0) {
 
  343       for (TAB::iterator it = rc.begin(); it != rc.end();) {
 
  344         TAB::iterator itnext = it; ++itnext;
 
  345         R a = gmm::abs(M(*it, *it));
 
  346         if (a > nmax) { nmax = a; imax = *it; }
 
  347         if (a < R(EPS)) { columns.erase(ind[*it]); rc.erase(*it); }
 
  351       if (nmax < R(EPS)) 
break;
 
  354       gmm::scale(mat_row(M, imax), T(1) / sqrt(nmax));
 
  355       gmm::scale(mat_col(M, imax), T(1) / sqrt(nmax));
 
  358       copy(mat_row(M, imax), v);
 
  359       rank_one_update(M, scaled(v, T(-1)), v);
 
  360       M(imax, imax) = T(1);
 
  364     for (std::set<size_type>::iterator it=rc.begin(); it!=rc.end(); ++it)
 
  365       columns.erase(ind[*it]);
 
  368   template <
typename L> 
size_type nnz_eps(
const L& l, 
double eps) {
 
  369     typename linalg_traits<L>::const_iterator it = vect_const_begin(l),
 
  370       ite = vect_const_end(l);
 
  372     for (; it != ite; ++it) 
if (gmm::abs(*it) >= eps) ++res;
 
  376   template <
typename L>
 
  377   bool reserve__rb(
const L& l, std::vector<bool> &b, 
double eps) {
 
  378     typename linalg_traits<L>::const_iterator it = vect_const_begin(l),
 
  379       ite = vect_const_end(l);
 
  381     for (; it != ite; ++it)
 
  382       if (gmm::abs(*it) >= eps && b[it.index()]) ok = 
false;
 
  384       for (it = vect_const_begin(l); it != ite; ++it)
 
  385         if (gmm::abs(*it) >= eps) b[it.index()] = 
true;
 
  390   template <
typename Mat>
 
  391   void range_basis(
const Mat &B, std::set<size_type> &columns,
 
  392                        double EPS, col_major, 
bool skip_init=
false) {
 
  394     typedef typename linalg_traits<Mat>::value_type T;
 
  395     typedef typename number_traits<T>::magnitude_type R;
 
  397     size_type nc = mat_ncols(B), nr = mat_nrows(B);
 
  399     std::vector<R> norms(nc);
 
  400     std::vector<bool> c_ortho(nc), booked(nr);
 
  401     std::vector< std::set<size_type> > nnzs(mat_nrows(B));
 
  408         norm_max = std::max(norm_max, norms[i]);
 
  413         if (norms[i] > norm_max*R(EPS)) {
 
  415           nnzs[nnz_eps(mat_col(B, i), R(EPS) * norms[i])].insert(i);
 
  419         for (std::set<size_type>::iterator it = nnzs[i].begin();
 
  420              it != nnzs[i].end(); ++it)
 
  421           if (reserve__rb(mat_col(B, *it), booked, R(EPS) * norms[*it]))
 
  425     size_type sizesm[7] = {125, 200, 350, 550, 800, 1100, 1500}, actsize;
 
  426     for (
int k = 0; k < 7; ++k) {
 
  428       std::set<size_type> c1, cres;
 
  430       for (std::set<size_type>::iterator it = columns.begin();
 
  431            it != columns.end(); ++it) {
 
  433         if (c1.size() >= actsize) {
 
  434           range_basis_eff_Gram_Schmidt_dense(B, c1, c_ortho, EPS);
 
  435           for (std::set<size_type>::iterator it2=c1.begin(); it2 != c1.end();
 
  436                ++it2) cres.insert(*it2);
 
  441         range_basis_eff_Gram_Schmidt_dense(B, c1, c_ortho, EPS);
 
  442       for (std::set<size_type>::iterator it = c1.begin(); it != c1.end(); ++it)
 
  445       if (nc_r <= actsize) 
return;
 
  446       if (columns.size() == nc_r) 
break;
 
  447       if (sizesm[k] >= 350 && columns.size() > (nc_r*19)/20) 
break;
 
  449     if (columns.size() > std::max(
size_type(10), actsize))
 
  450       range_basis_eff_Lanczos(B, columns, EPS);
 
  452       range_basis_eff_Gram_Schmidt_dense(B, columns, c_ortho, EPS);
 
  456   template <
typename Mat>
 
  457   void range_basis(
const Mat &B, std::set<size_type> &columns,
 
  458                    double EPS, row_major) {
 
  459     typedef typename  linalg_traits<Mat>::value_type T;
 
  460     gmm::col_matrix< rsvector<T> > BB(mat_nrows(B), mat_ncols(B));
 
  461     GMM_WARNING3(
"A copy of a row matrix is done into a column matrix " 
  462                  "for range basis algorithm.");
 
  464     range_basis(BB, columns, EPS);
 
  489   template <
typename Mat>
 
  490   void range_basis(
const Mat &B, std::set<size_type> &columns,
 
  492     range_basis(B, columns, EPS,
 
  493                 typename principal_orientation_type
 
  494                 <
typename linalg_traits<Mat>::sub_orientation>::potype());
 
void copy(const L1 &l1, L2 &l2)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
 
void fill_random(L &l)
fill a vector or matrix with random value (uniform [-1,1]).
 
strongest_value_type< V1, V2 >::value_type vect_hp(const V1 &v1, const V2 &v2)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norminf(const V &v)
Infinity norm of a vector.
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
void resize(V &v, size_type n)
*/
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
void add(const L1 &l1, L2 &l2)
*/
 
LU factorizations and determinant computation for dense matrices.
 
size_type lu_factor(DenseMatrix &A, Pvector &ipvt)
LU Factorization of a general (dense) matrix (real or complex).
 
Include the base gmm files.
 
size_t size_type
used as the common size type in the library
 
size_type alpha(short_type n, short_type d)
Return the value of  which is the number of monomials of a polynomial of  variables and degree .