int check(Epetra_RowMatrix& A, Epetra_RowMatrix & B, bool verbose) { int ierr = 0; EPETRA_TEST_ERR(!A.Comm().NumProc()==B.Comm().NumProc(),ierr); EPETRA_TEST_ERR(!A.Comm().MyPID()==B.Comm().MyPID(),ierr); EPETRA_TEST_ERR(!A.Filled()==B.Filled(),ierr); EPETRA_TEST_ERR(!A.HasNormInf()==B.HasNormInf(),ierr); EPETRA_TEST_ERR(!A.LowerTriangular()==B.LowerTriangular(),ierr); EPETRA_TEST_ERR(!A.Map().SameAs(B.Map()),ierr); EPETRA_TEST_ERR(!A.MaxNumEntries()==B.MaxNumEntries(),ierr); EPETRA_TEST_ERR(!A.NumGlobalCols64()==B.NumGlobalCols64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalDiagonals64()==B.NumGlobalDiagonals64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalNonzeros64()==B.NumGlobalNonzeros64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalRows64()==B.NumGlobalRows64(),ierr); EPETRA_TEST_ERR(!A.NumMyCols()==B.NumMyCols(),ierr); EPETRA_TEST_ERR(!A.NumMyDiagonals()==B.NumMyDiagonals(),ierr); EPETRA_TEST_ERR(!A.NumMyNonzeros()==B.NumMyNonzeros(),ierr); for (int i=0; i<A.NumMyRows(); i++) { int nA, nB; A.NumMyRowEntries(i,nA); B.NumMyRowEntries(i,nB); EPETRA_TEST_ERR(!nA==nB,ierr); } EPETRA_TEST_ERR(!A.NumMyRows()==B.NumMyRows(),ierr); EPETRA_TEST_ERR(!A.OperatorDomainMap().SameAs(B.OperatorDomainMap()),ierr); EPETRA_TEST_ERR(!A.OperatorRangeMap().SameAs(B.OperatorRangeMap()),ierr); EPETRA_TEST_ERR(!A.RowMatrixColMap().SameAs(B.RowMatrixColMap()),ierr); EPETRA_TEST_ERR(!A.RowMatrixRowMap().SameAs(B.RowMatrixRowMap()),ierr); EPETRA_TEST_ERR(!A.UpperTriangular()==B.UpperTriangular(),ierr); EPETRA_TEST_ERR(!A.UseTranspose()==B.UseTranspose(),ierr); int NumVectors = 5; { // No transpose case Epetra_MultiVector X(A.OperatorDomainMap(), NumVectors); Epetra_MultiVector YA1(A.OperatorRangeMap(), NumVectors); Epetra_MultiVector YA2(YA1); Epetra_MultiVector YB1(YA1); Epetra_MultiVector YB2(YA1); X.Random(); bool transA = false; A.SetUseTranspose(transA); B.SetUseTranspose(transA); A.Apply(X,YA1); A.Multiply(transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2,"A Multiply and A Apply", verbose),ierr); B.Apply(X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1,"A Multiply and B Multiply", verbose),ierr); B.Multiply(transA, X, YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2,"A Multiply and B Apply", verbose), ierr); } {// transpose case Epetra_MultiVector X(A.OperatorRangeMap(), NumVectors); Epetra_MultiVector YA1(A.OperatorDomainMap(), NumVectors); Epetra_MultiVector YA2(YA1); Epetra_MultiVector YB1(YA1); Epetra_MultiVector YB2(YA1); X.Random(); bool transA = true; A.SetUseTranspose(transA); B.SetUseTranspose(transA); A.Apply(X,YA1); A.Multiply(transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2, "A Multiply and A Apply (transpose)", verbose),ierr); B.Apply(X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1, "A Multiply and B Multiply (transpose)", verbose),ierr); B.Multiply(transA, X,YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2, "A Multiply and B Apply (transpose)", verbose),ierr); } Epetra_Vector diagA(A.RowMatrixRowMap()); EPETRA_TEST_ERR(A.ExtractDiagonalCopy(diagA),ierr); Epetra_Vector diagB(B.RowMatrixRowMap()); EPETRA_TEST_ERR(B.ExtractDiagonalCopy(diagB),ierr); EPETRA_TEST_ERR(checkMultiVectors(diagA,diagB, "ExtractDiagonalCopy", verbose),ierr); Epetra_Vector rowA(A.RowMatrixRowMap()); EPETRA_TEST_ERR(A.InvRowSums(rowA),ierr); Epetra_Vector rowB(B.RowMatrixRowMap()); EPETRA_TEST_ERR(B.InvRowSums(rowB),ierr) EPETRA_TEST_ERR(checkMultiVectors(rowA,rowB, "InvRowSums", verbose),ierr); Epetra_Vector colA(A.RowMatrixColMap()); EPETRA_TEST_ERR(A.InvColSums(colA),ierr); Epetra_Vector colB(B.RowMatrixColMap()); EPETRA_TEST_ERR(B.InvColSums(colB),ierr); EPETRA_TEST_ERR(checkMultiVectors(colA,colB, "InvColSums", verbose),ierr); EPETRA_TEST_ERR(checkValues(A.NormInf(), B.NormInf(), "NormInf before scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(A.NormOne(), B.NormOne(), "NormOne before scaling", verbose),ierr); EPETRA_TEST_ERR(A.RightScale(colA),ierr); EPETRA_TEST_ERR(B.RightScale(colB),ierr); EPETRA_TEST_ERR(A.LeftScale(rowA),ierr); EPETRA_TEST_ERR(B.LeftScale(rowB),ierr); EPETRA_TEST_ERR(checkValues(A.NormInf(), B.NormInf(), "NormInf after scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(A.NormOne(), B.NormOne(), "NormOne after scaling", verbose),ierr); vector<double> valuesA(A.MaxNumEntries()); vector<int> indicesA(A.MaxNumEntries()); vector<double> valuesB(B.MaxNumEntries()); vector<int> indicesB(B.MaxNumEntries()); return(0); for (int i=0; i<A.NumMyRows(); i++) { int nA, nB; EPETRA_TEST_ERR(A.ExtractMyRowCopy(i, A.MaxNumEntries(), nA, &valuesA[0], &indicesA[0]),ierr); EPETRA_TEST_ERR(B.ExtractMyRowCopy(i, B.MaxNumEntries(), nB, &valuesB[0], &indicesB[0]),ierr); EPETRA_TEST_ERR(!nA==nB,ierr); for (int j=0; j<nA; j++) { double curVal = valuesA[j]; int curIndex = indicesA[j]; bool notfound = true; int jj = 0; while (notfound && jj< nB) { if (!checkValues(curVal, valuesB[jj])) notfound = false; jj++; } EPETRA_TEST_ERR(notfound, ierr); vector<int>::iterator p = find(indicesB.begin(),indicesB.end(),curIndex); // find curIndex in indicesB EPETRA_TEST_ERR(p==indicesB.end(), ierr); } } if (verbose) cout << "RowMatrix Methods check OK" << endl; return (ierr); }
void AZOO_iterate(double * xsolve, double * b, int * options, double * params, double * status, int *proc_config, AZ_MATRIX * Amat, AZ_PRECOND *precond, struct AZ_SCALING *scaling) { (void)precond; (void)scaling; bool verbose = (options[AZ_output]!=AZ_none); // Print info unless all output is turned off Epetra_Comm * comm; Epetra_BlockMap * map; Epetra_RowMatrix * A; Epetra_Vector * px; Epetra_Vector * pb; int * global_indices; int ierr = Aztec2Petra(proc_config, Amat, xsolve, b, comm, map, A, px, pb, &global_indices); if (ierr!=0) { cerr << "Error detected in Aztec2Petra. Value = " << ierr << endl; exit(1); } Epetra_LinearProblem problem(A, px, pb); Epetra_Vector * leftScaleVec = 0; Epetra_Vector * rightScaleVec = 0; bool doRowScaling = false; bool doColScaling = false; if ((options[AZ_scaling]==AZ_Jacobi) || options[AZ_scaling]==AZ_BJacobi) { doRowScaling = true; leftScaleVec = new Epetra_Vector(*map); A->ExtractDiagonalCopy(*leftScaleVec); // Extract diagonal of matrix leftScaleVec->Reciprocal(*leftScaleVec); // invert it } else if (options[AZ_scaling]==AZ_row_sum) { doRowScaling = true; leftScaleVec = new Epetra_Vector(*map); A->InvRowSums(*leftScaleVec); } else if (options[AZ_scaling]==AZ_sym_diag) { doRowScaling = true; doColScaling = true; leftScaleVec = new Epetra_Vector(*map); A->ExtractDiagonalCopy(*leftScaleVec); // Extract diagonal of matrix int length = leftScaleVec->MyLength(); for (int i=0; i<length; i++) (*leftScaleVec)[i] = sqrt(fabs((*leftScaleVec)[i])); // Take its sqrt rightScaleVec = leftScaleVec; // symmetric, so left and right the same leftScaleVec->Reciprocal(*leftScaleVec); // invert it } else if (options[AZ_scaling]==AZ_sym_row_sum) { doRowScaling = true; doColScaling = true; leftScaleVec = new Epetra_Vector(*map); A->InvRowSums(*leftScaleVec); int length = leftScaleVec->MyLength(); for (int i=0; i<length; i++) (*leftScaleVec)[i] = sqrt(fabs((*leftScaleVec)[i])); // Take its sqrt rightScaleVec = leftScaleVec; // symmetric, so left and right the same } if ((doRowScaling || doColScaling) && verbose) { double norminf = A->NormInf(); double normone = A->NormOne(); if (comm->MyPID()==0) cout << "\n Inf-norm of A before scaling = " << norminf << "\n One-norm of A before scaling = " << normone<< endl << endl; } if (doRowScaling) problem.LeftScale(*leftScaleVec); if (doColScaling) problem.RightScale(*rightScaleVec); if ((doRowScaling || doColScaling) && verbose) { double norminf = A->NormInf(); double normone = A->NormOne(); if (comm->MyPID()==0) cout << "\n Inf-norm of A after scaling = " << norminf << "\n One-norm of A after scaling = " << normone << endl << endl; } AztecOO solver(problem); solver.SetAllAztecParams(params); // set all AztecOO params with user-provided params solver.SetAllAztecOptions(options); // set all AztecOO options with user-provided options solver.CheckInput(); solver.SetAztecOption(AZ_scaling, AZ_none); // Always must have scaling off solver.Iterate(options[AZ_max_iter], params[AZ_tol]); solver.GetAllAztecStatus(status); if (doColScaling) { rightScaleVec->Reciprocal(*rightScaleVec); problem.RightScale(*rightScaleVec); } if (doRowScaling) { leftScaleVec->Reciprocal(*leftScaleVec); problem.LeftScale(*leftScaleVec); } if ((rightScaleVec!=0) && (rightScaleVec!=leftScaleVec)) delete rightScaleVec; if (leftScaleVec!=0) delete leftScaleVec; delete pb; // These are all objects created here and we have to delete them delete px; delete A; delete map; delete comm; if (global_indices!=0) AZ_free((void *) global_indices); // Note: we used a special version of free here return; }