1 // Copyright (C) 2004, 2006 International Business Machines and others. 2 // All Rights Reserved. 3 // This code is published under the Common Public License. 4 // 5 // $Id: IpCompoundMatrix.hpp 759 2006-07-07 03:07:08Z andreasw $ 6 // 7 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 8 9 #ifndef __IPCOMPOUNDMATRIX_HPP__ 10 #define __IPCOMPOUNDMATRIX_HPP__ 11 12 #include "IpUtils.hpp" 13 #include "IpMatrix.hpp" 14 15 namespace SimTKIpopt 16 { 17 18 /* forward declarations */ 19 class CompoundMatrixSpace; 20 21 /** Class for Matrices consisting of other matrices. This matrix is 22 * a matrix that consists of zero, one or more Matrices's which are 23 * arranged like this: \f$ M_{\rm compound} = 24 * \left(\begin{array}{cccc}M_{00} & M_{01} & \ldots & M_{0,{\rm 25 * ncomp\_cols}-1} \\ \dots &&&\dots \\ M_{{\rm ncomp\_rows}-1,0} & 26 * M_{{\rm ncomp\_rows}-1,1} & \dots & M_{{\rm ncomp\_rows}-1,{\rm 27 * ncomp\_cols}-1}\end{array}\right)\f$. The individual components 28 * can be associated to different MatrixSpaces. The individual 29 * components can also be const and non-const Matrices. If a 30 * component is not set (i.e., it's pointer is NULL), then this 31 * components is treated like a zero-matrix of appropriate 32 * dimensions. 33 */ 34 class CompoundMatrix : public Matrix 35 { 36 public: 37 38 /**@name Constructors / Destructors */ 39 //@{ 40 41 /** Constructor, taking the owner_space. The owner_space has to 42 * be defined, so that at each block row and column contain at 43 * least one non-NULL component. The individual components can 44 * be set afterwards with the SeteComp and SetCompNonConst 45 * methods. 46 */ 47 CompoundMatrix(const CompoundMatrixSpace* owner_space); 48 49 /** Destructor */ 50 ~CompoundMatrix(); 51 //@} 52 53 /** Method for setting an individual component at position (irow, 54 * icol) in the compound matrix. The counting of indices starts 55 * at 0. */ 56 void SetComp(Index irow, Index jcol, const Matrix& matrix); 57 58 /** Method to set a non-const Matrix entry */ 59 void SetCompNonConst(Index irow, Index jcol, Matrix& matrix); 60 61 /** Method to create a new matrix from the space for this block */ 62 void CreateBlockFromSpace(Index irow, Index jcol); 63 64 /** Method for retrieving one block from the compound matrix as a 65 * const Matrix. 66 */ GetComp(Index irow,Index jcol) const67 SmartPtr<const Matrix> GetComp(Index irow, Index jcol) const 68 { 69 return ConstComp(irow, jcol); 70 } 71 72 /** Method for retrieving one block from the compound matrix as a 73 * non-const Matrix. Note that calling this method with mark the 74 * CompoundMatrix as changed. Therefore, only use this method if 75 * you are intending to change the Matrix that you receive. */ GetCompNonConst(Index irow,Index jcol)76 SmartPtr<Matrix> GetCompNonConst(Index irow, Index jcol) 77 { 78 ObjectChanged(); 79 return Comp(irow, jcol); 80 } 81 82 /** Number of block rows of this compound matrix. */ 83 inline Index NComps_Rows() const; 84 /** Number of block colmuns of this compound matrix. */ 85 inline Index NComps_Cols() const; 86 87 protected: 88 /**@name Methods overloaded from Matrix */ 89 //@{ 90 virtual void MultVectorImpl(Number alpha, const Vector& x, 91 Number beta, Vector& y) const override; 92 93 virtual void TransMultVectorImpl(Number alpha, const Vector& x, 94 Number beta, Vector& y) const override; 95 96 /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized implementation. 97 */ 98 virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, 99 Vector& X) const override; 100 101 /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation. 102 */ 103 virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, 104 const Vector& R, const Vector& Z, 105 const Vector& D, Vector& X) const override; 106 107 /** Method for determining if all stored numbers are valid (i.e., 108 * no Inf or Nan). */ 109 virtual bool HasValidNumbersImpl() const override; 110 111 virtual void PrintImpl(const Journalist& jnlst, 112 EJournalLevel level, 113 EJournalCategory category, 114 const std::string& name, 115 Index indent, 116 const std::string& prefix) const override; 117 //@} 118 119 private: 120 /**@name Default Compiler Generated Methods 121 * (Hidden to avoid implicit creation/calling). 122 * These methods are not implemented and 123 * we do not want the compiler to implement 124 * them for us, so we declare them private 125 * and do not define them. This ensures that 126 * they will not be implicitly created/called. */ 127 //@{ 128 /** Default Constructor */ 129 CompoundMatrix(); 130 131 /** Copy Constructor */ 132 CompoundMatrix(const CompoundMatrix&); 133 134 /** Overloaded Equals Operator */ 135 void operator=(const CompoundMatrix&); 136 //@} 137 138 /** Matrix of matrix's containing the components */ 139 std::vector<std::vector<SmartPtr<Matrix> > > comps_; 140 141 /** Matrix of const matrix's containing the components */ 142 std::vector<std::vector<SmartPtr<const Matrix> > > const_comps_; 143 144 /** Copy of the owner_space ptr as a CompoundMatrixSpace instead 145 * of MatrixSpace */ 146 const CompoundMatrixSpace* owner_space_; 147 148 /** boolean indicating if the compound matrix is in a "valid" state */ 149 mutable bool matrices_valid_; 150 151 /** Method to check whether or not the matrices are valid */ 152 bool MatricesValid() const; 153 154 inline const Matrix* ConstComp(Index irow, Index jcol) const; 155 156 inline Matrix* Comp(Index irow, Index jcol); 157 }; 158 159 /** This is the matrix space for CompoundMatrix. Before a CompoundMatrix 160 * can be created, at least one MatrixSpace has to be set per block 161 * row and column. Individual component MatrixSpace's can be set 162 * with the SetComp method. 163 */ 164 class CompoundMatrixSpace : public MatrixSpace 165 { 166 public: 167 /** @name Constructors / Destructors */ 168 //@{ 169 /** Constructor, given the number of row and columns blocks, as 170 * well as the totel number of rows and columns. 171 */ 172 CompoundMatrixSpace(Index ncomps_rows, 173 Index ncomps_cols, 174 Index total_nRows, 175 Index total_nCols); 176 177 /** Destructor */ ~CompoundMatrixSpace()178 ~CompoundMatrixSpace() 179 {} 180 ; 181 //@} 182 183 /** @name Methods for setting information about the components. */ 184 //@{ 185 /** Set the number nrows of rows in row-block number irow. */ 186 void SetBlockRows(Index irow, Index nrows); 187 188 /** Set the number ncols of columns in column-block number jcol. */ 189 void SetBlockCols(Index jcol, Index ncols); 190 191 /** Get the number nrows of rows in row-block number irow. */ 192 Index GetBlockRows(Index irow) const; 193 194 /** Set the number ncols of columns in column-block number jcol. */ 195 Index GetBlockCols(Index jcol) const; 196 197 /** Set the component MatrixSpace. If auto_allocate is true, then 198 * a new CompoundMatrix created later with MakeNew will have this 199 * component automatically created with the Matrix's MakeNew. 200 * Otherwise, the corresponding component will be NULL and has to 201 * be set with the SetComp methods of the CompoundMatrix. 202 */ 203 void SetCompSpace(Index irow, Index jcol, 204 const MatrixSpace& mat_space, 205 bool auto_allocate = false); 206 //@} 207 208 /** Obtain the component MatrixSpace in block row irow and block 209 * column jcol. 210 */ GetCompSpace(Index irow,Index jcol) const211 SmartPtr<const MatrixSpace> GetCompSpace(Index irow, Index jcol) const 212 { 213 DBG_ASSERT(irow<NComps_Rows()); 214 DBG_ASSERT(jcol<NComps_Cols()); 215 return comp_spaces_[irow][jcol]; 216 } 217 218 /** @name Accessor methods */ 219 //@{ 220 /** Number of block rows */ NComps_Rows() const221 Index NComps_Rows() const 222 { 223 return ncomps_rows_; 224 } 225 /** Number of block columns */ NComps_Cols() const226 Index NComps_Cols() const 227 { 228 return ncomps_cols_; 229 } 230 231 /** True if the blocks lie on the diagonal - can make some operations faster */ Diagonal() const232 bool Diagonal() const 233 { 234 return diagonal_; 235 } 236 //@} 237 238 /** Method for creating a new matrix of this specific type. */ 239 CompoundMatrix* MakeNewCompoundMatrix() const; 240 241 /** Overloaded MakeNew method for the MatrixSpace base class. 242 */ MakeNew() const243 virtual Matrix* MakeNew() const override 244 { 245 return MakeNewCompoundMatrix(); 246 } 247 248 private: 249 /**@name Default Compiler Generated Methods 250 * (Hidden to avoid implicit creation/calling). 251 * These methods are not implemented and 252 * we do not want the compiler to implement 253 * them for us, so we declare them private 254 * and do not define them. This ensures that 255 * they will not be implicitly created/called. */ 256 //@{ 257 /** Default constructor */ 258 CompoundMatrixSpace(); 259 260 /** Copy Constructor */ 261 CompoundMatrixSpace(const CompoundMatrixSpace&); 262 263 /** Overloaded Equals Operator */ 264 CompoundMatrixSpace& operator=(const CompoundMatrixSpace&); 265 //@} 266 267 /** Number of block rows */ 268 Index ncomps_rows_; 269 270 /** Number of block columns */ 271 Index ncomps_cols_; 272 273 /** Store whether or not the dimensions are valid */ 274 mutable bool dimensions_set_; 275 276 /** 2-dim std::vector of matrix spaces for the components */ 277 std::vector<std::vector<SmartPtr<const MatrixSpace> > > comp_spaces_; 278 279 /** 2-dim std::vector of booleans deciding whether to 280 * allocate a new matrix for the blocks automagically */ 281 std::vector<std::vector< bool > > allocate_block_; 282 283 /** Vector of the number of rows in each comp column */ 284 std::vector<Index> block_rows_; 285 286 /** Vector of the number of cols in each comp row */ 287 std::vector<Index> block_cols_; 288 289 /** true if the CompoundMatrixSpace only has Matrix spaces along the diagonal. 290 * this means that the CompoundMatrix will only have matrices along the 291 * diagonal and it could make some operations more efficient 292 */ 293 bool diagonal_; 294 295 /** Auxilliary function for debugging to set if all block 296 * dimensions have been set. */ 297 bool DimensionsSet() const; 298 }; 299 300 /* inline methods */ 301 inline NComps_Rows() const302 Index CompoundMatrix::NComps_Rows() const 303 { 304 return owner_space_->NComps_Rows(); 305 } 306 307 inline NComps_Cols() const308 Index CompoundMatrix::NComps_Cols() const 309 { 310 return owner_space_->NComps_Cols(); 311 } 312 313 inline ConstComp(Index irow,Index jcol) const314 const Matrix* CompoundMatrix::ConstComp(Index irow, Index jcol) const 315 { 316 DBG_ASSERT(irow < NComps_Rows()); 317 DBG_ASSERT(jcol < NComps_Cols()); 318 if (IsValid(comps_[irow][jcol])) { 319 return GetRawPtr(comps_[irow][jcol]); 320 } 321 else if (IsValid(const_comps_[irow][jcol])) { 322 return GetRawPtr(const_comps_[irow][jcol]); 323 } 324 325 return NULL; 326 } 327 328 inline Comp(Index irow,Index jcol)329 Matrix* CompoundMatrix::Comp(Index irow, Index jcol) 330 { 331 DBG_ASSERT(irow < NComps_Rows()); 332 DBG_ASSERT(jcol < NComps_Cols()); 333 return GetRawPtr(comps_[irow][jcol]); 334 } 335 336 } // namespace Ipopt 337 #endif 338