1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
// Copyright (C) 2005, 2008 International Business Machines and others.
// All Rights Reserved.
// This code is published under the Eclipse Public License.
//
// Authors: Andreas Waechter IBM 2005-12-25
#ifndef __IPLOWRANKUPDATESYMMATRIX_HPP__
#define __IPLOWRANKUPDATESYMMATRIX_HPP__
#include "IpUtils.hpp"
#include "IpSymMatrix.hpp"
#include "IpMultiVectorMatrix.hpp"
namespace Ipopt
{
/* forward declarations */
class LowRankUpdateSymMatrixSpace;
/** Class for symmetric matrices, represented as low-rank updates.
*
* The matrix M is represented as M = P_LR(D + V V^T - U U^T)P_LR^T
* (if reduced_diag is true), or M = D + P_LR(V V^T - U U^T)P_LR^T
* (if reduced_diag is false). D is a diagonal matrix, and V and U
* are MultiVectorMatrices, and P_LR is an ExpansionMatrix. The
* vectors in the low-rank update (before expansion) live in the
* LowRankVectorSpace. If P_LR is NULL, P_LR is assumed to be the
* identity matrix. If V or U is NULL, it is assume to be a matrix
* of zero columns.
*/
class LowRankUpdateSymMatrix: public SymMatrix
{
public:
/**@name Constructors / Destructors */
///@{
/** Constructor, given the corresponding matrix space. */
LowRankUpdateSymMatrix(
const LowRankUpdateSymMatrixSpace* owner_space
);
/** Destructor */
~LowRankUpdateSymMatrix();
///@}
/** Method for setting the diagonal elements (as a Vector). */
void SetDiag(
const Vector& D
)
{
D_ = &D;
ObjectChanged();
}
/** Method for getting the diagonal elements. */
SmartPtr<const Vector> GetDiag() const
{
return D_;
}
/** Method for setting the positive low-rank update part. */
void SetV(
const MultiVectorMatrix& V
)
{
V_ = &V;
ObjectChanged();
}
/** Method for getting the positive low-rank update part. */
SmartPtr<const MultiVectorMatrix> GetV() const
{
return V_;
}
/** Method for setting the negative low-rank update part. */
void SetU(
const MultiVectorMatrix& U
)
{
U_ = &U;
ObjectChanged();
}
/** Method for getting the negative low-rank update part. */
SmartPtr<const MultiVectorMatrix> GetU() const
{
return U_;
}
/** Return the expansion matrix to lift the low-rank update to the
* higher-dimensional space.
*/
SmartPtr<const Matrix> P_LowRank() const;
/** Return the vector space in with the low-rank update vectors live. */
SmartPtr<const VectorSpace> LowRankVectorSpace() const;
/** Flag indicating whether the diagonal term lives in the smaller
* space (from P_LowRank) or in the full space.
*/
bool ReducedDiag() const;
protected:
/**@name Methods overloaded from matrix */
///@{
virtual void MultVectorImpl(
Number alpha,
const Vector& x,
Number beta,
Vector& y
) 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 */
LowRankUpdateSymMatrix();
/** Copy Constructor */
LowRankUpdateSymMatrix(
const LowRankUpdateSymMatrix&
);
/** Default Assignment Operator */
void operator=(
const LowRankUpdateSymMatrix&
);
///@}
/** corresponding matrix space */
SmartPtr<const LowRankUpdateSymMatrixSpace> owner_space_;
/** Vector storing the diagonal matrix D. */
SmartPtr<const Vector> D_;
/** Vector storing the positive low-rank update. */
SmartPtr<const MultiVectorMatrix> V_;
/** Vector storing the negative low-rank update. */
SmartPtr<const MultiVectorMatrix> U_;
};
/** This is the matrix space for LowRankUpdateSymMatrix. */
class LowRankUpdateSymMatrixSpace: public SymMatrixSpace
{
public:
/** @name Constructors / Destructors */
///@{
/** Constructor, given the dimension of the matrix. */
LowRankUpdateSymMatrixSpace(
Index dim,
SmartPtr<const Matrix> P_LowRank,
SmartPtr<const VectorSpace> LowRankVectorSpace,
bool reduced_diag
)
: SymMatrixSpace(dim),
P_LowRank_(P_LowRank),
lowrank_vector_space_(LowRankVectorSpace),
reduced_diag_(reduced_diag)
{
DBG_ASSERT(IsValid(lowrank_vector_space_));
}
/** Destructor */
virtual ~LowRankUpdateSymMatrixSpace()
{ }
///@}
virtual SymMatrix* MakeNewSymMatrix() const
{
return MakeNewLowRankUpdateSymMatrix();
}
/** Method for creating a new matrix of this specific type. */
LowRankUpdateSymMatrix* MakeNewLowRankUpdateSymMatrix() const
{
return new LowRankUpdateSymMatrix(this);
}
SmartPtr<const Matrix> P_LowRank() const
{
return P_LowRank_;
}
SmartPtr<const VectorSpace> LowRankVectorSpace() const
{
return lowrank_vector_space_;
}
bool ReducedDiag() const
{
return reduced_diag_;
}
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 */
LowRankUpdateSymMatrixSpace();
/** Copy Constructor */
LowRankUpdateSymMatrixSpace(
const LowRankUpdateSymMatrixSpace&
);
/** Default Assignment Operator */
void operator=(
const LowRankUpdateSymMatrixSpace&
);
///@}
/** Expansion matrix to lift the low-rank approximation into a
* possibly higher-dimensional space.
*
* If it is NULL, it is assume that no lift is performed.
*/
SmartPtr<const Matrix> P_LowRank_;
/** Vector space for the space in which the low-rank approximation lives. */
SmartPtr<const VectorSpace> lowrank_vector_space_;
/** Flag indicating whether the diagonal matrix is nonzero only in
* the space of V or in the full space.
*/
bool reduced_diag_;
};
inline SmartPtr<const Matrix> LowRankUpdateSymMatrix::P_LowRank() const
{
return owner_space_->P_LowRank();
}
inline SmartPtr<const VectorSpace> LowRankUpdateSymMatrix::LowRankVectorSpace() const
{
return owner_space_->LowRankVectorSpace();
}
inline bool LowRankUpdateSymMatrix::ReducedDiag() const
{
return owner_space_->ReducedDiag();
}
} // namespace Ipopt
#endif