sub_matrix_type constructor_helper(transposed_view<MatrixType> const& view) { typedef typename boost::remove_const<MatrixType>::type tmp_type; typedef typename sub_matrix_t<tmp_type>::sub_matrix_type ref_sub_type; typedef boost::shared_ptr<ref_sub_type> pointer_type; typedef typename transposed_view<MatrixType>::other ref_type; // Submatrix of referred matrix, colums and rows interchanged // Create a submatrix, whos address will be kept by transposed_view pointer_type p(new ref_sub_type(sub_matrix(const_cast<ref_type&>(view.ref), view.begin_col(), view.end_col(), view.begin_row(), view.end_row()))); return sub_matrix_type(p); }
void abcd::aijAugmentMatrix(std::vector<CompCol_Mat_double> &M) { int nbcols = A.dim(1); std::map<int,std::vector<CompCol_Mat_double> > C; std::map<int,std::vector<int> > stCols; #ifdef WIP double filter_c = dcntl[Controls::aug_filter]; #endif //WIP stC.assign(M.size(), -1); for( size_t i = 0; i < M.size() - 1; i++ ){ for ( size_t j = i+1; j < M.size(); j++ ) { std::vector<int> intersect; std::set_intersection(column_index[i].begin(), column_index[i].end(), column_index[j].begin(), column_index[j].end(), std::back_inserter(intersect)); if (intersect.empty()) continue; CompCol_Mat_double A_ij(sub_matrix(M[i], intersect)); CompCol_Mat_double A_ji(sub_matrix(M[j], intersect)); double *jv = A_ji.val_ptr(); for (int k = 0; k < A_ji.NumNonzeros(); k++) { jv[k] *= -1.0; } #ifdef WIP if(filter_c != 0 || icntl[Controls::aug_iterative] != 0) { std::vector<int> selected_cols; std::vector<double> frob_ij, mu; frob_ij.reserve(A_ij.dim(1)); mu.reserve(A_ij.dim(1)); double card_max = 0; double frob_sum = 0; double nu; for (int k = 0; k < A_ij.dim(1); ++k){ VECTOR_int A_ij_k_ind, A_ji_k_ind; VECTOR_double A_ij_k = middleCol(A_ij, k, A_ij_k_ind); VECTOR_double A_ji_k = middleCol(A_ji, k, A_ji_k_ind); double card_current = A_ij_k_ind.size() * A_ji_k_ind.size(); // exploit the sparcity of the vectors! frob_ij.push_back(sqrt( squaredNorm(A_ij_k, A_ij_k_ind) * squaredNorm(A_ji_k, A_ji_k_ind))); frob_sum += frob_ij[k]; card_max = card_max > card_current ? card_max : card_current; } nu = (frob_sum / frob_ij.size()) / sqrt(card_max); for (int k = 0; k < A_ij.dim(1); ++k){ VECTOR_int A_ij_k_ind, A_ji_k_ind; VECTOR_double A_ij_k = middleCol(A_ij, k, A_ij_k_ind); VECTOR_double A_ji_k = middleCol(A_ji, k, A_ji_k_ind); double inf_ij = infNorm(A_ij_k); double inf_ji = infNorm(A_ji_k); double p = 0, q = 0; for (int l = 0; l < A_ij_k_ind.size(); ++l){ if (abs(A_ij_k(A_ij_k_ind(l))) >= nu/inf_ji) p++; } for (int l = 0; l < A_ji_k_ind.size(); ++l){ if (abs(A_ji_k(A_ji_k_ind(l))) >= nu/inf_ij) q++; } p = ( p==0 ? A_ij_k_ind.size() : p ); q = ( q==0 ? A_ji_k_ind.size() : q ); double mu_ij_k = frob_ij[k] / sqrt(p*q); mu.push_back(mu_ij_k); if(mu_ij_k >= filter_c){ selected_cols.push_back(k); } if(icntl[Controls::aug_iterative] != 0){ if (dcntl[Controls::aug_precond] < 0) { if ((nbcols + k - n_o) % abs((int)dcntl[Controls::aug_precond]) == 0) selected_S_columns.push_back( nbcols + k - n_o); else skipped_S_columns.push_back( nbcols + k - n_o); } else { if (mu_ij_k >= dcntl[Controls::aug_precond]) selected_S_columns.push_back( nbcols + k - n_o); else skipped_S_columns.push_back( nbcols + k - n_o); } } } if (selected_cols.empty()) continue; if( icntl[Controls::aug_iterative] != 2 ) { // don't reduce the A_ij/A_ji, we just need the selected columns! A_ij = sub_matrix(A_ij, selected_cols); A_ji = sub_matrix(A_ji, selected_cols); } } #endif //WIP stCols[i].push_back(nbcols); stCols[j].push_back(nbcols); C[i].push_back(A_ij); C[j].push_back(A_ji); nbcols += A_ij.dim(1); } } size_c = nbcols - A.dim(1); n = nbcols; LINFO << "Size of C : " << size_c; #ifdef WIP if(icntl[Controls::aug_analysis] != 0) return; #endif // WIP // Augment the matrices for(size_t k = 0; k < M.size(); k++){ if(stCols[k].size() == 0) continue; // now augment each partition! stC[k] = stCols[k][0]; M[k] = concat_columns(M[k], C[k], stCols[k]); M[k] = resize_columns(M[k], nbcols); } }
// ----------------------------------------------------------------- // Given matrix in = P.u, calculate the unitary matrix u = [1 / P].in // and the positive P = sqrt[in.in^dag] // We diagonalize PSq = in.in^dag using LAPACK, // then project out its inverse square root void polar(matrix *in, matrix *u, matrix *P) { char V = 'V'; // Ask LAPACK for both eigenvalues and eigenvectors char U = 'U'; // Have LAPACK store upper triangle of U.Ubar int row, col, Npt = NCOL, stat = 0, Nwork = 2 * NCOL; matrix PSq, Pinv, tmat; // Convert PSq to column-major double array used by LAPACK mult_na(in, in, &PSq); for (row = 0; row < NCOL; row++) { for (col = 0; col < NCOL; col++) { store[2 * (col * NCOL + row)] = PSq.e[row][col].real; store[2 * (col * NCOL + row) + 1] = PSq.e[row][col].imag; } } // Compute eigenvalues and eigenvectors of PSq zheev_(&V, &U, &Npt, store, &Npt, eigs, work, &Nwork, Rwork, &stat); // Check for degenerate eigenvalues (broke previous Jacobi algorithm) for (row = 0; row < NCOL; row++) { for (col = row + 1; col < NCOL; col++) { if (fabs(eigs[row] - eigs[col]) < IMAG_TOL) printf("WARNING: w[%d] = w[%d] = %.8g\n", row, col, eigs[row]); } } // Move the results back into matrix structures // Overwrite PSq to hold the eigenvectors for projection for (row = 0; row < NCOL; row++) { for (col = 0; col < NCOL; col++) { PSq.e[row][col].real = store[2 * (col * NCOL + row)]; PSq.e[row][col].imag = store[2 * (col * NCOL + row) + 1]; P->e[row][col] = cmplx(0.0, 0.0); Pinv.e[row][col] = cmplx(0.0, 0.0); } P->e[row][row].real = sqrt(eigs[row]); Pinv.e[row][row].real = 1.0 / sqrt(eigs[row]); } mult_na(P, &PSq, &tmat); mult_nn(&PSq, &tmat, P); // Now project out 1 / sqrt[in.in^dag] to find u = [1 / P].in mult_na(&Pinv, &PSq, &tmat); mult_nn(&PSq, &tmat, &Pinv); mult_nn(&Pinv, in, u); #ifdef DEBUG_CHECK // Check unitarity of u mult_na(u, u, &PSq); c_scalar_add_diag(&PSq, &minus1); for (row = 0; row < NCOL; row++) { for (col = 0; col < NCOL; col++) { if (cabs_sq(&(PSq.e[row][col])) > SQ_TOL) { printf("Error getting unitary piece: "); printf("%.4g > %.4g for [%d, %d]\n", cabs(&(PSq.e[row][col])), IMAG_TOL, row, col); dumpmat(in); dumpmat(u); dumpmat(P); return; } } } #endif #ifdef DEBUG_CHECK // Check hermiticity of P adjoint(P, &tmat); sub_matrix(P, &tmat, &PSq); for (row = 0; row < NCOL; row++) { for (col = 0; col < NCOL; col++) { if (cabs_sq(&(PSq.e[row][col])) > SQ_TOL) { printf("Error getting hermitian piece: "); printf("%.4g > %.4g for [%d, %d]\n", cabs(&(PSq.e[row][col])), IMAG_TOL, row, col); dumpmat(in); dumpmat(u); dumpmat(P); return; } } } #endif #ifdef DEBUG_CHECK // Check that in = P.u mult_nn(P, u, &tmat); sub_matrix(in, &tmat, &PSq); for (row = 0; row < NCOL; row++) { for (col = 0; col < NCOL; col++) { if (cabs_sq(&(PSq.e[row][col])) > SQ_TOL) { printf("Error reconstructing initial matrix: "); printf("%.4g > %.4g for [%d, %d]\n", cabs(&(PSq.e[row][col])), IMAG_TOL, row, col); dumpmat(in); dumpmat(u); dumpmat(P); return; } } } #endif }
sub_matrix_type constructor_helper(MatrixType const& matrix) { return sub_matrix(matrix, matrix.begin_row(), matrix.end_row(), matrix.begin_col(), matrix.end_col()); }