2 #include "NNLS_solver.h" 3 #include "helper_functions.h" 9 const dealii::ParameterHandler ¶meter_handler_input,
10 const Epetra_CrsMatrix &A,
14 parameter_handler_input,
26 const dealii::ParameterHandler ¶meter_handler_input,
27 const Epetra_CrsMatrix &A,
28 const bool is_input_A_matrix_transposed,
32 parameter_handler_input,
34 is_input_A_matrix_transposed,
44 const dealii::ParameterHandler ¶meter_handler_input,
45 const Epetra_CrsMatrix &A,
50 parameter_handler_input,
62 const dealii::ParameterHandler ¶meter_handler_input,
63 const Epetra_CrsMatrix &A,
64 const bool is_input_A_matrix_transposed,
69 parameter_handler_input,
71 is_input_A_matrix_transposed,
81 const dealii::ParameterHandler ¶meter_handler_input,
82 const Epetra_CrsMatrix &A,
89 parameter_handler_input,
101 const dealii::ParameterHandler ¶meter_handler_input,
102 const Epetra_CrsMatrix &A,
103 const bool is_input_A_matrix_transposed,
104 Epetra_MpiComm &Comm,
110 parameter_handler_input,
112 is_input_A_matrix_transposed,
122 const dealii::ParameterHandler ¶meter_handler_input,
123 const Epetra_CrsMatrix &A,
124 const bool is_input_A_matrix_transposed,
125 Epetra_MpiComm &Comm,
134 A_((Comm.NumProc() == 1) ? transpose_matrix_on_single_core(A, is_input_A_matrix_transposed) : allocate_matrix_to_single_core(A, is_input_A_matrix_transposed)),
135 b_((Comm.NumProc() == 1) ? b : allocate_vector_to_single_core(b)),
137 multi_x_((is_input_A_matrix_transposed) ? A.RowMap(): A.ColMap()),
140 Z(
A_.NumGlobalCols()),
141 P(
A_.NumGlobalCols()),
146 index_set = Eigen::VectorXd::LinSpaced(
A_.NumGlobalCols(), 0,
A_.NumGlobalCols() -1);
155 for(
int i = 0; i < P_mat.NumMyCols(); i++){
156 int globalRow = P_mat.GRID(i);
158 P_mat.InsertGlobalValues(globalRow, 1, &posOne , &i);
167 std::vector<int> colMap(
A_.NumGlobalCols());
169 for(
int j = 0; j <
A_.NumGlobalCols(); j++){
172 colMap[idx] = numCol;
178 for(
int i =0; i <
A_.NumGlobalRows(); i++){
179 double *row =
new double[
A_.NumGlobalCols()];
181 const int globalRow =
A_.GRID(i);
182 A_.ExtractGlobalRowCopy(globalRow,
A_.NumGlobalCols(), numE , row);
183 for(
int j = 0; j <
A_.NumGlobalCols(); j++){
185 P_mat.InsertGlobalValues(i, 1, &row[j] , &colMap[j]);
195 std::vector<int> colMap(
A_.NumGlobalCols());
197 for(
int j = 0; j <
x_.MyLength(); j++){
200 colMap[idx] = numCol;
204 for(
int j = 0; j <
x_.MyLength(); j++){
206 x_[j] = temp[colMap[j]];
213 std::vector<int> colMap(
A_.NumGlobalCols());
215 for(
int j = 0; j <
x_.MyLength(); j++){
218 colMap[idx] = numCol;
222 for(
int j = 0; j <
x_.MyLength(); j++){
224 x_[j] += alpha*(temp[colMap[j]] -
x_[j]);
248 const int rank = this->
Comm_.MyPID();
252 Epetra_CrsMatrix AtA(Epetra_DataAccess::Copy,
A_.ColMap(),
A_.NumMyCols());
253 EpetraExt::MatrixMatrix::Multiply(
A_,
true,
A_,
false, AtA);
255 Epetra_Vector Atb (
A_.ColMap());
256 A_.Multiply(
true,
b_, Atb);
258 Epetra_Vector AtAx (
A_.ColMap());
259 Epetra_Vector Ax (
A_.RowMap());
260 Epetra_MultiVector gradient (
A_.ColMap(), 1);
261 Epetra_MultiVector residual (
A_.RowMap(), 1);
262 Eigen::VectorXd grad_eig (gradient.GlobalLength());
263 Epetra_Vector grad_col (
A_.ColMap());
272 AtA.Multiply(
false,
x_, AtAx);
274 gradient.Update(-1.0, AtAx, 1.0);
276 grad_col = *gradient(0);
277 for(
int i = 0; i < gradient.MyLength() ; ++i){
278 grad_eig[i] = grad_col[i];
284 int argmaxGradient = -1;
287 maxGradient = grad_eig(
index_set.tail(numActive)).maxCoeff(&argmaxGradient);
289 MPI_Bcast(&maxGradient,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
291 MPI_Bcast(&argmaxGradient,1, MPI_INT,0,MPI_COMM_WORLD);
293 A_.Multiply(
false,
x_, Ax);
294 residual.Update(-1.0, Ax, 1.0);
296 residual.Norm2(normRes);
304 if (maxGradient < all_parameters->hyper_reduction_param.NNLS_tol){
305 std::cout <<
"Exited due to Gradient Criteria" << std::endl;
306 std::cout <<
"Norm-2 of b" << std::endl;
307 std::cout << normb[0] << std::endl;
308 std::cout <<
"Norm-2 of the residual (b-A*x)" << std::endl;
309 std::cout << normRes[0] << std::endl;
320 std::cout <<
"Exited due to Residual Criteria" << std::endl;
321 std::cout <<
"Norm-2 of b" << std::endl;
322 std::cout << normb[0] << std::endl;
323 std::cout <<
"Norm-2 of the residual (b-A*x)" << std::endl;
324 std::cout << normRes[0] << std::endl;
333 bool no_feasible_soln =
true;
334 while(no_feasible_soln){
341 Epetra_Map Map(
A_.NumGlobalRows(),(rank == 0) ?
A_.NumGlobalRows() : 0, 0,
Comm_);
343 Epetra_CrsMatrix P_mat(Epetra_DataAccess::Copy, Map,
numInactive_);
345 P_mat.FillComplete(ColMap, Map);
347 Epetra_Vector temp(P_mat.ColMap());
350 Epetra_CrsMatrix PtP(Epetra_DataAccess::Copy, P_mat.ColMap(), P_mat.NumMyCols());
351 EpetraExt::MatrixMatrix::Multiply(P_mat,
true, P_mat,
false, PtP);
353 Epetra_Vector Ptb (P_mat.ColMap());
354 P_mat.Multiply(
true,
b_, Ptb);
358 Epetra_LinearProblem problem(&P_mat, &temp, &
b_);
359 AztecOO solver(problem);
362 solver.SetAztecOption(AZ_conv, AZ_rhs);
363 solver.SetAztecOption( AZ_precond, AZ_Jacobi);
364 solver.SetAztecOption(AZ_output, AZ_none);
369 Epetra_LinearProblem problem(&PtP, &temp, &Ptb);
373 std::string SolverType =
"Klu";
374 std::unique_ptr<Amesos_BaseSolver> Solver(Factory.Create(SolverType, problem));
376 Teuchos::ParameterList List;
377 Solver->SetParameters(List);
378 Solver->SymbolicFactorization();
379 Solver->NumericFactorization();
385 bool feasible =
true;
386 double alpha = Eigen::NumTraits<Eigen::VectorXd::Scalar>::highest();
387 int infeasibleIdx = -1;
393 double t = -
x_[idx]/(temp[k] -
x_[idx]);
403 MPI_Bcast(&feasible,1,MPI_CXX_BOOL,0,MPI_COMM_WORLD);
404 MPI_Bcast(&infeasibleIdx, 1, MPI_INT,0,MPI_COMM_WORLD);
405 MPI_Bcast(&alpha,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
406 eigen_assert(feasible || 0 <= infeasibleIdx);
411 no_feasible_soln =
false;
std::vector< bool > Z
Vector of booleans representing the columns in the active set.
const dealii::ParameterHandler & parameter_handler
Parameter handler for storing the .prm file being ran.
void move_to_active_set(int idx)
Moves the column at idx into the active set (updating the index_set, Z, P, and numInactive_) ...
std::vector< bool > P
Vector of boolean representing the columns in the inactive set.
const bool is_input_A_matrix_transposed_
Files for the baseline physics.
int NNLS_max_iter
Maximum number of iterations for NNLS Solver.
Main parameter class that contains the various other sub-parameter classes.
const Epetra_CrsMatrix A_
Epetra Matrix A allocated to a single core.
bool iter_solver_
Boolean used for iterative solvers.
Epetra_MpiComm Comm_
Epetra Commuicator Object with MPI.
double NNLS_tol
Tolerance for NNLS Solver.
Eigen::VectorXd index_set
Eigen Vector of the index_set.
Epetra_Vector multi_x_
Epetra_Vector x, to be solved. Allocated to multiple cores.
void sub_into_x(Epetra_Vector &temp)
Replaces the entries with x with the values in temp.
int LS_iter_
Needed if the an iterative solver is used.
int iter_
Number of iterations in the NNLS solver.
void move_to_inactive_set(int idx)
Moves the column at idx into the inactive set (updating the index_set, Z, P, and numInactive_) ...
NNLSSolver(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input, const Epetra_CrsMatrix &A, Epetra_MpiComm &Comm, Epetra_Vector &b)
Default Constructor.
bool grad_exit_crit_
Boolean to use an exit Condition depending on maximum gradent.
int numInactive_
Number of inactive points.
double LS_tol_
Needed if the an iterative solver is used.
Epetra_Vector x_
Epetra Vector x, to be solved. Allocated to a single core.
bool solve()
Call to solve NNLS problem.
Epetra_Vector b_
Epetra Vector b allocated to a single core.
HyperReductionParam hyper_reduction_param
Contains parameters for Hyperreduction.
void positive_set_matrix(Epetra_CrsMatrix &P_mat)
Creates a matrix using the columns in A in the set P.
void epetra_permutation_matrix(Epetra_CrsMatrix &P_mat)
Creates square permutation matrix based off the active/inactive set, no longer in use...
void add_into_x(Epetra_Vector &temp, double alpha)
Adds the values of temp times alpha into the solution vector x.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.