ConstrainedOptPack: C++ Tools for Constrained (and Unconstrained) Optimization  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ConstrainedOptPack_MatrixSymPosDefBandedChol.cpp
1 #if 0
2 
3 // @HEADER
4 // ***********************************************************************
5 //
6 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
7 // Copyright (2003) Sandia Corporation
8 //
9 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
10 // license for use of this work by or on behalf of the U.S. Government.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
40 //
41 // ***********************************************************************
42 // @HEADER
43 
44 #include <assert.h>
45 
46 #include <sstream>
47 
48 #include "ConstrainedOptPack_MatrixSymPosDefBandedChol.hpp"
49 #include "DenseLinAlgPack_AssertOp.hpp"
50 #include "DenseLinAlgPack_LinAlgOpPack.hpp"
51 #include "DenseLinAlgPack_BLAS_Cpp.hpp"
52 #include "MiReleaseResource_ref_count_ptr.h"
53 #include "MiWorkspacePack.h"
54 
55 // LAPACK functions
56 
57 extern "C" {
58 
59 FORTRAN_FUNC_DECL_UL(void,DPBTRF,dpbtrf)(
60  FORTRAN_CONST_CHAR_1_ARG(UPLO)
61  ,const FortranTypes::f_int &N
62  ,const FortranTypes::f_int &KD
63  ,FortranTypes::f_dbl_prec *AB
64  ,const FortranTypes::f_int &LDAB
65  ,FortranTypes::f_int *INFO
66  );
67 
68 FORTRAN_FUNC_DECL_UL(void,DPBTRS,dpbtrs)(
69  FORTRAN_CONST_CHAR_1_ARG(UPLO)
70  ,const FortranTypes::f_int &N
71  ,const FortranTypes::f_int &KD
72  ,const FortranTypes::f_int &NRHS
73  ,const FortranTypes::f_dbl_prec AB[]
74  ,const FortranTypes::f_int &LDAB
75  ,FortranTypes::f_dbl_prec *B
76  ,const FortranTypes::f_int &LDB
77  ,FortranTypes::f_int *INFO
78  );
79 
80 } // end namespace LAPACK
81 
82 namespace ConstrainedOptPack {
83 
85  size_type n
86  ,size_type kd
87  ,DMatrixSlice *MB
88  ,const release_resource_ptr_t& MB_release_resource_ptr
89  ,BLAS_Cpp::Uplo MB_uplo
90  ,DMatrixSlice *UB
91  ,const release_resource_ptr_t& UB_release_resource_ptr
92  ,BLAS_Cpp::Uplo UB_uplo
93  ,bool update_factor
94  ,value_type scale
95  )
96 {
97  initialize(n,kd,MB,MB_release_resource_ptr,MB_uplo
98  ,UB,UB_release_resource_ptr,UB_uplo,update_factor,scale);
99 }
100 
102  size_type n
103  ,size_type kd
104  ,DMatrixSlice *MB
105  ,const release_resource_ptr_t& MB_release_resource_ptr
106  ,BLAS_Cpp::Uplo MB_uplo
107  ,DMatrixSlice *UB
108  ,const release_resource_ptr_t& UB_release_resource_ptr
109  ,BLAS_Cpp::Uplo UB_uplo
110  ,bool update_factor
111  ,value_type scale
112  )
113 {
114  // Validate input
115 
116  if( n == 0 ) {
117  if( kd != 0 )
118  throw std::invalid_argument(
119  "MatrixSymPosDefBandedChol::initialize(...): Error, "
120  "kd must be 0 if n == 0" );
121  if( MB != NULL )
122  throw std::invalid_argument(
123  "MatrixSymPosDefBandedChol::initialize(...): Error, "
124  "MB must be NULL if n == 0" );
125  if( MB_release_resource_ptr.get() != NULL )
126  throw std::invalid_argument(
127  "MatrixSymPosDefBandedChol::initialize(...): Error, "
128  "MB_release_resource_ptr.get() must be NULL if n == 0" );
129  if( UB != NULL )
130  throw std::invalid_argument(
131  "MatrixSymPosDefBandedChol::initialize(...): Error, "
132  "UB must be NULL if n == 0" );
133  if( UB_release_resource_ptr.get() != NULL )
134  throw std::invalid_argument(
135  "MatrixSymPosDefBandedChol::initialize(...): Error, "
136  "UB_release_resource_ptr.get() must be NULL if n == 0" );
137  }
138  else {
139  if( kd + 1 > n )
140  throw std::invalid_argument(
141  "MatrixSymPosDefBandedChol::initialize(...): Error, "
142  "kd + 1 can not be larger than n" );
143  if( MB == NULL && UB == NULL )
144  throw std::invalid_argument(
145  "MatrixSymPosDefBandedChol::initialize(...): Error, "
146  "MB and UB can not both be NULL" );
147  if( MB != NULL && ( MB->rows() != kd + 1 || MB->cols() != n ) )
148  throw std::invalid_argument(
149  "MatrixSymPosDefBandedChol::initialize(...): Error, "
150  "MB is not the correct size" );
151  if( UB != NULL && ( UB->rows() != kd + 1 || UB->cols() != n ) )
152  throw std::invalid_argument(
153  "MatrixSymPosDefBandedChol::initialize(...): Error, "
154  "UB is not the correct size" );
155  }
156 
157  // Set the members
158 
159  if( n == 0 ) {
160  n_ = 0;
161  kd_ = 0;
162  MB_.bind(DMatrixSlice());
163  MB_release_resource_ptr_ = NULL;
164  MB_uplo_ = BLAS_Cpp::lower;
165  UB_.bind(DMatrixSlice());
166  UB_release_resource_ptr_ = NULL;
167  UB_uplo_ = BLAS_Cpp::lower;
168  scale_ = 1.0;
169  }
170  else {
171  // Set the members
172  n_ = n;
173  kd_ = kd;
174  if(MB) MB_.bind(*MB);
175  MB_release_resource_ptr_ = MB_release_resource_ptr;
176  MB_uplo_ = MB_uplo;
177  if(UB) UB_.bind(*UB);
178  UB_release_resource_ptr_ = UB_release_resource_ptr;
179  UB_uplo_ = UB_uplo;
180  factor_updated_ = UB && !update_factor;
181  scale_ = scale;
182  // Update the factorization if we have storage
183  if( update_factor )
184  update_factorization();
185  }
186 }
187 
188 // Overridden from MatrixOp
189 
191 {
192  return n_;
193 }
194 
196 {
197  return (2 * kd_ + 1) * n_ - ( (kd_+1)*(kd_+1) - (kd_+1) );
198 }
199 
200 std::ostream& MatrixSymPosDefBandedChol::output(std::ostream& out) const
201 {
202  return MatrixOp::output(out); // ToDo: Implement specialized version later!
203 }
204 
206  DVectorSlice* y, value_type a, BLAS_Cpp::Transp M_trans
207  , const DVectorSlice& x, value_type b) const
208 {
209  assert_initialized();
210  DenseLinAlgPack::Vp_MtV_assert_sizes( y->size(), n_, n_, BLAS_Cpp::no_trans, x.size() );
211  if( MB_.rows() ) {
212  BLAS_Cpp::sbmv(MB_uplo_,n_,kd_,a,MB_.col_ptr(1),MB_.max_rows(),x.raw_ptr(),x.stride()
213  ,b,y->raw_ptr(),y->stride());
214  }
215  else if( UB_.rows() ) {
216  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement when and if needed!
217  }
218  else {
219  TEUCHOS_TEST_FOR_EXCEPT(true); // This should not happen!
220  }
221 }
222 
224  DVectorSlice* y, value_type a, BLAS_Cpp::Transp M_trans
225  , const SpVectorSlice& x, value_type b) const
226 {
227  assert_initialized();
228  MatrixOp::Vp_StMtV(y,a,M_trans,x,b); // ToDo: Implement spacialized operation when needed!
229 }
230 
232  DVectorSlice* y, value_type a
233  , const GenPermMatrixSlice& P, BLAS_Cpp::Transp P_trans
234  , BLAS_Cpp::Transp M_trans
235  , const DVectorSlice& x, value_type b) const
236 {
237  assert_initialized();
238  MatrixOp::Vp_StPtMtV(y,a,P,P_trans,M_trans,x,b); // ToDo: Implement spacialized operation when needed!
239 }
240 
242  DVectorSlice* y, value_type a
243  , const GenPermMatrixSlice& P, BLAS_Cpp::Transp P_trans
244  , BLAS_Cpp::Transp M_trans
245  , const SpVectorSlice& x, value_type b) const
246 {
247  assert_initialized();
248  MatrixOp::Vp_StPtMtV(y,a,P,P_trans,M_trans,x,b); // ToDo: Implement spacialized operation when needed!
249 }
250 
251 // Overridden from MatrixFactorized
252 
254  DVectorSlice* y, BLAS_Cpp::Transp M_trans
255  , const DVectorSlice& x) const
256 {
257  using Teuchos::Workspace;
259 
260  assert_initialized();
261 
262  DenseLinAlgPack::Vp_MtV_assert_sizes( y->size(), n_, n_, BLAS_Cpp::no_trans, x.size() );
263 
264  update_factorization();
265 
266  Workspace<value_type> t_ws(wss,y->size());
267  DVectorSlice t(&t_ws[0],t_ws.size());
268 
269  t = x;
270 
271  FortranTypes::f_int info = 0;
272  FORTRAN_FUNC_CALL_UL(DPBTRS,dpbtrs)(
273  FORTRAN_CHAR_1_ARG_CALL(UB_uplo_ == BLAS_Cpp::upper ? 'U' : 'L')
274  , n_, kd_, 1, UB_.col_ptr(1), UB_.max_rows()
275  ,&t[0], t.size(), &info );
276  if( info > 0 )
277  TEUCHOS_TEST_FOR_EXCEPT(true); // Should not happen!
278  if( info < 0 ) {
279  std::ostringstream omsg;
280  omsg
281  << "MatrixSymPosDefBandedChol::update_factorization(): Error, "
282  << "The " << -info << " argument passed to xPBTRF(...) is invalid!";
283  throw std::invalid_argument(omsg.str());
284  }
285  *y = t;
286 }
287 
288 // Private member functions
289 
290 void MatrixSymPosDefBandedChol::assert_initialized() const
291 {
292  if( n_ == 0 )
293  throw std::logic_error("MatrixSymPosDefBandedChol::assert_initialized(): Error, "
294  "not initialized!" );
295 }
296 
297 void MatrixSymPosDefBandedChol::update_factorization() const
298 {
299  namespace rcp = MemMngPack;
300  using Teuchos::RCP;
301  namespace rmp = MemMngPack;
302 
303  if( !factor_updated_ ) {
304  if(UB_.rows() == 0) {
305  // Allocate our own storage for the banded cholesky factor!
306  typedef Teuchos::RCP<DMatrix> UB_ptr_t;
307  typedef rmp::ReleaseResource_ref_count_ptr<DMatrix> UB_rel_ptr_t;
308  typedef Teuchos::RCP<UB_rel_ptr_t> UB_rel_ptr_ptr_t;
309  UB_rel_ptr_ptr_t UB_rel_ptr_ptr = new UB_rel_ptr_t(new DMatrix);
310  UB_rel_ptr_ptr->ptr->resize(kd_+1,n_);
311  UB_.bind( (*UB_rel_ptr_ptr->ptr)() );
312  UB_release_resource_ptr_ = Teuchos::rcp_implicit_cast<rmp::ReleaseResource>(UB_rel_ptr_ptr);
313  }
314  // Update the cholesky factor
315  LinAlgOpPack::M_StM( &UB_, scale_, MB_, BLAS_Cpp::no_trans );
316  UB_uplo_ = MB_uplo_;
317  FortranTypes::f_int info = 0;
318  FORTRAN_FUNC_CALL_UL(DPBTRF,dpbtrf)(
319  FORTRAN_CHAR_1_ARG_CALL(UB_uplo_ == BLAS_Cpp::upper ? 'U' : 'L')
320  , n_, kd_, UB_.col_ptr(1), UB_.max_rows(), &info );
321  if( info < 0 ) {
322  std::ostringstream omsg;
323  omsg
324  << "MatrixSymPosDefBandedChol::update_factorization(): Error, "
325  << "The " << -info << " argument passed to xPBTRF(...) is invalid!";
326  throw std::invalid_argument(omsg.str());
327  }
328  if( info > 0 ) {
329  std::ostringstream omsg;
330  omsg
331  << "MatrixSymPosDefBandedChol::update_factorization(): Error, "
332  << "The leading minor of order " << info << " passed to xPBTRF(...) is not positive definite!";
333  throw std::invalid_argument(omsg.str());
334  }
335  factor_updated_ = true;
336  }
337 }
338 
339 } // end namespace ConstrainedOptPack
340 
341 #endif // 0
void Vp_StPtMtV(DVectorSlice *vs_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs1, BLAS_Cpp::Transp P_rhs1_trans, BLAS_Cpp::Transp M_rhs2_trans, const DVectorSlice &vs_rhs3, value_type beta) const
Uplo
std::ostream & output(std::ostream &out) const
void Vp_StPtMtV(VectorMutable *v_lhs, value_type alpha, const GenPermMatrixSlice &P_rhs1, BLAS_Cpp::Transp P_rhs1_trans, const MatrixOp &M_rhs2, BLAS_Cpp::Transp M_rhs2_trans, const Vector &v_rhs3, value_type beta=1.0)
void Vp_StMtV(DVectorSlice *vs_lhs, value_type alpha, BLAS_Cpp::Transp trans_rhs1, const DVectorSlice &vs_rhs2, value_type beta) const
void V_InvMtV(DVectorSlice *vs_lhs, BLAS_Cpp::Transp trans_rhs1, const DVectorSlice &vs_rhs2) const
With throw exception if factorization is not allowed.
void initialize(size_type n=0, size_type kd=0, DMatrixSlice *MB=NULL, const release_resource_ptr_t &MB_release_resource_ptr=NULL, BLAS_Cpp::Uplo MB_uplo=BLAS_Cpp::lower, DMatrixSlice *UB=NULL, const release_resource_ptr_t &UB_release_resource_ptr=NULL, BLAS_Cpp::Uplo UB_uplo=BLAS_Cpp::lower, bool update_factor=false, value_type scale=1.0)
Initialize.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void M_StM(MatrixOp *M_lhs, value_type alpha, const MatrixOp &M_rhs, BLAS_Cpp::Transp trans_rhs)
size_t size_type
void Vp_StMtV(VectorMutable *v_lhs, value_type alpha, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2, value_type beta=1.0)
MatrixSymPosDefBandedChol(size_type n=0, size_type kd=0, DMatrixSlice *MB=NULL, const release_resource_ptr_t &MB_release_resource_ptr=NULL, BLAS_Cpp::Uplo MB_uplo=BLAS_Cpp::lower, DMatrixSlice *UB=NULL, const release_resource_ptr_t &UB_release_resource_ptr=NULL, BLAS_Cpp::Uplo UB_uplo=BLAS_Cpp::lower, bool update_factor=false, value_type scale=1.0)
Construct and Initialize.
Transp
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()