NM_Status SubspaceIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot) // // this function solve the generalized eigenproblem using the Generalized // jacobi iteration // { if ( a.giveNumberOfColumns() != b.giveNumberOfColumns() ) { OOFEM_ERROR("matrices size mismatch"); } FloatArray temp, w, d, tt, f, rtolv, eigv; FloatMatrix r; int nn, nc1, ij = 0, is; double rt, art, brt, eigvt; FloatMatrix ar, br, vec; std :: unique_ptr< SparseLinearSystemNM > solver( GiveClassFactory().createSparseLinSolver(ST_Direct, domain, engngModel) ); GJacobi mtd(domain, engngModel); int nc = min(2 * nroot, nroot + 8); nn = a.giveNumberOfColumns(); if ( nc > nn ) { nc = nn; } ar.resize(nc, nc); ar.zero(); br.resize(nc, nc); br.zero(); // // creation of initial iteration vectors // nc1 = nc - 1; w.resize(nn); w.zero(); d.resize(nc); d.zero(); tt.resize(nn); tt.zero(); rtolv.resize(nc); rtolv.zero(); vec.resize(nc, nc); vec.zero(); // eigen vectors of reduced problem // // create work arrays // r.resize(nn, nc); r.zero(); eigv.resize(nc); eigv.zero(); FloatArray h(nn); for ( int i = 1; i <= nn; i++ ) { h.at(i) = 1.0; w.at(i) = b.at(i, i) / a.at(i, i); } b.times(h, tt); r.setColumn(tt, 1); for ( int j = 2; j <= nc; j++ ) { rt = 0.0; for ( int i = 1; i <= nn; i++ ) { if ( fabs( w.at(i) ) >= rt ) { rt = fabs( w.at(i) ); ij = i; } } tt.at(j) = ij; w.at(ij) = 0.; for ( int i = 1; i <= nn; i++ ) { if ( i == ij ) { h.at(i) = 1.0; } else { h.at(i) = 0.0; } } b.times(h, tt); r.setColumn(tt, j); } // (r = z) # ifdef DETAILED_REPORT OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Degrees of freedom invoked by initial vectors :\n"); tt.printYourself(); OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: initial vectors for iteration:\n"); r.printYourself(); # endif //ish = 0; a.factorized(); // // start of iteration loop // for ( int nite = 0; ; ++nite ) { // label 100 # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Iteration loop no. %d\n", nite); # endif // // compute projection ar and br of matrices a , b // for ( int j = 1; j <= nc; j++ ) { f.beColumnOf(r, j); solver->solve(a, f, tt); for ( int i = j; i <= nc; i++ ) { art = 0.; for ( int k = 1; k <= nn; k++ ) { art += r.at(k, i) * tt.at(k); } ar.at(j, i) = art; } r.setColumn(tt, j); // (r = xbar) } ar.symmetrized(); // label 110 #ifdef DETAILED_REPORT OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Printing projection matrix ar\n"); ar.printYourself(); #endif // for ( int j = 1; j <= nc; j++ ) { tt.beColumnOf(r, j); b.times(tt, temp); for ( int i = j; i <= nc; i++ ) { brt = 0.; for ( int k = 1; k <= nn; k++ ) { brt += r.at(k, i) * temp.at(k); } br.at(j, i) = brt; } // label 180 r.setColumn(temp, j); // (r=zbar) } // label 160 br.symmetrized(); #ifdef DETAILED_REPORT OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Printing projection matrix br\n"); br.printYourself(); #endif // // solution of reduced eigenvalue problem // mtd.solve(ar, br, eigv, vec); // START EXPERIMENTAL #if 0 // solve the reduced problem by Inverse iteration { FloatMatrix x(nc,nc), z(nc,nc), zz(nc,nc), arinv; FloatArray w(nc), ww(nc), tt(nc), t(nc); double c; // initial setting for ( int i = 1;i <= nc; i++ ) { ww.at(i)=1.0; } for ( int i = 1;i <= nc; i++ ) for ( int j = 1; j <= nc;j++ ) z.at(i,j)=1.0; arinv.beInverseOf (ar); for ( int i = 0;i < nitem; i++ ) { // copy zz=z zz = z; // solve matrix equation K.X = M.X x.beProductOf(arinv, z); // evaluation of Rayleigh quotients for ( int j = 1;j <= nc; j++ ) { w.at(j) = 0.0; for (k = 1; k<= nc; k++) w.at(j) += zz.at(k,j) * x.at(k,j); } z.beProductOf (br, x); for ( int j = 1;j <= nc; j++ ) { c = 0; for ( int k = 1; k<= nc; k++ ) c += z.at(k,j) * x.at(k,j); w.at(j) /= c; } // check convergence int ac = 0; for ( int j = 1;j <= nc; j++ ) { if (fabs((ww.at(j)-w.at(j))/w.at(j))< rtol) ac++; ww.at(j) = w.at(j); } //printf ("\n iterace cislo %d %d",i,ac); //w.printYourself(); // Gramm-Schmidt ortogonalization for ( int j = 1;j <= nc;j++ ) { for ( int k = 1; k<= nc; k++ ) tt.at(k) = x.at(k,j); t.beProductOf(br,tt) ; for ( int ii = 1;ii < j; ii++ ) { c = 0.0; for ( int k = 1; k<= nc; k++ ) c += x.at(k,ii) * t.at(k); for ( int k = 1; k<= nc; k++ ) x.at(k,j) -= x.at(k,ii) * c; } for ( int k = 1; k<= nc; k++) tt.at(k) = x.at(k,j); t.beProductOf(br, tt); c = 0.0; for ( int k = 1; k<= nc; k++) c += x.at(k,j)*t.at(k); for ( int k = 1; k<= nc; k++) x.at(k,j) /= sqrt(c); } if ( ac > nroot ) { break; } // compute new approximation of Z z.beProductOf(br,x); } eigv = w; vec = x; } #endif // // sorting eigenvalues according to their values // do { is = 0; // label 350 for ( int i = 1; i <= nc1; i++ ) { if ( fabs( eigv.at(i + 1) ) < fabs( eigv.at(i) ) ) { is++; eigvt = eigv.at(i + 1); eigv.at(i + 1) = eigv.at(i); eigv.at(i) = eigvt; for ( int k = 1; k <= nc; k++ ) { rt = vec.at(k, i + 1); vec.at(k, i + 1) = vec.at(k, i); vec.at(k, i) = rt; } } } // label 360 } while ( is != 0 ); # ifdef DETAILED_REPORT OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: current eigen values of reduced problem \n"); eigv.printYourself(); OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: current eigen vectors of reduced problem \n"); vec.printYourself(); # endif // // compute eigenvectors // for ( int i = 1; i <= nn; i++ ) { // label 375 for ( int j = 1; j <= nc; j++ ) { tt.at(j) = r.at(i, j); } for ( int k = 1; k <= nc; k++ ) { rt = 0.; for ( int j = 1; j <= nc; j++ ) { rt += tt.at(j) * vec.at(j, k); } r.at(i, k) = rt; } } // label 420 (r = z) // // convergency check // for ( int i = 1; i <= nc; i++ ) { double dif = ( eigv.at(i) - d.at(i) ); rtolv.at(i) = fabs( dif / eigv.at(i) ); } # ifdef DETAILED_REPORT OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Reached precision of eigenvalues:\n"); rtolv.printYourself(); # endif for ( int i = 1; i <= nroot; i++ ) { if ( rtolv.at(i) > rtol ) { goto label400; } } OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Convergence reached for RTOL=%20.15f\n", rtol); break; label400: if ( nite >= nitem ) { OOFEM_WARNING("SubspaceIteration :: solveYourselfAt: Convergence not reached in %d iteration - using current values", nitem); break; } d = eigv; // label 410 and 440 continue; } // compute eigenvectors for ( int j = 1; j <= nc; j++ ) { tt.beColumnOf(r, j); a.backSubstitutionWith(tt); r.setColumn(tt, j); // r = xbar } // one cad add a normalization of eigen-vectors here // initialize original index locations _r.resize(nn, nroot); _eigv.resize(nroot); for ( int i = 1; i <= nroot; i++ ) { _eigv.at(i) = eigv.at(i); for ( int j = 1; j <= nn; j++ ) { _r.at(j, i) = r.at(j, i); } } return NM_Success; }
NM_Status SLEPcSolver :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot) { FILE *outStream; PetscErrorCode ierr; int size; ST st; outStream = domain->giveEngngModel()->giveOutputStream(); // first check whether Lhs is defined if ( a->giveNumberOfRows() != a->giveNumberOfColumns() || b->giveNumberOfRows() != b->giveNumberOfRows() || a->giveNumberOfColumns() != b->giveNumberOfColumns() ) { OOFEM_ERROR("matrices size mismatch"); } A = dynamic_cast< PetscSparseMtrx * >(&a); B = dynamic_cast< PetscSparseMtrx * >(&b); if ( !A || !B ) { OOFEM_ERROR("PetscSparseMtrx Expected"); } size = engngModel->giveParallelContext( A->giveDomainIndex() )->giveNumberOfNaturalEqs(); // A->giveLeqs(); _r.resize(size, nroot); _eigv.resize(nroot); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Create the eigensolver and set various options * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ int nconv, nite; EPSConvergedReason reason; #ifdef TIME_REPORT Timer timer; timer.startTimer(); #endif if ( !epsInit ) { /* * Create eigensolver context */ #ifdef __PARALLEL_MODE MPI_Comm comm = engngModel->giveParallelComm(); #else MPI_Comm comm = PETSC_COMM_SELF; #endif ierr = EPSCreate(comm, & eps); CHKERRQ(ierr); epsInit = true; } /* * Set operators. In this case, it is a generalized eigenvalue problem */ ierr = EPSSetOperators( eps, * A->giveMtrx(), * B->giveMtrx() ); CHKERRQ(ierr); ierr = EPSSetProblemType(eps, EPS_GHEP); CHKERRQ(ierr); ierr = EPSGetST(eps, & st); CHKERRQ(ierr); ierr = STSetType(st, STSINVERT); CHKERRQ(ierr); ierr = STSetMatStructure(st, SAME_NONZERO_PATTERN); CHKERRQ(ierr); ierr = EPSSetTolerances(eps, ( PetscReal ) rtol, PETSC_DECIDE); CHKERRQ(ierr); ierr = EPSSetDimensions(eps, ( PetscInt ) nroot, PETSC_DECIDE, PETSC_DECIDE); CHKERRQ(ierr); ierr = EPSSetWhichEigenpairs(eps, EPS_SMALLEST_MAGNITUDE); CHKERRQ(ierr); /* * Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Solve the eigensystem * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps); CHKERRQ(ierr); ierr = EPSGetConvergedReason(eps, & reason); CHKERRQ(ierr); ierr = EPSGetIterationNumber(eps, & nite); CHKERRQ(ierr); OOFEM_LOG_INFO("SLEPcSolver::solve EPSConvergedReason: %d, number of iterations: %d\n", reason, nite); ierr = EPSGetConverged(eps, & nconv); CHKERRQ(ierr); if ( nconv > 0 ) { fprintf(outStream, "SLEPcSolver :: solveYourselfAt: Convergence reached for RTOL=%20.15f", rtol); PetscScalar kr; Vec Vr; ierr = MatGetVecs(* B->giveMtrx(), PETSC_NULL, & Vr); CHKERRQ(ierr); FloatArray Vr_loc; for ( int i = 0; i < nconv && i < nroot; i++ ) { ierr = EPSGetEigenpair(eps, nconv - i - 1, & kr, PETSC_NULL, Vr, PETSC_NULL); CHKERRQ(ierr); //Store the eigenvalue _eigv->at(i + 1) = kr; //Store the eigenvector A->scatterG2L(Vr, Vr_loc); for ( int j = 0; j < size; j++ ) { _r->at(j + 1, i + 1) = Vr_loc.at(j + 1); } } ierr = VecDestroy(Vr); CHKERRQ(ierr); } else { OOFEM_ERROR("No converged eigenpairs"); } #ifdef TIME_REPORT timer.stopTimer(); OOFEM_LOG_INFO( "SLEPcSolver info: user time consumed by solution: %.2fs\n", timer.getUtime() ); #endif return NM_Success; }
NM_Status InverseIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot) { FILE *outStream; if ( a.giveNumberOfColumns() != b.giveNumberOfColumns() ) { OOFEM_ERROR("matrices size mismatch"); } SparseLinearSystemNM *solver = GiveClassFactory().createSparseLinSolver(ST_Direct, domain, engngModel); int nn = a.giveNumberOfColumns(); int nc = min(2 * nroot, nroot + 8); nc = min(nc, nn); //// control of diagonal zeroes in mass matrix, to be avoided //int i; //for (i = 1; i <= nn; i++) { // if (b.at(i, i) == 0) { // b.at(i, i) = 1.0e-12; // } //} FloatArray w(nc), ww(nc), t; std :: vector< FloatArray > z(nc, nn), zz(nc, nn), x(nc, nn); outStream = domain->giveEngngModel()->giveOutputStream(); /* initial setting */ #if 0 ww.add(1.0); for ( int j = 0; j < nc; j++ ) { z[j].add(1.0); } #else { FloatArray ad(nn), bd(nn); for (int i = 1; i <= nn; i++) { ad.at(i) = fabs(a.at(i, i)); bd.at(i) = fabs(b.at(i, i)); } IntArray order; order.enumerate(nn); std::sort(order.begin(), order.end(), [&ad, &bd](int a, int b) { return bd.at(a) * ad.at(b) > bd.at(b) * ad.at(a); }); for (int i = 0; i < nc; i++) { x[i].at(order[i]) = 1.0; b.times(x[i], z[i]); ww.at(i + 1) = z[i].dotProduct(x[i]); } } #endif int it; for ( it = 0; it < nitem; it++ ) { /* copy zz=z */ for ( int j = 0; j < nc; j++ ) { zz[j] = z[j]; } /* solve matrix equation K.X = M.X */ for ( int j = 0; j < nc; j++ ) { solver->solve(a, z[j], x[j]); } /* evaluation of Rayleigh quotients */ for ( int j = 0; j < nc; j++ ) { w.at(j + 1) = zz[j].dotProduct(x[j]); } for ( int j = 0; j < nc; j++ ) { b.times(x[j], z[j]); } for ( int j = 0; j < nc; j++ ) { w.at(j + 1) /= z[j].dotProduct(x[j]); } /* check convergence */ int ac = 0; for ( int j = 1; j <= nc; j++ ) { if ( fabs( ww.at(j) - w.at(j) ) <= fabs( w.at(j) * rtol ) ) { ac++; } ww.at(j) = w.at(j); } //printf ("\n iteration %d %d",it,ac); //w.printYourself(); /* Gramm-Schmidt ortogonalization */ for ( int j = 0; j < nc; j++ ) { if ( j != 0 ) { b.times(x[j], t); } for ( int ii = 0; ii < j; ii++ ) { x[j].add( -x[ii].dotProduct(t), x[ii] ); } b.times(x[j], t); x[j].times( 1.0 / sqrt( x[j].dotProduct(t) ) ); } if ( ac > nroot ) { break; } /* compute new approximation of Z */ for ( int j = 0; j < nc; j++ ) { b.times(x[j], z[j]); } } // copy results IntArray order; order.enumerate(w.giveSize()); std :: sort(order.begin(), order.end(), [&w](int a, int b) { return w.at(a) < w.at(b); }); _eigv.resize(nroot); _r.resize(nn, nroot); for ( int i = 1; i <= nroot; i++ ) { _eigv.at(i) = w.at(order.at(i)); _r.setColumn(x[order.at(i) - 1], i); } if ( it < nitem ) { fprintf(outStream, "InverseIteration :: convergence reached in %d iterations\n", it); } else { fprintf(outStream, "InverseIteration :: convergence not reached after %d iterations\n", it); } return NM_Success; }
NM_Status SubspaceIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot) // // this function solve the generalized eigenproblem using the Generalized // jacobi iteration // // { FILE *outStream; FloatArray temp, w, d, tt, rtolv, eigv; FloatMatrix r; int nn, nc1, i, j, k, ij = 0, nite, is; double rt, art, brt, eigvt, dif; FloatMatrix ar, br, vec; GJacobi mtd(domain, engngModel); outStream = domain->giveEngngModel()->giveOutputStream(); nc = min(2 * nroot, nroot + 8); // // check matrix size // if ( a.giveNumberOfColumns() != b.giveNumberOfColumns() ) { OOFEM_ERROR("matrices size mismatch"); } // check matrix for factorization support if ( !a.canBeFactorized() ) { OOFEM_ERROR("a matrix not support factorization"); } // // check for wery small problem // nn = a.giveNumberOfColumns(); if ( nc > nn ) { nc = nn; } ar.resize(nc, nc); ar.zero(); br.resize(nc, nc); br.zero(); // // creation of initial iteration vectors // nc1 = nc - 1; w.resize(nn); w.zero(); d.resize(nc); d.zero(); tt.resize(nn); tt.zero(); rtolv.resize(nc); rtolv.zero(); vec.resize(nc, nc); vec.zero(); // eigen vectors of reduced problem _r.resize(nn, nroot); _eigv.resize(nroot); // // create work arrays // r.resize(nn, nc); r.zero(); eigv.resize(nc); eigv.zero(); FloatArray h(nn); for ( i = 1; i <= nn; i++ ) { h.at(i) = 1.0; w.at(i) = b.at(i, i) / a.at(i, i); } b.times(h, tt); for ( i = 1; i <= nn; i++ ) { r.at(i, 1) = tt.at(i); } for ( j = 2; j <= nc; j++ ) { rt = 0.0; for ( i = 1; i <= nn; i++ ) { if ( fabs( w.at(i) ) >= rt ) { rt = fabs( w.at(i) ); ij = i; } } tt.at(j) = ij; w.at(ij) = 0.; for ( i = 1; i <= nn; i++ ) { if ( i == ij ) { h.at(i) = 1.0; } else { h.at(i) = 0.0; } } b.times(h, tt); for ( i = 1; i <= nn; i++ ) { r.at(i, j) = tt.at(i); } } // (r = z) # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Degrees of freedom invoked by initial vectors :\n"); tt.printYourself(); printf("SubspaceIteration :: solveYourselfAt: initial vectors for iteration:\n"); r.printYourself(); # endif //ish = 0; a.factorized(); // // start of iteration loop // nite = 0; do { // label 100 nite++; # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Iteration loop no. %d\n", nite); # endif // // compute projection ar and br of matrices a , b // for ( j = 1; j <= nc; j++ ) { for ( k = 1; k <= nn; k++ ) { tt.at(k) = r.at(k, j); } //a. forwardReductionWith(&tt) -> diagonalScalingWith (&tt) // -> backSubstitutionWithtt) ; a.backSubstitutionWith(tt); for ( i = j; i <= nc; i++ ) { art = 0.; for ( k = 1; k <= nn; k++ ) { art += r.at(k, i) * tt.at(k); } ar.at(j, i) = art; } for ( k = 1; k <= nn; k++ ) { r.at(k, j) = tt.at(k); // (r = xbar) } } ar.symmetrized(); // label 110 #ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Printing projection matrix ar\n"); ar.printYourself(); #endif // for ( j = 1; j <= nc; j++ ) { for ( k = 1; k <= nn; k++ ) { tt.at(k) = r.at(k, j); } b.times(tt, temp); for ( i = j; i <= nc; i++ ) { brt = 0.; for ( k = 1; k <= nn; k++ ) { brt += r.at(k, i) * temp.at(k); } br.at(j, i) = brt; } // label 180 for ( k = 1; k <= nn; k++ ) { r.at(k, j) = temp.at(k); // (r=zbar) } } // label 160 br.symmetrized(); #ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Printing projection matrix br\n"); br.printYourself(); #endif // // solution of reduced eigenvalue problem // mtd.solve(ar, br, eigv, vec); /// START EXPERIMENTAL // solve the reduced problem by Inverse iteration /* * { * FloatMatrix x(nc,nc), z(nc,nc), zz(nc,nc), arinv; * FloatArray w(nc), ww(nc), tt(nc), t(nc); * double c; * int ii, i,j,k,ac; * * * // initial setting * for (i=1;i<=nc;i++){ * ww.at(i)=1.0; * } * * for (i=1;i<=nc;i++) * for (j=1; j<=nc;j++) * z.at(i,j)=1.0; * * arinv.beInverseOf (ar); * * for (i=0;i<nitem;i++) { * * // copy zz=z * zz = z; * * // solve matrix equation K.X = M.X * x.beProductOf (arinv, z); * // evaluation of Rayleigh quotients * for (j=1;j<=nc;j++){ * w.at(j) = 0.0; * for (k = 1; k<= nc; k++) w.at(j) += zz.at(k,j)*x.at(k,j); * } * * z.beProductOf (br, x); * * for (j=1;j<=nc;j++){ * c = 0; * for (k = 1; k<= nc; k++) c+= z.at(k,j)*x.at(k,j); * w.at(j) /= c; * } * * // check convergence * ac=0; * for (j=1;j<=nc;j++){ * if (fabs((ww.at(j)-w.at(j))/w.at(j))< rtol) ac++; * ww.at(j)=w.at(j); * } * * printf ("\n iterace cislo %d %d",i,ac); * w.printYourself(); * * // Gramm-Schmidt ortogonalization * for (j=1;j<=nc;j++) { * for (k = 1; k<= nc; k++) tt.at(k) = x.at(k,j) ; * t.beProductOf(br,tt) ; * for (ii=1;ii<j;ii++) { * c = 0.0; * for (k = 1; k<= nc; k++) c += x.at(k,ii)*t.at(k); * for (k = 1; k<= nc; k++) x.at(k,j) -= x.at(k,ii)*c; * } * for (k = 1; k<= nc; k++) tt.at(k) = x.at(k,j) ; * t.beProductOf (br,tt) ; * c = 0.0; * for (k = 1; k<= nc; k++) c += x.at(k,j)*t.at(k); * for (k = 1; k<= nc; k++) x.at(k,j) /= sqrt(c); * } * * if (ac>nroot){ * break; * } * * // compute new approximation of Z * z.beProductOf (br,x); * } * * eigv = w; * vec = x; * } * /// END EXPERIMANTAL */ // // sorting eigenvalues according to their values // do { is = 0; // label 350 for ( i = 1; i <= nc1; i++ ) { if ( fabs( eigv.at(i + 1) ) < fabs( eigv.at(i) ) ) { is++; eigvt = eigv.at(i + 1); eigv.at(i + 1) = eigv.at(i); eigv.at(i) = eigvt; for ( k = 1; k <= nc; k++ ) { rt = vec.at(k, i + 1); vec.at(k, i + 1) = vec.at(k, i); vec.at(k, i) = rt; } } } // label 360 } while ( is != 0 ); # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: current eigen values of reduced problem \n"); eigv.printYourself(); printf("SubspaceIteration :: solveYourselfAt: current eigen vectors of reduced problem \n"); vec.printYourself(); # endif // // compute eigenvectors // for ( i = 1; i <= nn; i++ ) { // label 375 for ( j = 1; j <= nc; j++ ) { tt.at(j) = r.at(i, j); } for ( k = 1; k <= nc; k++ ) { rt = 0.; for ( j = 1; j <= nc; j++ ) { rt += tt.at(j) * vec.at(j, k); } r.at(i, k) = rt; } } // label 420 (r = z) // // convergency check // for ( i = 1; i <= nc; i++ ) { dif = ( eigv.at(i) - d.at(i) ); rtolv.at(i) = fabs( dif / eigv.at(i) ); } # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Reached precision of eigenvalues:\n"); rtolv.printYourself(); # endif for ( i = 1; i <= nroot; i++ ) { if ( rtolv.at(i) > rtol ) { goto label400; } } fprintf(outStream, "SubspaceIteration :: solveYourselfAt: Convergence reached for RTOL=%20.15f", rtol); break; label400: if ( nite >= nitem ) { fprintf(outStream, " SubspaceIteration :: solveYourselfAt: Convergence not reached in %d iteration - using current values", nitem); break; } for ( i = 1; i <= nc; i++ ) { d.at(i) = eigv.at(i); // label 410 and 440 } continue; } while ( 1 ); // compute eigenvectors for ( j = 1; j <= nc; j++ ) { for ( k = 1; k <= nn; k++ ) { tt.at(k) = r.at(k, j); } a.backSubstitutionWith(tt); for ( k = 1; k <= nn; k++ ) { r.at(k, j) = tt.at(k); // (r = xbar) } } // one cad add a normalization of eigen-vectors here for ( i = 1; i <= nroot; i++ ) { _eigv.at(i) = eigv.at(i); for ( j = 1; j <= nn; j++ ) { _r.at(j, i) = r.at(j, i); } } solved = 1; return NM_Success; }