source: branches/dev/Algorithm/IpIpoptData.hpp @ 416

Last change on this file since 416 was 416, checked in by andreasw, 14 years ago
  • revised handling of "acceptable level of accuracy" (now in ConvCheck?)
  • fixed uncaught evaluation error exceptions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.0 KB
Line 
1// Copyright (C) 2004, International Business Machines and others.
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// $Id: IpIpoptData.hpp 416 2005-07-29 19:11:41Z andreasw $
6//
7// Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
8
9#ifndef __IPIPOPTDATA_HPP__
10#define __IPIPOPTDATA_HPP__
11
12#include "IpUtils.hpp"
13#include "IpSmartPtr.hpp"
14#include "IpVector.hpp"
15#include "IpSymMatrix.hpp"
16#include "IpReferenced.hpp"
17#include "IpOptionsList.hpp"
18#include "IpIteratesVector.hpp"
19#include "IpIpoptType.hpp"
20
21namespace Ipopt
22{
23
24  DeclareIpoptType(IpoptData);
25
26  /* Forward declaration */
27  class IpoptNLP;
28
29  /** Class to organize all the data required by the algorithm.
30   *  Internally, once this Data object has been initialized, all
31   *  internal curr_ vectors must always be set (so that prototyes are
32   *  available).  The current values can only be set from the trial
33   *  values.  The trial values can be set by copying from a vector or
34   *  by adding some fraction of a step to the current values.  This
35   *  object also stores steps, which allows to easily communicate the
36   *  step from the step computation object to the line search object.
37   */
38  class IpoptData : public ReferencedObject
39  {
40  public:
41    /**@name Constructors/Destructors */
42    //@{
43    /** Constructor */
44    IpoptData();
45
46    /** Default destructor */
47    ~IpoptData();
48    //@}
49
50    /** Initialize Data Structures */
51    bool InitializeDataStructures(IpoptNLP& ip_nlp,
52                                  bool want_x,
53                                  bool want_y_c,
54                                  bool want_y_d,
55                                  bool want_z_L,
56                                  bool want_z_U);
57
58    /** This method must be called to initialize the global
59     *  algorithmic parameters.  The parameters are taken from the
60     *  OptionsList object. */
61    bool Initialize(const Journalist& jnlst,
62                    const OptionsList& options,
63                    const std::string& prefix);
64
65    /** @name Get Methods for Iterates */
66    //@{
67    /** Current point */
68    SmartPtr<const IteratesVector> curr() const;
69
70    /** Get the current point in a copied container that is non-const.
71    The entries in the container cannot be modified, but
72    the container can be modified to point to new entries.
73    */
74    //    SmartPtr<IteratesVector> curr_container() const;
75
76    /** Get Trial point */
77    SmartPtr<const IteratesVector> trial() const;
78
79    /** Get Trial point in a copied container that is non-const.
80     *  The entries in the container can not be modified, but
81     *  the container can be modified to point to new entries.
82     */
83    //SmartPtr<IteratesVector> trial_container() const;
84
85    /** Set the trial point - this method copies the pointer for
86     *  efficiency (no copy and to keep cache tags the same) so
87     *  after you call set you cannot modify the data again
88     */
89    void set_trial(SmartPtr<IteratesVector>& trial);
90
91    /** Set the values of the primal trial variables (x and s) from
92     *  provided Step with step length alpha.
93     */
94    void SetTrialPrimalVariablesFromStep(Number alpha,
95                                         const Vector& delta_x,
96                                         const Vector& delta_s);
97    /** Set the values of the trial values for the equality constraint
98     *  multipliers (y_c and y_d) from provided step with step length
99     *  alpha.
100     */
101    void SetTrialEqMultipliersFromStep(Number alpha,
102                                       const Vector& delta_y_c,
103                                       const Vector& delta_y_d);
104    /** Set the value of the trial values for the bound multipliers
105     *  (z_L, z_U, v_L, v_U) from provided step with step length
106     *  alpha.
107     */
108    void SetTrialBoundMultipliersFromStep(Number alpha,
109                                          const Vector& delta_z_L,
110                                          const Vector& delta_z_U,
111                                          const Vector& delta_v_L,
112                                          const Vector& delta_v_U);
113
114    /** ToDo: I may need to add versions of set_trial like the
115     *  following, but I am not sure
116     */
117    // void set_trial(const SmartPtr<IteratesVector>& trial_iterates);
118    // void set_trial(SmartPtr<const IteratesVector>& trial_iterates);
119
120    /** get the current delta */
121    SmartPtr<const IteratesVector> delta() const;
122
123    /** Set the current delta - like the trial point, this method copies
124     *  the pointer for efficiency (no copy and to keep cache tags the
125     *  same) so after you call set, you cannot modify the data
126     */
127    void set_delta(SmartPtr<IteratesVector>& delta);
128
129    /** Affine Delta */
130    SmartPtr<const IteratesVector> delta_aff() const;
131
132    /** Set the affine delta - like the trial point, this method copies
133     *  the pointer for efficiency (no copy and to keep cache tags the
134     *  same) so after you call set, you cannot modify the data
135     */
136    void set_delta_aff(SmartPtr<IteratesVector>& delta_aff);
137
138
139    /** Hessian or Hessian approximation (do not hold on to it, it might be changed) */
140    SmartPtr<const SymMatrix> W()
141    {
142      DBG_ASSERT(IsValid(W_));
143      return W_;
144    }
145
146    /** Set Hessian approximation */
147    void Set_W(SmartPtr<const SymMatrix> W)
148    {
149      W_ = W;
150      ;
151    }
152
153    /** @name ("Main") Primal-dual search direction.  Those fields are
154     *  used to store the search directions computed from solving the
155     *  primal-dual system, and can be used in the line search.  They
156     *  are overwritten in every iteration, so do not hold on to the
157     *  pointers (make copies instead) */
158    //@{
159
160    /** Returns true, if the primal-dual step have been already
161     *  computed for the current iteration.  This flag is reset after
162     *  every call of AcceptTrialPoint().  If the search direction is
163     *  computed during the computation of the barrier parameter, the
164     *  method computing the barrier parameter should call
165     *  SetHaveDeltas(true) to tell the IpoptAlgorithm object that it
166     *  doesn't need to recompute the primal-dual step. */
167    bool HaveDeltas() const
168    {
169      return have_deltas_;
170    }
171
172    /** Method for setting the HaveDeltas flag.  This method should be
173     *  called if some method computes the primal-dual step (and
174     *  stores it in the delta_ fields of IpoptData) at an early part
175     *  of the iteration.  If that flag is set to true, the
176     *  IpoptAlgorithm object will not recompute the step. */
177    void SetHaveDeltas(bool have_deltas)
178    {
179      have_deltas_ = have_deltas;
180    }
181    //@}
182
183    /** @name Affine-scaling step.  Those fields can be used to store
184     *  the affine scaling step.  For example, if the method for
185     *  computing the current barrier parameter computes the affine
186     *  scaling steps, then the corrector step in the line search does
187     *  not have to recompute those solutions of the linear system. */
188    //@{
189
190    /** Returns true, if the affine-scaling step have been already
191     *  computed for the current iteration.  This flag is reset after
192     *  every call of AcceptTrialPoint().  If the search direction is
193     *  computed during the computation of the barrier parameter, the
194     *  method computing the barrier parameter should call
195     *  SetHaveDeltas(true) to tell the line search does not have to
196     *  recompute them in case it wants to do a corrector step. */
197    bool HaveAffineDeltas() const
198    {
199      return have_affine_deltas_;
200    }
201
202    /** Method for setting the HaveDeltas flag.  This method should be
203     *  called if some method computes the primal-dual step (and
204     *  stores it in the delta_ fields of IpoptData) at an early part
205     *  of the iteration.  If that flag is set to true, the
206     *  IpoptAlgorithm object will not recompute the step. */
207    void SetHaveAffineDeltas(bool have_affine_deltas)
208    {
209      have_affine_deltas_ = have_affine_deltas;
210    }
211    //@}
212
213
214    /** @name Public Methods for updating iterates */
215    //@{
216    /** Copy the trial values to the current values */
217    void CopyTrialToCurrent();
218
219    /** Set the current iterate values from the
220     *  trial values. */
221    void AcceptTrialPoint();
222    //@}
223
224    /** @name General algorithmic data */
225    //@{
226    Index iter_count() const
227    {
228      return iter_count_;
229    }
230    void Set_iter_count(Index iter_count)
231    {
232      iter_count_ = iter_count;
233    }
234
235    Number curr_mu() const
236    {
237      DBG_ASSERT(mu_initialized_);
238      return curr_mu_;
239    }
240    void Set_mu(Number mu)
241    {
242      curr_mu_ = mu;
243      mu_initialized_ = true;
244    }
245    bool MuInitialized() const
246    {
247      return mu_initialized_;
248    }
249
250    Number curr_tau() const
251    {
252      DBG_ASSERT(tau_initialized_);
253      return curr_tau_;
254    }
255    void Set_tau(Number tau)
256    {
257      curr_tau_ = tau;
258      tau_initialized_ = true;
259    }
260    bool TauInitialized() const
261    {
262      return tau_initialized_;
263    }
264
265    void SetFreeMuMode(bool free_mu_mode)
266    {
267      free_mu_mode_ = free_mu_mode;
268    }
269    bool FreeMuMode() const
270    {
271      return free_mu_mode_;
272    }
273
274    /** Setting the flag that indicates if a tiny step (below machine
275     *  precision) has been detected */
276    void Set_tiny_step_flag(bool flag)
277    {
278      tiny_step_flag_ = flag;
279    }
280    bool tiny_step_flag()
281    {
282      return tiny_step_flag_;
283    }
284    //@}
285
286    /**@name Algorithm Parameters ("these will later be
287     *  moved to a specific IpoptParameters class, once
288     *  I get time to write one" - he said) */
289    //@{
290    Number tol() const
291    {
292      DBG_ASSERT(initialize_called_);
293      return tol_;
294    }
295    //@}
296
297    /** @name Information gathered for iteration output */
298    //@{
299    Number info_regu_x() const
300    {
301      return info_regu_x_;
302    }
303    void Set_info_regu_x(Number regu_x)
304    {
305      info_regu_x_ = regu_x;
306    }
307    Number info_alpha_primal() const
308    {
309      return info_alpha_primal_;
310    }
311    void Set_info_alpha_primal(Number alpha_primal)
312    {
313      info_alpha_primal_ = alpha_primal;
314    }
315    char info_alpha_primal_char() const
316    {
317      return info_alpha_primal_char_;
318    }
319    void Set_info_alpha_primal_char(char info_alpha_primal_char)
320    {
321      info_alpha_primal_char_ = info_alpha_primal_char;
322    }
323    Number info_alpha_dual() const
324    {
325      return info_alpha_dual_;
326    }
327    void Set_info_alpha_dual(Number alpha_dual)
328    {
329      info_alpha_dual_ = alpha_dual;
330    }
331    Index info_ls_count() const
332    {
333      return info_ls_count_;
334    }
335    void Set_info_ls_count(Index ls_count)
336    {
337      info_ls_count_ = ls_count;
338    }
339    bool info_skip_output() const
340    {
341      return info_skip_output_;
342    }
343    void Append_info_string(const std::string& add_str)
344    {
345      info_string_ += add_str;
346    }
347    const std::string& info_string() const
348    {
349      return info_string_;
350    }
351    /** Set this to true, if the next time when output is written, the
352     *  summary line should not be printed. */
353    void Set_info_skip_output(bool info_skip_output)
354    {
355      info_skip_output_ = info_skip_output;
356    }
357
358    /** Reset all info fields */
359    void ResetInfo()
360    {
361      info_regu_x_ = 0;
362      info_alpha_primal_ = 0;
363      info_alpha_dual_ = 0.;
364      info_alpha_primal_char_ = ' ';
365      info_ls_count_ = -1;
366      info_skip_output_ = false;
367      info_string_.clear();
368    }
369    //@}
370
371    /** Methods for IpoptType */
372    //@{
373    static void RegisterOptions(SmartPtr<RegisteredOptions> reg_options);
374    //@}
375
376  private:
377    /** @name Iterates */
378    //@{
379    /** Main iteration variables
380     * (current iteration) */
381    SmartPtr<const IteratesVector> curr_;
382
383    /** Main iteration variables
384     *  (trial calculations) */
385    SmartPtr<const IteratesVector> trial_;
386
387    /** Hessian (approximation) - might be changed elsewhere! */
388    SmartPtr<const SymMatrix> W_;
389
390    /** @name Primal-dual Step */
391    //@{
392    SmartPtr<const IteratesVector> delta_;
393    /** The following flag is set to true, if some other part of the
394     *  algorithm (like the method for computing the barrier
395     *  parameter) has already computed the primal-dual search
396     *  direction.  This flag is reset when the AcceptTrialPoint
397     *  method is called.
398     * ToDo: we could cue off of a null delta_;
399     */
400    bool have_deltas_;
401    //@}
402
403    /** @name Affine-scaling step.  This used to transfer the
404     *  information about the affine-scaling step from the computation
405     *  of the barrier parameter to the corrector (in the line
406     *  search). */
407    //@{
408    SmartPtr<const IteratesVector> delta_aff_;
409    /** The following flag is set to true, if some other part of the
410     *  algorithm (like the method for computing the barrier
411     *  parameter) has already computed the affine-scaling step.  This
412     *  flag is reset when the AcceptTrialPoint method is called.
413     * ToDo: we could cue off of a null delta_aff_;
414     */
415    bool have_affine_deltas_;
416    //@}
417
418    /** iteration count */
419    Index iter_count_;
420
421    /** current barrier parameter */
422    Number curr_mu_;
423    bool mu_initialized_;
424
425    /** current fraction to the boundary parameter */
426    Number curr_tau_;
427    bool tau_initialized_;
428
429    /** flag indicating if Initialize method has been called (for
430     *  debugging) */
431    bool initialize_called_;
432
433    /** flag for debugging whether we have already curr_ values
434     *  available (from which new Vectors can be generated */
435    bool have_prototypes_;
436
437    /** @name Global algorithm parameters.  Those are options that can
438     *  be modified by the user and appear at different places in the
439     *  algorithm.  They are set using an OptionsList object in the
440     *  Initialize method.  */
441    //@{
442    /** Overall convergence tolerance */
443    Number tol_;
444    //@}
445
446    /** @name Gathered information for iteration output */
447    //@{
448    /** Size of regularization for the Hessian */
449    Number info_regu_x_;
450    /** Primal step size */
451    Number info_alpha_primal_;
452    /** Info character for primal step size */
453    char info_alpha_primal_char_;
454    /** Dual step size */
455    Number info_alpha_dual_;
456    /** Number of backtracking trial steps */
457    Index info_ls_count_;
458    /** true, if next summary output line should not be printed (eg
459     *  after restoration phase. */
460    bool info_skip_output_;
461    /** any string of characters for the end of the output line */
462    std::string info_string_;
463    //@}
464
465    /** @name Status data **/
466    //@{
467    /** flag indicating whether the algorithm is in the free mu mode */
468    bool free_mu_mode_;
469    /** flag indicating if a tiny step has been detected */
470    bool tiny_step_flag_;
471    //@}
472
473    /** VectorSpace for all the iterates */
474    SmartPtr<IteratesVectorSpace> iterates_space_;
475
476    /**@name Default Compiler Generated Methods
477     * (Hidden to avoid implicit creation/calling).
478     * These methods are not implemented and
479     * we do not want the compiler to implement
480     * them for us, so we declare them private
481     * and do not define them. This ensures that
482     * they will not be implicitly created/called. */
483    //@{
484    /** Copy Constructor */
485    IpoptData(const IpoptData&);
486
487    /** Overloaded Equals Operator */
488    void operator=(const IpoptData&);
489    //@}
490
491#ifdef IP_DEBUG
492    /** Some debug flags to make sure vectors are not changed
493     *  behind the IpoptData's back
494     */
495    //@{
496    TaggedObject::Tag debug_curr_tag_;
497    TaggedObject::Tag debug_trial_tag_;
498    TaggedObject::Tag debug_delta_tag_;
499    TaggedObject::Tag debug_delta_aff_tag_;
500    TaggedObject::Tag debug_curr_tag_sum_;
501    TaggedObject::Tag debug_trial_tag_sum_;
502    TaggedObject::Tag debug_delta_tag_sum_;
503    TaggedObject::Tag debug_delta_aff_tag_sum_;
504    //@}
505#endif
506
507  };
508
509  inline
510  SmartPtr<const IteratesVector> IpoptData::curr() const
511  {
512#ifdef IP_DEBUG
513    DBG_ASSERT(IsNull(curr_) || (curr_->GetTag() == debug_curr_tag_ && curr_->GetTagSum() == debug_curr_tag_sum_) );
514#endif
515
516    return curr_;
517  }
518
519  inline
520  SmartPtr<const IteratesVector> IpoptData::trial() const
521  {
522#ifdef IP_DEBUG
523    DBG_ASSERT(IsNull(trial_) || (trial_->GetTag() == debug_trial_tag_ && trial_->GetTagSum() == debug_trial_tag_sum_) );
524#endif
525
526    return trial_;
527  }
528
529  inline
530  SmartPtr<const IteratesVector> IpoptData::delta() const
531  {
532#   ifdef IP_DEBUG
533    DBG_ASSERT(IsNull(delta_) || (delta_->GetTag() == debug_delta_tag_ && delta_->GetTagSum() == debug_delta_tag_sum_) );
534#   endif
535
536    return delta_;
537  }
538
539  inline
540  SmartPtr<const IteratesVector> IpoptData::delta_aff() const
541  {
542#   ifdef IP_DEBUG
543    DBG_ASSERT(IsNull(delta_aff_) || (delta_aff_->GetTag() == debug_delta_aff_tag_ && delta_aff_->GetTagSum() == debug_delta_aff_tag_sum_) );
544#   endif
545
546    return delta_aff_;
547  }
548
549  inline
550  void IpoptData::CopyTrialToCurrent()
551  {
552    curr_ = trial_;
553#ifdef IP_DEBUG
554
555    if (IsValid(curr_)) {
556      debug_curr_tag_ = curr_->GetTag();
557      debug_curr_tag_sum_ = curr_->GetTagSum();
558    }
559    else {
560      debug_curr_tag_ = 0;
561      debug_curr_tag_sum_ = 0;
562    }
563#endif
564
565  }
566
567  inline
568  void IpoptData::set_trial(SmartPtr<IteratesVector>& trial)
569  {
570    trial_ = ConstPtr(trial);
571
572#ifdef IP_DEBUG
573    // verify the correct space
574    DBG_ASSERT(trial_->OwnerSpace() == (VectorSpace*)GetRawPtr(iterates_space_));
575    if (IsValid(trial)) {
576      debug_trial_tag_ = trial->GetTag();
577      debug_trial_tag_sum_ = trial->GetTagSum();
578    }
579    else {
580      debug_trial_tag_ = 0;
581      debug_trial_tag_sum_ = 0;
582    }
583#endif
584
585    trial = NULL;
586  }
587
588  inline
589  void IpoptData::set_delta(SmartPtr<IteratesVector>& delta)
590  {
591    delta_ = ConstPtr(delta);
592#ifdef IP_DEBUG
593
594    if (IsValid(delta)) {
595      debug_delta_tag_ = delta->GetTag();
596      debug_delta_tag_sum_ = delta->GetTagSum();
597    }
598    else {
599      debug_delta_tag_ = 0;
600      debug_delta_tag_sum_ = 0;
601    }
602#endif
603
604    delta = NULL;
605  }
606
607  inline
608  void IpoptData::set_delta_aff(SmartPtr<IteratesVector>& delta_aff)
609  {
610    delta_aff_ = ConstPtr(delta_aff);
611#ifdef IP_DEBUG
612
613    if (IsValid(delta_aff)) {
614      debug_delta_aff_tag_ = delta_aff->GetTag();
615      debug_delta_aff_tag_sum_ = delta_aff->GetTagSum();
616    }
617    else {
618      debug_delta_aff_tag_ = 0;
619      debug_delta_aff_tag_sum_ = delta_aff->GetTagSum();
620    }
621#endif
622
623    delta_aff = NULL;
624  }
625
626} // namespace Ipopt
627
628#endif
Note: See TracBrowser for help on using the repository browser.