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

Last change on this file since 414 was 414, checked in by andreasw, 14 years ago
  • several changes handling the NLP scaling
  • compute unscaled quantities in CalculatedQuantities? (such as errors)
  • print unscaled errors in output file and on console after solution
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.5 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 414 2005-07-28 15:53:28Z 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    Number dual_inf_tol() const
296    {
297      DBG_ASSERT(initialize_called_);
298      return dual_inf_tol_;
299    }
300    Number primal_inf_tol() const
301    {
302      DBG_ASSERT(initialize_called_);
303      return primal_inf_tol_;
304    }
305    Number compl_inf_tol() const
306    {
307      DBG_ASSERT(initialize_called_);
308      return compl_inf_tol_;
309    }
310    //@}
311
312    /** @name Information gathered for iteration output */
313    //@{
314    Number info_regu_x() const
315    {
316      return info_regu_x_;
317    }
318    void Set_info_regu_x(Number regu_x)
319    {
320      info_regu_x_ = regu_x;
321    }
322    Number info_alpha_primal() const
323    {
324      return info_alpha_primal_;
325    }
326    void Set_info_alpha_primal(Number alpha_primal)
327    {
328      info_alpha_primal_ = alpha_primal;
329    }
330    char info_alpha_primal_char() const
331    {
332      return info_alpha_primal_char_;
333    }
334    void Set_info_alpha_primal_char(char info_alpha_primal_char)
335    {
336      info_alpha_primal_char_ = info_alpha_primal_char;
337    }
338    Number info_alpha_dual() const
339    {
340      return info_alpha_dual_;
341    }
342    void Set_info_alpha_dual(Number alpha_dual)
343    {
344      info_alpha_dual_ = alpha_dual;
345    }
346    Index info_ls_count() const
347    {
348      return info_ls_count_;
349    }
350    void Set_info_ls_count(Index ls_count)
351    {
352      info_ls_count_ = ls_count;
353    }
354    bool info_skip_output() const
355    {
356      return info_skip_output_;
357    }
358    void Append_info_string(const std::string& add_str)
359    {
360      info_string_ += add_str;
361    }
362    const std::string& info_string() const
363    {
364      return info_string_;
365    }
366    /** Set this to true, if the next time when output is written, the
367     *  summary line should not be printed. */
368    void Set_info_skip_output(bool info_skip_output)
369    {
370      info_skip_output_ = info_skip_output;
371    }
372
373    /** Reset all info fields */
374    void ResetInfo()
375    {
376      info_regu_x_ = 0;
377      info_alpha_primal_ = 0;
378      info_alpha_dual_ = 0.;
379      info_alpha_primal_char_ = ' ';
380      info_ls_count_ = -1;
381      info_skip_output_ = false;
382      info_string_.clear();
383    }
384    //@}
385
386    /** Methods for IpoptType */
387    //@{
388    static void RegisterOptions(SmartPtr<RegisteredOptions> reg_options);
389    //@}
390
391  private:
392    /** @name Iterates */
393    //@{
394    /** Main iteration variables
395     * (current iteration) */
396    SmartPtr<const IteratesVector> curr_;
397
398    /** Main iteration variables
399     *  (trial calculations) */
400    SmartPtr<const IteratesVector> trial_;
401
402    /** Hessian (approximation) - might be changed elsewhere! */
403    SmartPtr<const SymMatrix> W_;
404
405    /** @name Primal-dual Step */
406    //@{
407    SmartPtr<const IteratesVector> delta_;
408    /** The following flag is set to true, if some other part of the
409     *  algorithm (like the method for computing the barrier
410     *  parameter) has already computed the primal-dual search
411     *  direction.  This flag is reset when the AcceptTrialPoint
412     *  method is called.
413     * ToDo: we could cue off of a null delta_;
414     */
415    bool have_deltas_;
416    //@}
417
418    /** @name Affine-scaling step.  This used to transfer the
419     *  information about the affine-scaling step from the computation
420     *  of the barrier parameter to the corrector (in the line
421     *  search). */
422    //@{
423    SmartPtr<const IteratesVector> delta_aff_;
424    /** The following flag is set to true, if some other part of the
425     *  algorithm (like the method for computing the barrier
426     *  parameter) has already computed the affine-scaling step.  This
427     *  flag is reset when the AcceptTrialPoint method is called.
428     * ToDo: we could cue off of a null delta_aff_;
429     */
430    bool have_affine_deltas_;
431    //@}
432
433    /** iteration count */
434    Index iter_count_;
435
436    /** current barrier parameter */
437    Number curr_mu_;
438    bool mu_initialized_;
439
440    /** current fraction to the boundary parameter */
441    Number curr_tau_;
442    bool tau_initialized_;
443
444    /** flag indicating if Initialize method has been called (for
445     *  debugging) */
446    bool initialize_called_;
447
448    /** flag for debugging whether we have already curr_ values
449     *  available (from which new Vectors can be generated */
450    bool have_prototypes_;
451
452    /** @name Global algorithm parameters.  Those are options that can
453     *  be modified by the user and appear at different places in the
454     *  algorithm.  They are set using an OptionsList object in the
455     *  Initialize method.  */
456    //@{
457    /** Overall convergence tolerance */
458    Number tol_;
459    /** Tolerance on unscaled dual infeasibility */
460    Number dual_inf_tol_;
461    /** Tolerance on unscaled primal infeasibility */
462    Number primal_inf_tol_;
463    /** Tolerance on unscaled complementarity */
464    Number compl_inf_tol_;
465    //@}
466
467    /** @name Gathered information for iteration output */
468    //@{
469    /** Size of regularization for the Hessian */
470    Number info_regu_x_;
471    /** Primal step size */
472    Number info_alpha_primal_;
473    /** Info character for primal step size */
474    char info_alpha_primal_char_;
475    /** Dual step size */
476    Number info_alpha_dual_;
477    /** Number of backtracking trial steps */
478    Index info_ls_count_;
479    /** true, if next summary output line should not be printed (eg
480     *  after restoration phase. */
481    bool info_skip_output_;
482    /** any string of characters for the end of the output line */
483    std::string info_string_;
484    //@}
485
486    /** @name Status data **/
487    //@{
488    /** flag indicating whether the algorithm is in the free mu mode */
489    bool free_mu_mode_;
490    /** flag indicating if a tiny step has been detected */
491    bool tiny_step_flag_;
492    //@}
493
494    /** VectorSpace for all the iterates */
495    SmartPtr<IteratesVectorSpace> iterates_space_;
496
497    /**@name Default Compiler Generated Methods
498     * (Hidden to avoid implicit creation/calling).
499     * These methods are not implemented and
500     * we do not want the compiler to implement
501     * them for us, so we declare them private
502     * and do not define them. This ensures that
503     * they will not be implicitly created/called. */
504    //@{
505    /** Copy Constructor */
506    IpoptData(const IpoptData&);
507
508    /** Overloaded Equals Operator */
509    void operator=(const IpoptData&);
510    //@}
511
512#ifdef IP_DEBUG
513    /** Some debug flags to make sure vectors are not changed
514     *  behind the IpoptData's back
515     */
516    //@{
517    TaggedObject::Tag debug_curr_tag_;
518    TaggedObject::Tag debug_trial_tag_;
519    TaggedObject::Tag debug_delta_tag_;
520    TaggedObject::Tag debug_delta_aff_tag_;
521    TaggedObject::Tag debug_curr_tag_sum_;
522    TaggedObject::Tag debug_trial_tag_sum_;
523    TaggedObject::Tag debug_delta_tag_sum_;
524    TaggedObject::Tag debug_delta_aff_tag_sum_;
525    //@}
526#endif
527
528  };
529
530  inline
531  SmartPtr<const IteratesVector> IpoptData::curr() const
532  {
533#ifdef IP_DEBUG
534    DBG_ASSERT(IsNull(curr_) || (curr_->GetTag() == debug_curr_tag_ && curr_->GetTagSum() == debug_curr_tag_sum_) );
535#endif
536
537    return curr_;
538  }
539
540  inline
541  SmartPtr<const IteratesVector> IpoptData::trial() const
542  {
543#ifdef IP_DEBUG
544    DBG_ASSERT(IsNull(trial_) || (trial_->GetTag() == debug_trial_tag_ && trial_->GetTagSum() == debug_trial_tag_sum_) );
545#endif
546
547    return trial_;
548  }
549
550  inline
551  SmartPtr<const IteratesVector> IpoptData::delta() const
552  {
553#   ifdef IP_DEBUG
554    DBG_ASSERT(IsNull(delta_) || (delta_->GetTag() == debug_delta_tag_ && delta_->GetTagSum() == debug_delta_tag_sum_) );
555#   endif
556
557    return delta_;
558  }
559
560  inline
561  SmartPtr<const IteratesVector> IpoptData::delta_aff() const
562  {
563#   ifdef IP_DEBUG
564    DBG_ASSERT(IsNull(delta_aff_) || (delta_aff_->GetTag() == debug_delta_aff_tag_ && delta_aff_->GetTagSum() == debug_delta_aff_tag_sum_) );
565#   endif
566
567    return delta_aff_;
568  }
569
570  inline
571  void IpoptData::CopyTrialToCurrent()
572  {
573    curr_ = trial_;
574#ifdef IP_DEBUG
575
576    if (IsValid(curr_)) {
577      debug_curr_tag_ = curr_->GetTag();
578      debug_curr_tag_sum_ = curr_->GetTagSum();
579    }
580    else {
581      debug_curr_tag_ = 0;
582      debug_curr_tag_sum_ = 0;
583    }
584#endif
585
586  }
587
588  inline
589  void IpoptData::set_trial(SmartPtr<IteratesVector>& trial)
590  {
591    trial_ = ConstPtr(trial);
592
593#ifdef IP_DEBUG
594    // verify the correct space
595    DBG_ASSERT(trial_->OwnerSpace() == (VectorSpace*)GetRawPtr(iterates_space_));
596    if (IsValid(trial)) {
597      debug_trial_tag_ = trial->GetTag();
598      debug_trial_tag_sum_ = trial->GetTagSum();
599    }
600    else {
601      debug_trial_tag_ = 0;
602      debug_trial_tag_sum_ = 0;
603    }
604#endif
605
606    trial = NULL;
607  }
608
609  inline
610  void IpoptData::set_delta(SmartPtr<IteratesVector>& delta)
611  {
612    delta_ = ConstPtr(delta);
613#ifdef IP_DEBUG
614
615    if (IsValid(delta)) {
616      debug_delta_tag_ = delta->GetTag();
617      debug_delta_tag_sum_ = delta->GetTagSum();
618    }
619    else {
620      debug_delta_tag_ = 0;
621      debug_delta_tag_sum_ = 0;
622    }
623#endif
624
625    delta = NULL;
626  }
627
628  inline
629  void IpoptData::set_delta_aff(SmartPtr<IteratesVector>& delta_aff)
630  {
631    delta_aff_ = ConstPtr(delta_aff);
632#ifdef IP_DEBUG
633
634    if (IsValid(delta_aff)) {
635      debug_delta_aff_tag_ = delta_aff->GetTag();
636      debug_delta_aff_tag_sum_ = delta_aff->GetTagSum();
637    }
638    else {
639      debug_delta_aff_tag_ = 0;
640      debug_delta_aff_tag_sum_ = delta_aff->GetTagSum();
641    }
642#endif
643
644    delta_aff = NULL;
645  }
646
647} // namespace Ipopt
648
649#endif
Note: See TracBrowser for help on using the repository browser.