bool FiniteDifferenceColoringWithUpdate::differenceProbe(const Epetra_Vector& x, Epetra_CrsMatrix& jac,const Epetra_MapColoring& colors){ // Allocate space for perturbation, get column version of x for scaling Epetra_Vector xp(x); Epetra_Vector *xcol; int N=jac.NumMyRows(); if(jac.ColMap().SameAs(x.Map())) xcol=const_cast<Epetra_Vector*>(&x); else{ xcol=new Epetra_Vector(jac.ColMap(),true);//zeros out by default xcol->Import(x,*jac.Importer(),InsertAdd); } // Counters for probing diagnostics double tmp,probing_error_lower_bound=0.0,jc_norm=0.0; // Grab coloring info (being very careful to ignore color 0) int Ncolors=colors.MaxNumColors()+1; int num_c0_global,num_c0_local=colors.NumElementsWithColor(0); colors.Comm().MaxAll(&num_c0_local,&num_c0_global,1); if(num_c0_global>0) Ncolors--; if(Ncolors==0) return false; // Pointers for Matrix Info int entries, *indices; double *values; // NTS: Fix me if ( diffType == Centered ) exit(1); double scaleFactor = 1.0; if ( diffType == Backward ) scaleFactor = -1.0; // Compute RHS at initial solution computeF(x,fo,NOX::Epetra::Interface::Required::FD_Res); /* Probing, vector by vector since computeF does not have a MultiVector interface */ // Assume that anything with Color 0 gets ignored. for(int j=1;j<Ncolors;j++){ xp=x; for(int i=0;i<N;i++){ if(colors[i]==j) xp[i] += scaleFactor*(alpha*abs(x[i])+beta); } computeF(xp, fp, NOX::Epetra::Interface::Required::FD_Res); // Do the subtraction to estimate the Jacobian (w/o including step length) Jc.Update(1.0, fp, -1.0, fo, 0.0); // Relative error in probing if(use_probing_diags){ Jc.Norm2(&tmp); jc_norm+=tmp*tmp; } for(int i=0;i<N;i++){ // Skip for uncolored row/columns, else update entries if(colors[i]==0) continue; jac.ExtractMyRowView(i,entries,values,indices); for(int k=0;k<jac.NumMyEntries(i);k++){ if(colors[indices[k]]==j){ values[k]=Jc[i] / (scaleFactor*(alpha*abs((*xcol)[indices[k]])+beta)); // If probing diagnostics are on, zero out the entries as they are used if(use_probing_diags) Jc[i]=0.0; break;// Only one value per row... } } } if(use_probing_diags){ Jc.Norm2(&tmp); probing_error_lower_bound+=tmp*tmp; } } // If diagnostics are requested, output Frobenius norm lower bound if(use_probing_diags && !x.Comm().MyPID()) printf("Probing Error Lower Bound (Frobenius) abs = %6.4e rel = %6.4e\n",sqrt(probing_error_lower_bound),sqrt(probing_error_lower_bound)/sqrt(jc_norm)); // Cleanup if(!jac.ColMap().SameAs(x.Map())) delete xcol; return true; }