// Copyright (C) 2004, 2009 International Business Machines and others. // All Rights Reserved. // This code is published under the Eclipse Public License. // // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 #ifndef __IPCOMPOUNDMATRIX_HPP__ #define __IPCOMPOUNDMATRIX_HPP__ #include "IpUtils.hpp" #include "IpMatrix.hpp" namespace Ipopt { /* forward declarations */ class CompoundMatrixSpace; /** Class for Matrices consisting of other matrices. * * This matrix is * a matrix that consists of zero, one or more Matrices's which are * arranged like this: \f$ M_{\rm compound} = * \left(\begin{array}{cccc}M_{00} & M_{01} & \ldots & M_{0,{\rm * ncomp\_cols}-1} \\ \dots &&&\dots \\ M_{{\rm ncomp\_rows}-1,0} & * M_{{\rm ncomp\_rows}-1,1} & \dots & M_{{\rm ncomp\_rows}-1,{\rm * ncomp\_cols}-1}\end{array}\right)\f$. The individual components * can be associated to different MatrixSpaces. The individual * components can also be const and non-const Matrices. If a * component is not set (i.e., it's pointer is NULL), then this * components is treated like a zero-matrix of appropriate * dimensions. */ class IPOPTLIB_EXPORT CompoundMatrix: public Matrix { public: /**@name Constructors / Destructors */ ///@{ /** Constructor, taking the owner_space. * * The owner_space has to * be defined, so that at each block row and column contain at * least one non-NULL component. The individual components can * be set afterwards with the SeteComp and SetCompNonConst * methods. */ CompoundMatrix( const CompoundMatrixSpace* owner_space ); /** Destructor */ virtual ~CompoundMatrix(); ///@} /** Method for setting an individual component at position (irow, * icol) in the compound matrix. * * The counting of indices starts at 0. */ void SetComp( Index irow, Index jcol, const Matrix& matrix ); /** Method to set a non-const Matrix entry */ void SetCompNonConst( Index irow, Index jcol, Matrix& matrix ); /** Method to create a new matrix from the space for this block */ void CreateBlockFromSpace( Index irow, Index jcol ); /** Method for retrieving one block from the compound matrix as a * const Matrix. */ SmartPtr GetComp( Index irow, Index jcol ) const { return ConstComp(irow, jcol); } /** Method for retrieving one block from the compound matrix as a * non-const Matrix. * * Note that calling this method with mark the * CompoundMatrix as changed. Therefore, only use this method if * you are intending to change the Matrix that you receive. */ SmartPtr GetCompNonConst( Index irow, Index jcol ) { ObjectChanged(); return Comp(irow, jcol); } /** Number of block rows of this compound matrix. */ inline Index NComps_Rows() const; /** Number of block colmuns of this compound matrix. */ inline Index NComps_Cols() const; protected: /**@name Methods overloaded from Matrix */ ///@{ virtual void MultVectorImpl( Number alpha, const Vector& x, Number beta, Vector& y ) const; virtual void TransMultVectorImpl( Number alpha, const Vector& x, Number beta, Vector& y ) const; virtual void AddMSinvZImpl( Number alpha, const Vector& S, const Vector& Z, Vector& X ) const; virtual void SinvBlrmZMTdBrImpl( Number alpha, const Vector& S, const Vector& R, const Vector& Z, const Vector& D, Vector& X ) const; virtual bool HasValidNumbersImpl() const; virtual void ComputeRowAMaxImpl( Vector& rows_norms, bool init ) const; virtual void ComputeColAMaxImpl( Vector& cols_norms, bool init ) const; virtual void PrintImpl( const Journalist& jnlst, EJournalLevel level, EJournalCategory category, const std::string& name, Index indent, const std::string& prefix ) const; ///@} private: /**@name Default Compiler Generated Methods * (Hidden to avoid implicit creation/calling). * These methods are not implemented and * we do not want the compiler to implement * them for us, so we declare them private * and do not define them. This ensures that * they will not be implicitly created/called. */ ///@{ /** Default Constructor */ CompoundMatrix(); /** Copy Constructor */ CompoundMatrix( const CompoundMatrix&); /** Default Assignment Operator */ void operator=( const CompoundMatrix&); ///@} /** Matrix of matrix's containing the components */ std::vector > > comps_; /** Matrix of const matrix's containing the components */ std::vector > > const_comps_; /** Copy of the owner_space ptr as a CompoundMatrixSpace instead * of MatrixSpace */ const CompoundMatrixSpace* owner_space_; /** boolean indicating if the compound matrix is in a "valid" state */ mutable bool matrices_valid_; /** Method to check whether or not the matrices are valid */ bool MatricesValid() const; inline const Matrix* ConstComp( Index irow, Index jcol ) const; inline Matrix* Comp( Index irow, Index jcol ); }; /** This is the matrix space for CompoundMatrix. Before a CompoundMatrix * can be created, at least one MatrixSpace has to be set per block * row and column. Individual component MatrixSpace's can be set * with the SetComp method. */ class IPOPTLIB_EXPORT CompoundMatrixSpace: public MatrixSpace { public: /** @name Constructors / Destructors */ ///@{ /** Constructor, given the number of row and columns blocks, as * well as the totel number of rows and columns. */ CompoundMatrixSpace( Index ncomps_rows, Index ncomps_cols, Index total_nRows, Index total_nCols ); /** Destructor */ ~CompoundMatrixSpace() { } ///@} /** @name Methods for setting information about the components. */ ///@{ /** Set the number nrows of rows in row-block number irow. */ void SetBlockRows( Index irow, Index nrows ); /** Set the number ncols of columns in column-block number jcol. */ void SetBlockCols( Index jcol, Index ncols ); /** Get the number nrows of rows in row-block number irow. */ Index GetBlockRows( Index irow ) const; /** Set the number ncols of columns in column-block number jcol. */ Index GetBlockCols( Index jcol ) const; /** Set the component MatrixSpace. * * If auto_allocate is true, then * a new CompoundMatrix created later with MakeNew will have this * component automatically created with the Matrix's MakeNew. * Otherwise, the corresponding component will be NULL and has to * be set with the SetComp methods of the CompoundMatrix. */ void SetCompSpace( Index irow, Index jcol, const MatrixSpace& mat_space, bool auto_allocate = false ); ///@} /** Obtain the component MatrixSpace in block row irow and block * column jcol. */ SmartPtr GetCompSpace( Index irow, Index jcol ) const { DBG_ASSERT(irow < NComps_Rows()); DBG_ASSERT(jcol < NComps_Cols()); return comp_spaces_[irow][jcol]; } /** @name Accessor methods */ ///@{ /** Number of block rows */ Index NComps_Rows() const { return ncomps_rows_; } /** Number of block columns */ Index NComps_Cols() const { return ncomps_cols_; } /** True if the blocks lie on the diagonal - can make some operations faster */ bool Diagonal() const { return diagonal_; } ///@} /** Method for creating a new matrix of this specific type. */ CompoundMatrix* MakeNewCompoundMatrix() const; virtual Matrix* MakeNew() const { return MakeNewCompoundMatrix(); } private: /**@name Default Compiler Generated Methods * (Hidden to avoid implicit creation/calling). * These methods are not implemented and * we do not want the compiler to implement * them for us, so we declare them private * and do not define them. This ensures that * they will not be implicitly created/called. */ ///@{ /** Default constructor */ CompoundMatrixSpace(); /** Copy Constructor */ CompoundMatrixSpace( const CompoundMatrixSpace&); /** Default Assignment Operator */ CompoundMatrixSpace& operator=( const CompoundMatrixSpace& ); ///@} /** Number of block rows */ Index ncomps_rows_; /** Number of block columns */ Index ncomps_cols_; /** Store whether or not the dimensions are valid */ mutable bool dimensions_set_; /** 2-dim std::vector of matrix spaces for the components */ std::vector > > comp_spaces_; /** 2-dim std::vector of booleans deciding whether to * allocate a new matrix for the blocks automagically */ std::vector > allocate_block_; /** Vector of the number of rows in each comp column */ std::vector block_rows_; /** Vector of the number of cols in each comp row */ std::vector block_cols_; /** true if the CompoundMatrixSpace only has Matrix spaces along the diagonal. * * This means that the CompoundMatrix will only have matrices along the * diagonal and it could make some operations more efficient. */ bool diagonal_; /** Auxiliary function for debugging to set if all block * dimensions have been set. */ bool DimensionsSet() const; }; /* inline methods */ inline Index CompoundMatrix::NComps_Rows() const { return owner_space_->NComps_Rows(); } inline Index CompoundMatrix::NComps_Cols() const { return owner_space_->NComps_Cols(); } inline const Matrix* CompoundMatrix::ConstComp( Index irow, Index jcol ) const { DBG_ASSERT(irow < NComps_Rows()); DBG_ASSERT(jcol < NComps_Cols()); if( IsValid(comps_[irow][jcol]) ) { return GetRawPtr(comps_[irow][jcol]); } else if( IsValid(const_comps_[irow][jcol]) ) { return GetRawPtr(const_comps_[irow][jcol]); } return NULL; } inline Matrix* CompoundMatrix::Comp( Index irow, Index jcol ) { DBG_ASSERT(irow < NComps_Rows()); DBG_ASSERT(jcol < NComps_Cols()); return GetRawPtr(comps_[irow][jcol]); } } // namespace Ipopt #endif