MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AbstractLinAlgPack_BasisSystemPermDirectSparse.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
52 #include "Teuchos_Assert.hpp"
53 #include "Teuchos_dyn_cast.hpp"
54 
55 namespace AbstractLinAlgPack {
56 
58  const direct_solver_ptr_t& direct_solver
59  )
61  Teuchos::rcp(
62  new Teuchos::AbstractFactoryStd<MatrixSymOp,MatrixSymPosDefCholFactor>()) // D'*D
63  ,Teuchos::rcp(
64  new Teuchos::AbstractFactoryStd<MatrixSymOpNonsing,MatrixSymPosDefCholFactor>()) // S
65  )
66 {
67  this->initialize(direct_solver);
68 }
69 
71  const direct_solver_ptr_t& direct_solver
72  )
73 {
74  direct_solver_ = direct_solver;
75  n_ = m_ = r_ = Gc_nz_ = 0;
76  init_var_inv_perm_.resize(0);
77  init_equ_inv_perm_.resize(0);
84 }
85 
86 // Overridden from BasisSystem
87 
90 {
91  return Teuchos::rcp(
93  );
94 }
95 
98 {
99  return Teuchos::rcp(
101  );
102 }
103 
106 {
107  return Teuchos::rcp(
109  );
110 }
111 
113 {
114  return var_dep_;
115 }
116 
118 {
119  return var_indep_;
120 }
121 
123 {
124  return equ_decomp_;
125 }
126 
128 {
129  return equ_undecomp_;
130 }
131 
133  const MatrixOp &Gc
135  ,MatrixOp *D
136  ,MatrixOp *GcUP
137  ,EMatRelations mat_rel
138  ,std::ostream *out
139  ) const
140 {
141  using Teuchos::dyn_cast;
142  if(out)
143  *out << "\nUsing a direct sparse solver to update basis ...\n";
144  const size_type
145  n = Gc.rows(),
146  m = Gc.cols();
147 #ifdef TEUCHOS_DEBUG
148  const size_type Gc_rows = n, Gc_cols = m, Gc_nz = Gc.nz();
150  Gc_rows != n_ || Gc_cols != m_ || Gc_nz != Gc_nz_, std::invalid_argument
151  ,"BasisSystemPermDirectSparse::set_basis(...) : Error, "
152  "This matrix object is not compatible with last call to set_basis() or select_basis()!" );
154  C == NULL, std::invalid_argument
155  ,"BasisSystemPermDirectSparse::set_basis(...) : Error!" );
156 #endif
157  // Get the aggregate matrix object for Gc
158  const MatrixPermAggr
159  &Gc_pa = dyn_cast<const MatrixPermAggr>(Gc);
160  // Get the basis matrix object from the aggregate or allocate one
162  &C_aggr = dyn_cast<MatrixOpNonsingAggr>(*C);
164  C_bm = get_basis_matrix(C_aggr);
165  // Setup the encapulated convert-to-sparse matrix object
167  set_A_mctse( n, m, Gc_pa, &A_mctse );
168  // Refactor this basis (it had better be full rank)!
169  try {
170  direct_solver_->factor(
171  A_mctse
172  ,C_bm.get()
173  ,Teuchos::null // Same factorization structure as before
174  ,out
175  );
176  }
177  catch(const DirectSparseSolver::FactorizationFailure& excpt) {
178  if(out)
179  *out << "\nCurrent basis is singular : " << excpt.what() << std::endl
180  << "Throwing SingularBasis exception to client ...\n";
182  true, SingularBasis
183  ,"BasisSystemPermDirectSparse::update_basis(...) : Error, the current basis "
184  "is singular : " << excpt.what() );
185  }
186  // Update the aggregate basis matrix and compute the auxiliary projected matrices
187  update_basis_and_auxiliary_matrices( Gc, C_bm, &C_aggr, D, GcUP );
188 }
189 
190 // Overridded from BasisSystemPerm
191 
194 {
195  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement using PermutationSerial
196  return Teuchos::null;
197 }
198 
201 {
202  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement using PermutationSerial
203  return Teuchos::null;
204 }
205 
208 {
209  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement using PermutationSerial
210  return Teuchos::null;
211 }
212 
214  const Permutation &P_var
215  ,const Range1D &var_dep
216  ,const Permutation *P_equ
217  ,const Range1D *equ_decomp
218  ,const MatrixOp &Gc
220  ,MatrixOp *D
221  ,MatrixOp *GcUP
222  ,EMatRelations mat_rel
223  ,std::ostream *out
224  )
225 {
226  using Teuchos::dyn_cast;
227  if(out)
228  *out << "\nUsing a direct sparse solver to set a new basis ...\n";
229  const size_type
230  n = Gc.rows(),
231  m = Gc.cols();
232 #ifdef TEUCHOS_DEBUG
233  const size_type Gc_rows = n, Gc_cols = m, Gc_nz = Gc.nz();
235  P_equ == NULL || equ_decomp == NULL, std::invalid_argument
236  ,"BasisSystemPermDirectSparse::set_basis(...) : Error!" );
238  C == NULL, std::invalid_argument
239  ,"BasisSystemPermDirectSparse::set_basis(...) : Error!" );
240 #endif
241  // Get the aggreate matrix object for Gc
242  const MatrixPermAggr
243  &Gc_pa = dyn_cast<const MatrixPermAggr>(Gc);
244  // Get the basis matrix object from the aggregate or allocate one
246  &C_aggr = dyn_cast<MatrixOpNonsingAggr>(*C);
248  C_bm = get_basis_matrix(C_aggr);
249  // Get at the concreate permutation vectors
250  const PermutationSerial
251  &P_var_s = dyn_cast<const PermutationSerial>(P_var),
252  &P_equ_s = dyn_cast<const PermutationSerial>(*P_equ);
253  // Setup the encapulated convert-to-sparse matrix object
254  init_var_inv_perm_ = *P_var_s.inv_perm();
256  init_equ_inv_perm_ = *P_equ_s.inv_perm();
259  set_A_mctse( n, m, Gc_pa, &A_mctse );
260  // Analyze and factor this basis (it had better be full rank)!
261  IVector row_perm_ds, col_perm_ds; // Must store these even though we don't want them!
262  size_type rank = 0;
263  direct_solver_->analyze_and_factor(
264  A_mctse
265  ,&row_perm_ds
266  ,&col_perm_ds
267  ,&rank
268  ,C_bm.get()
269  ,out
270  );
271  if( rank < var_dep.size() ) {
272  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Throw an exception with a good error message!
273  }
274  // Update the rest of the basis stuff
275  do_some_basis_stuff(Gc,var_dep,*equ_decomp,C_bm,&C_aggr,D,GcUP);
276 }
277 
279  const Vector *nu
280  ,MatrixOp *Gc
281  ,Permutation *P_var
282  ,Range1D *var_dep
283  ,Permutation *P_equ
284  ,Range1D *equ_decomp
286  ,MatrixOp *D
287  ,MatrixOp *GcUP
288  ,EMatRelations mat_rel
289  ,std::ostream *out
290  )
291 {
292  using Teuchos::dyn_cast;
293  if(out)
294  *out << "\nUsing a direct sparse solver to select a new basis ...\n";
295 #ifdef TEUCHOS_DEBUG
296  // Validate input
297  const char msg_err_head[] = "BasisSystemPermDirectSparse::set_basis(...) : Error!";
299  Gc == NULL, std::invalid_argument
300  ,msg_err_head << " Must have equality constriants in this current implementation! " );
301 #endif
302  const size_type
303  n = Gc->rows(),
304  m = Gc->cols();
305 #ifdef TEUCHOS_DEBUG
306  // Validate input
307  const size_type Gc_rows = Gc->rows(), Gc_cols = Gc->cols(), Gc_nz = Gc->nz();
309  P_var == NULL || var_dep == NULL, std::invalid_argument, msg_err_head );
311  P_equ == NULL || equ_decomp == NULL, std::invalid_argument, msg_err_head );
313  C == NULL, std::invalid_argument, msg_err_head );
314 #endif
315  // Get the aggreate matrix object for Gc
317  &Gc_pa = dyn_cast<MatrixPermAggr>(*Gc);
318  // Get the basis matrix object from the aggregate or allocate one
320  &C_aggr = dyn_cast<MatrixOpNonsingAggr>(*C);
322  C_bm = get_basis_matrix(C_aggr);
323  // Setup the encapulated convert-to-sparse matrix object
324  // ToDo: Use nu to exclude variables that are at a bound!
325  init_var_rng_ = Range1D(1,n);
326  init_var_inv_perm_.resize(0); // Not used since above is full range
327  init_equ_rng_ = Range1D(1,m);
328  init_equ_inv_perm_.resize(0); // Not used since above is full range
330  set_A_mctse( n, m, Gc_pa, &A_mctse );
331  // Analyze and factor this basis (it had better be full rank)!
333  var_perm_ds = Teuchos::rcp(new IVector),
334  equ_perm_ds = Teuchos::rcp(new IVector);
335  size_type rank = 0;
336  direct_solver_->analyze_and_factor(
337  A_mctse
338  ,equ_perm_ds.get()
339  ,var_perm_ds.get()
340  ,&rank
341  ,C_bm.get()
342  ,out
343  );
344  if( rank == 0 ) {
345  TEUCHOS_TEST_FOR_EXCEPT( !( rank == 0 ) ); // ToDo: Throw exception with good error message!
346  }
347  // Return the selected basis
348  // ToDo: Use var_perm_ds and equ_perm_ds together with nu to
349  // get the overall permuations for all of the variables.
350  PermutationSerial
351  &P_var_s = dyn_cast<PermutationSerial>(*P_var),
352  &P_equ_s = dyn_cast<PermutationSerial>(*P_equ);
353  // Create the overall permutations to set to the permutation matrices!
354  *var_dep = Range1D(1,rank);
355  P_var_s.initialize( var_perm_ds, Teuchos::null );
356  *equ_decomp = Range1D(1,rank);
357  P_equ_s.initialize( equ_perm_ds, Teuchos::null );
358  // Setup Gc_aggr with Gc_perm
359  const int num_row_part = 2;
360  const int num_col_part = 2;
361  const index_type row_part[3] = { 1, rank, n+1 };
362  const index_type col_part[3] = { 1, rank, m+1 };
363  Gc_pa.initialize(
364  Gc_pa.mat_orig()
365  ,Teuchos::rcp(new PermutationSerial(var_perm_ds,Teuchos::null)) // var_perm_ds reuse is okay!
366  ,Teuchos::rcp(new PermutationSerial(equ_perm_ds,Teuchos::null)) // equ_perm_ds resue is okay!
367  ,Gc_pa.mat_orig()->perm_view(
368  P_var,row_part,num_row_part
369  ,P_equ,col_part,num_col_part
370  )
371  );
372  // Update the rest of the basis stuff
373  do_some_basis_stuff(*Gc,*var_dep,*equ_decomp,C_bm,&C_aggr,D,GcUP);
374 }
375 
376 // private
377 
380 {
381  using Teuchos::dyn_cast;
383  if( C_aggr.mns().get() ) {
384  C_bm = Teuchos::rcp_dynamic_cast<DirectSparseSolver::BasisMatrix>(
385  Teuchos::rcp_const_cast<MatrixNonsing>(C_aggr.mns() ) );
386  if(C_bm.get() == NULL)
387  dyn_cast<const DirectSparseSolver::BasisMatrix>(*C_aggr.mns()); // Throws exception!
388  }
389  else {
390  C_bm = direct_solver_->basis_matrix_factory()->create();
391  }
392  return C_bm;
393 }
394 
396  size_type n
397  ,size_type m
398  ,const MatrixPermAggr &Gc_pa
400  ) const
401 {
402  A_mctse->initialize(
403  Teuchos::rcp_dynamic_cast<const MatrixExtractSparseElements>(Gc_pa.mat_orig())
404  ,Teuchos::rcp( init_var_rng_.size() < n ? &init_var_inv_perm_ : NULL, false )
406  ,Teuchos::rcp( init_equ_rng_.size() < m ? &init_equ_inv_perm_ : NULL, false )
409  );
410 }
411 
413  const MatrixOp& Gc
415  ,MatrixOpNonsingAggr *C_aggr
416  ,MatrixOp* D, MatrixOp* GcUP
417  ) const
418 {
419  using Teuchos::dyn_cast;
420  // Initialize the aggregate basis matrix object.
421  C_aggr->initialize(
424  ,C_bm
426  );
427  // Compute the auxiliary projected matrices
428  // Get the concreate type of the direct sensitivity matrix (if one was passed in)
429  if( D ) {
431  TEUCHOS_TEST_FOR_EXCEPT( !( D ) ); // ToDo: Throw exception!
432  // D = -inv(C) * N
433  D_mvd->initialize(var_dep_.size(),var_indep_.size());
435  D_mvd, -1.0, *C_bm, BLAS_Cpp::no_trans
436  ,*Gc.sub_view(var_indep_,equ_decomp_),BLAS_Cpp::trans // N = Gc(var_indep,equ_decomp)'
437  );
438  }
439  if( GcUP ) {
440  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement!
441  }
442 }
443 
445  const MatrixOp& Gc
446  ,const Range1D& var_dep, const Range1D& equ_decomp
448  ,MatrixOpNonsingAggr *C_aggr
449  ,MatrixOp* D, MatrixOp* GcUP
450  )
451 {
452  const size_type
453  n = Gc.rows(),
454  m = Gc.cols();
455  // Set the ranges
456  var_dep_ = var_dep;
457  var_indep_ = ( var_dep.size() == n
459  : ( var_dep.lbound() == 1
460  ? Range1D(var_dep.size()+1,n)
461  : Range1D(1,n-var_dep.size()) ) );
463  equ_undecomp_ = ( equ_decomp.size() == m
465  : ( equ_decomp.lbound() == 1
466  ? Range1D(equ_decomp.size()+1,m)
467  : Range1D(1,m-equ_decomp.size()) ) );
468  // Set the basis system dimensions
469  n_ = n;
470  m_ = m;
471  r_ = var_dep.size();
472  Gc_nz_ = Gc.nz();
473  // Update the aggregate basis matrix and compute the auxiliary projected matrices
474  update_basis_and_auxiliary_matrices( Gc, C_bm, C_aggr, D, GcUP );
475 }
476 
477 } // end namespace AbstractLinAlgPack
virtual mat_ptr_t sub_view(const Range1D &row_rng, const Range1D &col_rng) const
Create a transient constant sub-matrix view of this matrix (if supported).
virtual size_type nz() const
Return the number of nonzero elements in the matrix.
void initialize(const size_type rows, const size_type cols)
Call this->initialize(v,v_release) with an allocated DenseLinAlgPack::DVector object.
Abstract interface for immutable, finite dimensional, coordinate vectors {abstract}.
Abstract base class for all polymorphic symmetrix nonsingular matrices that can be used to compute ma...
MultiVectorMutable "Adapter" subclass for DenseLinAlgPack::DMatrixSlice or DenseLinAlgPack::DMatrix o...
void do_some_basis_stuff(const MatrixOp &Gc, const Range1D &var_dep, const Range1D &equ_decomp, const Teuchos::RCP< DirectSparseSolver::BasisMatrix > &C_bm, MatrixOpNonsingAggr *C_aggr, MatrixOp *D, MatrixOp *GcUP)
BasisSystemPermDirectSparse(const direct_solver_ptr_t &direct_solver=Teuchos::null)
Calls this->initialize()
void initialize(const direct_solver_ptr_t &direct_solver)
Initialize given a direct sparse solver object.
Abstract class for objects that represent the factorized matrix and can be used to solve for differen...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Index size() const
Return the size of the range (ubound() - lbound() + 1)
Aggregate matrix class for a matrix and its permuted view.
T * get() const
void initialize(const mwo_ptr_t &mwo, BLAS_Cpp::Transp mwo_trans, const mns_ptr_t &mns, BLAS_Cpp::Transp mns_trans)
Initialize.
void update_basis_and_auxiliary_matrices(const MatrixOp &Gc, const Teuchos::RCP< DirectSparseSolver::BasisMatrix > &C_bm, MatrixOpNonsingAggr *C_aggr, MatrixOp *D, MatrixOp *GcUP) const
Transposed.
Interface adding operations specific for a symmetric matrix {abstract}.
Not transposed.
void initialize(const mat_ptr_t &mat_orig, const perm_ptr_t &row_perm, const perm_ptr_t &col_perm, const mat_ptr_t &mat_perm)
Initialize.
virtual size_type cols() const
Return the number of columns in the matrix.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
. One-based subregion index range class.
T_To & dyn_cast(T_From &from)
std::ostream * out
Teuchos::RCP< DirectSparseSolver::BasisMatrix > get_basis_matrix(MatrixOpNonsingAggr &C_aggr) const
Base class for all matrices that support basic matrix operations.
static const Range1D Invalid
Range1D(INVALID)
Index lbound() const
Return lower bound of the range.
Abstract interface to permutation matrices.
void set_A_mctse(size_type n, size_type m, const MatrixPermAggr &Gc_pa, MatrixConvertToSparseEncap *A_mctse) const
void set_basis(const Permutation &P_var, const Range1D &var_dep, const Permutation *P_equ, const Range1D *equ_decomp, const MatrixOp &Gc, MatrixOpNonsing *C, MatrixOp *D, MatrixOp *GcUP, EMatRelations mat_rel, std::ostream *out)
Interface for setting and selecting a basis from the Jacobian from a set of equations.
Abstract base class for all nonsingular polymorphic matrices that can be used to compute matrix-vecto...
void M_StInvMtM(MatrixOp *m_lhs, value_type alpha, const MatrixNonsing &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const MatrixOp &mwo_rhs2, BLAS_Cpp::Transp trans_rhs2)
m_lhs = alpha * inv(op(mwo_rhs1)) * op(mwo_rhs2) (right)
virtual size_type rows() const
Return the number of rows in the matrix.
void select_basis(const Vector *nu, MatrixOp *Gc, Permutation *P_var, Range1D *var_dep, Permutation *P_equ, Range1D *equ_decomp, MatrixOpNonsing *C, MatrixOp *D, MatrixOp *GcUP, EMatRelations mat_rel, std::ostream *out)
virtual mat_ptr_t perm_view(const Permutation *P_row, const index_type row_part[], int num_row_part, const Permutation *P_col, const index_type col_part[], int num_col_part) const
Create a permuted view: M_perm = P_row' * M * P_col.
void initialize(const mese_ptr_t &mese, const i_vector_ptr_t &inv_row_perm, const Range1D &row_rng, const i_vector_ptr_t &inv_col_perm, const Range1D &col_rng, const BLAS_Cpp::Transp mese_trans, const value_type alpha=1.0)
Initialize a permuted view of a sparse matrix.
Abstract base class for all nonsingular polymorphic matrices that can solve for linear system with bu...
Sparse conversion subclass based on views of a MatrixExtractSparseElements object.
int n
void update_basis(const MatrixOp &Gc, MatrixOpNonsing *C, MatrixOp *D, MatrixOp *GcUP, EMatRelations mat_rel, std::ostream *out) const
Aggregate matrix class pulling together a MatrixOp object and a MatrixNonsing object into a unified m...
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)