1 // (C) Copyright International Business Machines Corporation, Carnegie Mellon University 2006
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // Pierre Bonami, Carnegie Mellon University,
7 // Andreas Waechter, International Business Machines Corporation
8 //
9 // Date : 02/15/2006
10 
11 
12 #ifndef IpoptWarmStart_HPP
13 #define IpoptWarmStart_HPP
14 #include "CoinWarmStartBasis.hpp"
15 #include "CoinWarmStartPrimalDual.hpp"
16 #include "BonIpoptInteriorWarmStarter.hpp"
17 
18 
19 namespace Bonmin
20 {
21   class TMINLP2TNLP;
22 
23   /** \brief Class for storing warm start informations for Ipopt.<br>
24    * This class inherits from CoinWarmStartPrimalDual, because that's what
25    * this warmstart really is. <br>
26    * For practical reason (integration in Cbc) this class also inherits from
27    * CoinWarmStartBasis. <br>
28    * This class stores a starting point (primal and dual values) for Ipopt.
29    * <br>
30    * <p>
31    * The primal part of the base class contains the value of each primal
32    * variable.
33    * <p>
34    * The dual part of the base class consists of three sections (the number of
35    * values is 2*numcols+numrows):
36      <UL>
37      <li> First, values for dual variables associated with the lower bound
38           constraints on structurals, i.e., primal variables (constraints
39 	  \f$ l \leq x \f$);
40      <li> Then values for dual variables associated with upper bound
41            constraints on structurals (constraints \f$ x \leq u\f$).
42      <li> the values for dual variables associated with regular constraints
43           (constraints \f$ g(x) \leq 0 \f$)
44      </UL>
45    */
46   class IpoptWarmStart :
47     public virtual CoinWarmStartPrimalDual, public virtual CoinWarmStartBasis
48   {
49   public:
50 
51     /// Default constructor
52     IpoptWarmStart(bool empty = 1, int numvars = 0, int numcont = 0);
53     /// Usefull constructor, stores the current optimum of ipopt
54     IpoptWarmStart(const Ipopt::SmartPtr<TMINLP2TNLP> tnlp,
55         Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter);
56     /// Another usefull constructor, stores the passed point
57     IpoptWarmStart(int primal_size, int dual_size,
58                    const double * primal, const double * dual);
59     /// Copy constructor
60     IpoptWarmStart( const IpoptWarmStart &other, bool ownValues = 1);
61     /// A constructor from a CoinWarmStartPrimalDual
62     IpoptWarmStart(const CoinWarmStartPrimalDual& pdws);
63     /// Abstract destructor
64     virtual ~IpoptWarmStart();
65 
66     /// `Virtual constructor'
clone() const67     virtual CoinWarmStart *clone() const
68     {
69       return new IpoptWarmStart(*this,1);
70     }
71 
72     /** Generate the "differences" between two IpoptWarmStart.*/
73     virtual CoinWarmStartDiff*
74     generateDiff(const CoinWarmStart *const oldCWS) const;
75     /** \brief Apply 'differences' to an Ipopt warm start.
76      * What this actually does is get a copy to the vector of values stored
77      in IpoptWarmStartDiff.*/
78     virtual void
79     applyDiff (const CoinWarmStartDiff *const cwsdDiff);
80 
81     /** Accessor to warm start information obecjt */
warm_starter() const82     Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter() const
83     {
84       return warm_starter_;
85     }
86 
87     /// flush the starting point
88     void flushPoint();
89 
90     ///Is this an empty warm start?
empty() const91     bool empty() const
92     {
93       return empty_;
94     }
95   private:
96     /** warm start information object */
97     mutable Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter_;
98     ///Say if warm start is empty
99     bool empty_;
100   };
101 
102   //###########################################################################
103 
104   /** \brief Diff class for IpoptWarmStart.
105    * Actually get the differences from CoinWarmStartBasis and stores the
106    whole vector of values.
107    \todo Find a way to free unused values.
108   */
109   class IpoptWarmStartDiff : public CoinWarmStartPrimalDualDiff
110   {
111   public:
112     friend class IpoptWarmStart;
113     /** Useful constructor; takes over the data in \c diff */
IpoptWarmStartDiff(CoinWarmStartPrimalDualDiff * diff,Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter)114     IpoptWarmStartDiff(CoinWarmStartPrimalDualDiff * diff,
115 		       Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter):
116       CoinWarmStartPrimalDualDiff(),
117       warm_starter_(NULL)//(warm_starter)
118     {
119       CoinWarmStartPrimalDualDiff::swap(*diff);
120     }
121     /** Copy constructor. */
IpoptWarmStartDiff(const IpoptWarmStartDiff & other)122     IpoptWarmStartDiff(const IpoptWarmStartDiff &other):
123         CoinWarmStartPrimalDualDiff(other),
124         warm_starter_(NULL /*other.warm_starter_*/) {}
125 
126     /// Abstract destructor
~IpoptWarmStartDiff()127     virtual ~IpoptWarmStartDiff() {}
128 
129     /// `Virtual constructor'
clone() const130     virtual CoinWarmStartDiff *clone() const
131     {
132       return new IpoptWarmStartDiff(*this);
133     }
134 
135     /** Accessor to warm start information obecjt */
warm_starter() const136     Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter() const
137     {
138       return warm_starter_;
139     }
140     void flushPoint();
141   private:
142 
143     /** warm start information object */
144     Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter_;
145   };
146 
147 }
148 #endif
149