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: IpExpansionMatrix.hpp 759 2006-07-07 03:07:08Z andreasw $
6 //
7 // Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
8 
9 #ifndef __IPEXPANSIONMATRIX_HPP__
10 #define __IPEXPANSIONMATRIX_HPP__
11 
12 #include "IpUtils.hpp"
13 #include "IpMatrix.hpp"
14 
15 namespace SimTKIpopt
16 {
17 
18   /** forward declarations */
19   class ExpansionMatrixSpace;
20 
21   /** Class for expansion/projection matrices.  These matrices allow
22    *  to lift a vector to a vector with larger dimension, keeping
23    *  some elements of the larger vector zero.  This operation is achieved
24    *  by the MultVector operation.  The transpose operation then
25    *  filters some elements from a large vector into a smaller vector.
26    */
27   class ExpansionMatrix : public Matrix
28   {
29   public:
30 
31     /**@name Constructors / Destructors */
32     //@{
33 
34     /** Constructor, taking the owner_space.
35      */
36     ExpansionMatrix(const ExpansionMatrixSpace* owner_space);
37 
38     /** Destructor */
39     ~ExpansionMatrix();
40     //@}
41 
42     /** Return the vector of indices marking the expanded position.
43      *  The result is the Index array (of length NSmallVec=NCols())
44      *  that stores the mapping from the small vector to the large
45      *  vector.  For each element i=0,..,NSmallVec in the small
46      *  vector, ExpandedPosIndices()[i] give the corresponding index
47      *  in the large vector.
48      */
49     const Index* ExpandedPosIndices() const;
50 
51     /** Return the vector of indices marking the compressed position.
52      *  The result is the Index array (of length NLargeVec=NRows())
53      *  that stores the mapping from the large vector to the small
54      *  vector.  For each element i=0,..,NLargeVec in the large
55      *  vector, CompressedPosIndices()[i] gives the corresponding
56      *  index in the small vector, unless CompressedPosIndices()[i] is
57      *  negative.
58      */
59     const Index* CompressedPosIndices() const;
60 
61   protected:
62     /**@name Overloaded methods from Matrix base class*/
63     //@{
64     virtual void MultVectorImpl(Number alpha, const Vector &x, Number beta,
65                                 Vector &y) const override;
66 
67     virtual void TransMultVectorImpl(Number alpha, const Vector& x,
68                                      Number beta, Vector& y) const override;
69 
70     /** X = beta*X + alpha*(Matrix S^{-1} Z).  Specialized implementation.
71      */
72     virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z,
73                                Vector& X) const override;
74 
75     /** X = S^{-1} (r + alpha*Z*M^Td).  Specialized implementation.
76      */
77     virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S,
78                                     const Vector& R, const Vector& Z,
79                                     const Vector& D, Vector& X) const override;
80 
81     virtual void PrintImpl(const Journalist& jnlst,
82                            EJournalLevel level,
83                            EJournalCategory category,
84                            const std::string& name,
85                            Index indent,
86                            const std::string& prefix) const override;
87     //@}
88 
89 
90   private:
91     /**@name Default Compiler Generated Methods
92      * (Hidden to avoid implicit creation/calling).
93      * These methods are not implemented and
94      * we do not want the compiler to implement
95      * them for us, so we declare them private
96      * and do not define them. This ensures that
97      * they will not be implicitly created/called. */
98     //@{
99     /** Default Constructor */
100     ExpansionMatrix();
101 
102     /** Copy Constructor */
103     ExpansionMatrix(const ExpansionMatrix&);
104 
105     /** Overloaded Equals Operator */
106     void operator=(const ExpansionMatrix&);
107     //@}
108 
109     const ExpansionMatrixSpace* owner_space_;
110 
111   };
112 
113   /** This is the matrix space for ExpansionMatrix.
114    */
115   class ExpansionMatrixSpace : public MatrixSpace
116   {
117   public:
118     /** @name Constructors / Destructors */
119     //@{
120     /** Constructor, given the list of elements of the large vector
121      *  (of size NLargeVec) to be filtered into the small vector (of
122      *  size NSmallVec).  For each i=0..NSmallVec-1 the i-th element
123      *  of the small vector will be put into the ExpPos[i] position of
124      *  the large vector.  The position counting in the vector is
125      *  assumed to start at 0 (C-like array notation).
126      */
127     ExpansionMatrixSpace(Index NLargeVec,
128                          Index NSmallVec,
129                          const Index *ExpPos,
130                          const int offset = 0);
131 
132     /** Destructor */
~ExpansionMatrixSpace()133     ~ExpansionMatrixSpace()
134     {
135       delete [] compressed_pos_;
136       delete [] expanded_pos_;
137     }
138     //@}
139 
140     /** Method for creating a new matrix of this specific type. */
MakeNewExpansionMatrix() const141     ExpansionMatrix* MakeNewExpansionMatrix() const
142     {
143       return new ExpansionMatrix(this);
144     }
145 
146     /** Overloaded MakeNew method for the MatrixSpace base class.
147      */
MakeNew() const148     virtual Matrix* MakeNew() const override
149     {
150       return MakeNewExpansionMatrix();
151     }
152 
153     /** Accessor Method to obtain the Index array (of length
154      *  NSmallVec=NCols()) that stores the mapping from the small
155      *  vector to the large vector.  For each element i=0,..,NSmallVec
156      *  in the small vector, ExpandedPosIndices()[i] give the
157      *  corresponding index in the large vector.
158      */
ExpandedPosIndices() const159     const Index* ExpandedPosIndices() const
160     {
161       return expanded_pos_;
162     }
163 
164     /** Accessor Method to obtain the Index array (of length
165      *  NLargeVec=NRows()) that stores the mapping from the large
166      *  vector to the small vector.  For each element i=0,..,NLargeVec
167      *  in the large vector, CompressedPosIndices()[i] gives the
168      *  corresponding index in the small vector, unless
169      *  CompressedPosIndices()[i] is negative.
170      */
CompressedPosIndices() const171     const Index* CompressedPosIndices() const
172     {
173       return compressed_pos_;
174     }
175 
176   private:
177     Index *expanded_pos_;
178     Index *compressed_pos_;
179   };
180 
181   /* inline methods */
182   inline
ExpandedPosIndices() const183   const Index* ExpansionMatrix::ExpandedPosIndices() const
184   {
185     return owner_space_->ExpandedPosIndices();
186   }
187 
188   inline
CompressedPosIndices() const189   const Index* ExpansionMatrix::CompressedPosIndices() const
190   {
191     return owner_space_->CompressedPosIndices();
192   }
193 
194 } // namespace Ipopt
195 #endif
196