int power_method(bool TransA, Epetra_RowMatrix& A, Epetra_Vector& q, Epetra_Vector& z0, Epetra_Vector& resid, double* lambda, int niters, double tolerance, bool verbose) { // Fill z with random Numbers Epetra_Vector z(z0); // variable needed for iteration double normz, residual; int ierr = 1; for(int iter = 0; iter < niters; iter++) { z.Norm2(&normz); // Compute 2-norm of z q.Scale(1.0/normz, z); A.Multiply(TransA, q, z); // Compute z = A*q // SEGFAULT HAPPENS HERE q.Dot(z, lambda); // Approximate maximum eigenvaluE if(iter%100==0 || iter+1==niters) { resid.Update(1.0, z, -(*lambda), q, 0.0); // Compute A*q - lambda*q resid.Norm2(&residual); if(verbose) cout << "Iter = " << iter << " Lambda = " << *lambda << " Residual of A*q - lambda*q = " << residual << endl; } if(residual < tolerance) { ierr = 0; break; } } return(ierr); }
int powerMethod (double & lambda, Epetra_CrsMatrix& A, const int niters, const double tolerance, const bool verbose) { // In the power iteration, z = A*q. Thus, q must be in the domain // of A, and z must be in the range of A. The residual vector is of // course in the range of A. Epetra_Vector q (A.OperatorDomainMap ()); Epetra_Vector z (A.OperatorRangeMap ()); Epetra_Vector resid (A.OperatorRangeMap ()); Epetra_Flops* counter = A.GetFlopCounter(); if (counter != 0) { q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); } // Initialize the starting vector z with random data. z.Random(); double normz, residual; int ierr = 1; for (int iter = 0; iter < niters; ++iter) { z.Norm2 (&normz); // normz := ||z||_2 q.Scale (1.0/normz, z); // q := z / normz A.Multiply(false, q, z); // z := A * q q.Dot(z, &lambda); // lambda := dot (q, z) // Compute the residual vector and display status output every // 100 iterations, or if we have reached the maximum number of // iterations. if (iter % 100 == 0 || iter + 1 == niters) { resid.Update (1.0, z, -lambda, q, 0.0); // resid := A*q - lambda*q resid.Norm2 (&residual); // residual := ||resid||_2 if (verbose) cout << "Iter = " << iter << " Lambda = " << lambda << " Residual of A*q - lambda*q = " << residual << endl; } if (residual < tolerance) { // We've converged! ierr = 0; break; } } return ierr; }