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
// Copyright (C) 2005, 2007 International Business Machines and others.
// All Rights Reserved.
// This code is published under the Eclipse Public License.
//
// Authors: Carl Laird, Andreas Waechter IBM 2005-08-04
#ifndef __IPPDPERTURBATIONHANDLER_HPP__
#define __IPPDPERTURBATIONHANDLER_HPP__
#include "IpAlgStrategy.hpp"
namespace Ipopt
{
/** Class for handling the perturbation factors delta_x, delta_s,
* delta_c, and delta_d in the primal dual system.
*
* This class is used by the PDFullSpaceSolver to handle the cases
* where the primal-dual system is singular or has the wrong inertia.
* The perturbation factors are obtained based on simple heuristics,
* taking into account the size of previous perturbations.
*/
class PDPerturbationHandler: public AlgorithmStrategyObject
{
public:
/**@name Constructors/Destructors */
///@{
/** Default Constructor */
PDPerturbationHandler();
/** Destructor */
virtual ~PDPerturbationHandler()
{ }
///@}
/* overloaded from AlgorithmStrategyObject */
virtual bool InitializeImpl(
const OptionsList& options,
const std::string& prefix
);
/** This method must be called for each new matrix, and before any
* other method for generating perturbation factors.
*
* Usually, the returned perturbation factors are zero, but if the
* system is thought to be structurally singular, they might be
* positive.
*
* @return false, no suitable perturbation could be found.
*/
virtual bool ConsiderNewSystem(
Number& delta_x,
Number& delta_s,
Number& delta_c,
Number& delta_d
);
/** This method returns perturbation factors for the case when the
* most recent factorization resulted in a singular matrix.
*
* @return false, if no suitable perturbation could be found.
*/
virtual bool PerturbForSingularity(
Number& delta_x,
Number& delta_s,
Number& delta_c,
Number& delta_d
);
/** This method returns perturbation factors for the case when the
* most recent factorization resulted in a matrix with an
* incorrect number of negative eigenvalues.
*
* @return false, if no suitable perturbation could be found.
*/
virtual bool PerturbForWrongInertia(
Number& delta_x,
Number& delta_s,
Number& delta_c,
Number& delta_d);
/** Just return the perturbation values that have been determined
* most recently.
*/
virtual void CurrentPerturbation(
Number& delta_x,
Number& delta_s,
Number& delta_c,
Number& delta_d
);
static void RegisterOptions(
SmartPtr<RegisteredOptions> roptions
);
protected:
/**@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.
*/
///@{
/** Copy Constructor */
PDPerturbationHandler(
const PDPerturbationHandler&
);
/** Default Assignment Operator */
void operator=(
const PDPerturbationHandler&
);
///@}
/** @name Size of the most recent non-zero perturbation. */
///@{
/** The last nonzero value for delta_x */
Number delta_x_last_;
/** The last nonzero value for delta_s */
Number delta_s_last_;
/** The last nonzero value for delta_c */
Number delta_c_last_;
/** The last nonzero value for delta_d */
Number delta_d_last_;
///@}
/** @name Size of the most recently suggested perturbation for the
* current matrix.
*/
///@{
/** The current value for delta_x */
Number delta_x_curr_;
/** The current value for delta_s */
Number delta_s_curr_;
/** The current value for delta_c */
Number delta_c_curr_;
/** The current value for delta_d */
Number delta_d_curr_;
///@}
/** Flag indicating if for the given matrix the perturb for wrong
* inertia method has already been called.
*/
bool get_deltas_for_wrong_inertia_called_;
/** @name Handling structural degeneracy */
///@{
/** Type for degeneracy flags */
enum DegenType
{
NOT_YET_DETERMINED,
NOT_DEGENERATE,
DEGENERATE
};
/** Flag indicating whether the reduced Hessian matrix is thought
* to be structurally singular.
*/
DegenType hess_degenerate_;
/** Flag indicating whether the Jacobian of the constraints is
* thought to be structurally rank-deficient.
*/
DegenType jac_degenerate_;
/** Flag counting matrices in which degeneracy was observed in the
* first successive iterations.
*
* -1 means that there was a non-degenerate (unperturbed) matrix
* at some point.
*/
Index degen_iters_;
/** Status of current trial configuration */
enum TrialStatus
{
NO_TEST,
TEST_DELTA_C_EQ_0_DELTA_X_EQ_0,
TEST_DELTA_C_GT_0_DELTA_X_EQ_0,
TEST_DELTA_C_EQ_0_DELTA_X_GT_0,
TEST_DELTA_C_GT_0_DELTA_X_GT_0
};
/** Current status */
TrialStatus test_status_;
///@}
/** @name Algorithmic parameters. */
///@{
/** Maximal perturbation for x and s. */
Number delta_xs_max_;
/** Smallest possible perturbation for x and s. */
Number delta_xs_min_;
/** Increase factor for delta_xs for first required perturbation. */
Number delta_xs_first_inc_fact_;
/** Increase factor for delta_xs for later perturbations. */
Number delta_xs_inc_fact_;
/** Decrease factor for delta_xs for later perturbations. */
Number delta_xs_dec_fact_;
/** Very first trial value for delta_xs perturbation. */
Number delta_xs_init_;
/** Size of perturbation for c and d blocks. */
Number delta_cd_val_;
/** Exponent on mu in formula for of perturbation for c and d blocks. */
Number delta_cd_exp_;
/** Flag indicating whether the new values are based on the
* perturbations in the last iteration or in the more recent
* iteration in which a perturbation was done.
*/
bool reset_last_;
/** Required number of iterations for degeneracy conclusions. */
Index degen_iters_max_;
/** Flag indicating that the delta_c, delta_d perturbation should
* always be used.
*/
bool perturb_always_cd_;
///@}
/** @name Auxiliary methods */
///@{
/** Internal version of PerturbForWrongInertia with the
* difference, that finalize_test is not called.
*
* @returns false, if the delta_x and delta_s parameters become too large.
*/
bool get_deltas_for_wrong_inertia(
Number& delta_x,
Number& delta_s,
Number& delta_c,
Number& delta_d
);
/** This method is call whenever a matrix had been factorization
* and is not singular.
*
* In here, we can evaluate the outcome of the deneracy test heuristics.
*/
void finalize_test();
/** Compute perturbation value for constraints */
Number delta_cd();
///@}
};
} // namespace Ipopt
#endif