1 // $Id: HOPSPACK_LinConstr.hpp 208 2012-08-01 22:59:33Z tplante $
2 // $URL: https://software.sandia.gov/svn/hopspack/trunk/src/src-shared/HOPSPACK_LinConstr.hpp $
3 
4 //@HEADER
5 // ************************************************************************
6 //
7 //         HOPSPACK: Hybrid Optimization Parallel Search Package
8 //                 Copyright 2009-2010 Sandia Corporation
9 //
10 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
11 // the U.S. Government retains certain rights in this software.
12 //
13 // This file is part of HOPSPACK.
14 //
15 // HOPSPACK is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU Lesser General Public License as
17 // published by the Free Software Foundation; either version 2.1 of the
18 // License, or (at your option) any later version.
19 //
20 // This library is distributed in the hope that it will be useful, but
21 // WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 // Lesser General Public License for more details.
24 //
25 // You should have received a copy of the GNU Lesser General Public
26 // License along with this library.  If not, see http://www.gnu.org/licenses/.
27 //
28 // Questions? Contact Tammy Kolda (tgkolda@sandia.gov)
29 //                 or Todd Plantenga (tplante@sandia.gov)
30 //
31 // ************************************************************************
32 //@HEADER
33 
34 /*!
35   \file HOPSPACK_LinConstr.hpp
36   \brief Class declaration for HOPSPACK::LinConstr.
37 */
38 
39 #ifndef HOPSPACK_LINCONSTR_HPP
40 #define HOPSPACK_LINCONSTR_HPP
41 
42 #include "HOPSPACK_common.hpp"
43 #include "HOPSPACK_Matrix.hpp"
44 #include "HOPSPACK_ParameterList.hpp"
45 #include "HOPSPACK_ProblemDef.hpp"
46 #include "HOPSPACK_Vector.hpp"
47 
48 namespace HOPSPACK
49 {
50 
51 //! Contains general linear constraints and methods for using them.
52 /*!
53   HOPSPACK can be configured at build time to exclude linking an LAPACK library,
54   which means linear constraints cannot be used.  The configuration appears
55   in the code as preprocessing symbol HAVE_LAPACK.  However, simple variable
56   bounds are also a type of linear constraint, so instances of this
57   class can be constructed even if general linear constraints are excluded.
58 
59   Consider the following linearly constrained problem
60   \f[
61     \begin{array}{rlcrcl}
62     \displaystyle\mbox{minimize} & \multicolumn{5}{c}{f(x)} \\
63     x \in R^n \\
64     \mbox{subject to} & b^{\rm lower} & \le & x & \le & b^{\rm upper}\\
65     & b^{\rm ineq\_lower} & \le & A^{\rm ineq} x & \le & b^{\rm ineq\_upper} \\
66     & & & A^{\rm eq} x & = & b^{\rm eq}
67     \end{array}
68   \f]
69   Note that inequality bounds may be infinite (i.e., unbounded).
70   A variable may be fixed by setting identical lower and upper bounds, or by
71   defining a linear equality.
72 
73   Variables are always scaled and shifted, and linear constraint computations
74   are made in the scaled and shifted problem space.
75   The scaling vector is denoted by \f$ s \f$, specified in ProblemDef, and
76   defined so that all components are positive and finite.
77   Variable shifting moves the lower bound to zero.
78 
79   Scaled and shifted quantities are:
80   \f[
81     \begin{array}{lcl}
82     \tilde{x}                   &=& S^{-1}(x - \hat{\ell})  \\
83     {\tilde f(\tilde x)}        &=& f(S \tilde x + \hat{\ell}) = f(x) \\
84     \tilde{b}^{\rm lower}       &=& S^{-1}(b^{\rm lower} - \hat{\ell}) \\
85     \tilde{b}^{\rm upper}       &=& S^{-1}(b^{\rm upper} - \hat{\ell}) \\
86     \tilde{b}^{\rm ineq\_lower}
87         &=& b^{\rm ineq\_lower} - A^{\rm ineq} \hat{\ell} \\
88     \tilde{b}^{\rm ineq\_upper}
89         &=& b^{\rm ineq\_upper} - A^{\rm ineq} \hat{\ell} \\
90     \tilde{b}^{\rm eq}          &=& b^{\rm eq} - A^{\rm eq} \hat{\ell} \\
91     \tilde{A}^{\rm ineq}        &=& A^{\rm ineq} S \\
92     \tilde{A}^{\rm eq}          &=& A^{\rm eq} S
93     \end{array}
94   \f]
95   where
96   \f[
97     S = \left(\begin{array}{ccc}
98     s_1 \\
99     & \ddots \\
100     & &  s_n
101     \end{array}\right)
102   \f]
103   \f[
104     \hat{\ell}_ = \left\{
105       \begin{array}{cl}
106       b^{\rm lower}_i & {\rm if } \; b^{\rm lower}_i > -\infty \\
107       0 & {\rm otherwise}.
108       \end{array}
109     \right.
110   \f]
111 
112   The scaled problem is then given by
113   \f[
114     \begin{array}{rlcrcl}
115     \displaystyle\mbox{minimize} & \multicolumn{5}{c}{\tilde f(\tilde x)} \\
116     \tilde x \in R^n \\
117     \mbox{subject to}
118       & \tilde b^{\rm lower} & \le & \tilde x & \le & \tilde b^{\rm upper} \\
119       & \tilde b^{\rm ineq\_lower} & \le & \tilde A^{\rm ineq} \tilde x
120           & \le & \tilde b^{\rm ineq\_upper} \\
121       & & & \tilde A^{\rm eq} \tilde x & = & \tilde b^{\rm eq}
122     \end{array}
123   \f]
124 
125   Internally, the code combines bound and linear inequality constraints into
126   one matrix, giving
127   \f[
128     \begin{array}{rlcrcl}
129     \displaystyle\mbox{minimize} & \multicolumn{5}{c}{\tilde f(\tilde x)} \\
130     \tilde x \in R^n \\
131     \mbox{subject to}
132       & \hat b^{\rm lower} & \le & \hat A^{\rm ineq} \tilde x & \le
133           & \hat b^{\rm upper} \\
134       & & & \tilde A^{\rm eq} \tilde x & = & \tilde b^{\rm eq}
135     \end{array}
136   \f]
137   where
138   \f[
139     \begin{array}{ccccc}
140     \hat{b}^{\rm lower} = \left(
141       \begin{array}{l}
142       \tilde{b}^{\rm lower} \\
143       \tilde{b}^{\rm ineq\_lower}
144       \end{array}
145     \right),
146     & &
147     \hat{b}^{\rm upper} = \left(
148       \begin{array}{l}
149       \tilde{b}^{\rm upper} \\
150       \tilde{b}^{\rm ineq\_upper}
151       \end{array}
152     \right),
153     & &
154     \hat{A} = \left(
155       \begin{array}{l}
156       I \\
157       \tilde{A}^{\rm ineq}
158       \end{array}
159     \right).
160     \end{array}
161   \f]
162 */
163 class LinConstr
164 {
165 
166 public:
167 
168   /*! \brief State of one constraint with respect to both its upper and lower
169     bounds and a given point.
170 
171     A linear constraint is declared active at a point if the scaled distance
172     to the constraint is within tolerance \f$ \epsilon \f$.
173     The point does not have to be feasible.
174     If \f$ \epsilon \f$ is sufficiently large, it is possible that both upper
175     and lower bounds may be considered active.
176   */
177   enum ActiveType {
178     //! Constraint is not active at the point.
179     NEITHER_ACTIVE = 0,
180     //! Lower bound on constraint is active at the point.
181     LOWER_ACTIVE,
182     //! Upper bound on constraint is active at the point.
183     UPPER_ACTIVE,
184     //! Both upper and lower bounds on constraint are active at the point.
185     BOTH_ACTIVE
186   };
187 
188 
189   //! Constructor.
190   /*!
191    *  @param[in] probDef  Problem definition with scaling and bounds.
192    */
193   LinConstr (const ProblemDef &  probDef);
194 
195   //! Copy constructer that can exclude equalities.
196   /*!
197    *  @param[in] cOther    Linear constraint set that will be copied over.
198    *  @param[in] bDropEqs  True means equalities are suppressed.
199    *  @return              False if fatal error encountered.
200    */
201   LinConstr (const LinConstr &  cOther,
202              const bool         bDropEqs);
203 
204   //! Destructor.
205   ~LinConstr();
206 
207   //! Initialize the definition from user input parameters.
208   /*!
209    *  @param[in] cLinConstrParams  Sublist of "Linear Constraints" user
210    *                               parameters (may be empty).
211    *  @return                      False if fatal error encountered.
212    */
213   bool  initialize (const ParameterList &  cLinConstrParams);
214 
215   //@{ \name Accessors
216   //! Return value that determines feasibility and activity of a constraint.
217   /*!
218    *  The default is a small multiple of machine epsilon, but this might
219    *  be too tight depending on the condition of the active constraints.
220    */
221   double getActiveTol() const;
222 
223   //! Return true if there are linear constraints in addition to variable bounds.
224   bool hasLinearConstraints() const;
225 
226   //! Return coefficient matrix for scaled and shifted inequality constraints.
227   /*!
228    *  The first n rows are the identity matrix, representing bound constraints.
229    *  The next m rows are linear inequality constraints.
230    *  Methods getBhatLower() and getBhatUpper() return vectors of length n+m
231    *  that provide lower and upper bounds on Ahat.
232    */
233   const Matrix & getAhat() const;
234 
235   //! Return lower bounds for scaled and shifted inequality constraints.
236   /*!
237    *  The first n rows are lower bounds on constraints.
238    *  The next m rows are lower bounds on linear inequality constraints.
239    *  A value of DNE means there is no bound on the constraint.
240    */
241   const Vector & getBhatLower() const;
242 
243   //! Return upper bounds for scaled and shifted inequality constraints.
244   /*!
245    *  The first n rows are upper bounds on constraints.
246    *  The next m rows are upper bounds on linear inequality constraints.
247    *  A value of DNE means there is no bound on the constraint.
248    */
249   const Vector & getBhatUpper() const;
250 
251   //! Return coefficient matrix for scaled and shifted equality constraints.
252   const Matrix & getAtildeEq() const;
253 
254   //! Return right-hand side for scaled and shifted equality constraints.
255   const Vector & getBtildeEq() const;
256 
257   //@}
258 
259   //@{ \name  Feasibility verification methods.
260 
261   //! Return true if feasible, false otherwise.
262   /*!
263     Simple bounds, linear inequalities, and linear equalities are checked.
264     A point is feasible with respect to a given inequality if it satisfies
265     the constraint or its scaled distance is within getActiveTol().
266     A point is feasible with respect to a given equality if its scaled
267     distance is within getActiveTol().
268 
269     \param[in] x                    The point to check, unscaled.
270     \param[in] bPrintViolationInfo  If true, print the extent that a constraint
271                                     is violated.
272   */
273   bool isFeasible(const Vector& x,
274                   const bool bPrintViolationInfo = false) const;
275 
276   //! Return the L2 norm of the constraint violations at x.
277   /*!
278    *  Variable bounds, linear equalities, and linear inequalities are
279    *  included.  The result is the L2 norm of the unscaled bound and constraint
280    *  violations.
281    */
282   double  getL2Norm (const Vector &  x) const;
283 
284   //! Return the unscaled infinity norm of the constraint violations at x.
285   /*!
286    *  Variable bounds, linear equalities, and linear inequalities are
287    *  included.  The result is the largest unscaled violation of a bound or
288    *  general linear constraint.
289    */
290   double  getLInfNorm (const Vector &  x) const;
291 
292   //@}
293 
294 
295   //@{ \name Transformation methods.
296   //! Replace x with a scaled and shifted version.
297   /*!
298     The affine transformation is \f$x\f$ with \f$ S^{-1} (x - \hat{\ell}) \f$.
299    */
300   void scale(Vector& x) const;
301 
302   //! Replace w with an unscaled version.
303   /*!
304     The affine transformation is \f$w\f$ with \f$ Sw + \hat{\ell} \f$.
305   */
306   void unscale(Vector& w) const;
307 
308   //@}
309 
310 
311   //@{ \name Constraint analysis.
312 
313   //! Returns maximum feasible step in the interval [0, step] along direction d.
314   /*!
315     \param[in] x Current point, unscaled.
316     \param[in] d Search direction, which must be in the null space of all
317                  equality constraints.
318     \param[in] maxLength Maximum step length, unscaled.
319 
320     On exit a nonnegative scalar \f$ \alpha \f$ is returned
321     that gives the maximum feasible step that can be made
322     along direction d.
323     The method finds all \a blocking \a constraints and then the minimum
324     distance to the first such constraint.
325     An inequality is a blocking constraint if the search direction has a
326     numerically significant component pointing towards its infeasible region.
327     Let \f$ \epsilon \f$ be the value returned by getActiveTol().
328     An inequality is blocking if it satisfies the following condition:
329 
330     \f[
331       \begin{array}{lccl}
332         \mbox{For finite variable lower bound $i$:}
333           & d_i & < & - \epsilon \times scaling_i \\
334         \mbox{For finite variable upper bound $i$:}
335           & d_i & > &   \epsilon \times scaling_i \\
336         \mbox{For linear inequality $a_i^T x \leq b_i$:}
337           & a_i^T d & > & \epsilon
338       \end{array}
339     \f]
340 
341     If any blocking inequality constraint is deemed active according to
342     getIneqState(), then a value of zero is returned.
343     Also, if the search direction d is not in the null space of the equality
344     constraints, then a value of zero is returned.
345     Otherwise,
346     \f[
347       \alpha = {\rm min} \left( \{\Delta\} \cup
348       \left\{ \frac{b_i - a_i^T x}{a_i^T d} \Big |\;
349           i \in \mathcal{B} \right\} \right)
350     \f]
351     is returned, where \f$ \mathcal{B} \f$ denotes the set of blocking
352     inequality constraints, and \f$ \Delta \f$ is maxLength.
353 
354     \note
355     Linear algebra roundoff error may cause the step to go slightly beyond
356     the variable bounds (as well as slightly off the general linear
357     constraints).  Variable bound violations are often considered serious;
358     hence, new points computed from the step should be checked using
359     isBndsFeasible() in HOPSPACK::ProblemDef.
360   */
361   double maxStep(const Vector& x, const Vector& d, double maxLength) const;
362 
363   //! Fill in the active/inactive state of all inequality constraints.
364   /*!
365     The ith inequality constraint is considered active at its lower bound if
366     \f[
367       {\rm  xdist}(i)  <  {\rm epsilon}.
368     \f]
369 
370     \param xdist Contains the scaled distance to each inequality constraint from
371                  a given point, as computed by formDistanceVector().
372     \param epsilon Tolerance for determining if a constraint is active.
373     \param index Vector with \f$ n+m \f$ entries, where \f$ n \f$ is the number
374     of variables and \f$ m \f$ the number of linear inequality constraints.
375     On exit each index[i] is set to one ActiveType value:
376     - index[i] = NEITHER_ACTIVE if the \f$i_{ith}\f$ constraint is
377     inactive at both its lower and upper bounds.
378     - index[i] = LOWER_ACTIVE if the \f$i_{ith}\f$ constraint is
379     active at its lower bound, but not its upper bound.
380     - index[i] = UPPER_ACTIVE if the \f$i_{ith}\f$ constraint is
381     active at its upper bound, but not its lower bound.
382     - index[i] = BOTH_ACTIVE if the \f$i_{ith}\f$ constraint is
383     active at both its upper and lower bound.
384   */
385   void getActiveIneqIndices(const Vector& xdist,
386                             double epsilon,
387                             vector<ActiveType>& index) const;
388 
389   //! Return the scaled, projected distance from x to each inequality.
390   /*!
391     \param x (input) The given point, unscaled.
392     \param xdist (output) Vector of length \f$ 2 (n+m) \f$, where \f$ n \f$ is
393     the number of variables and \f$ m \f$ the number of inequality constraints.
394     The first \f$ n+m \f$ elements are filled with the distance from x to each
395     lower bound, and the second \f$ n+m \f$ elements filled with distances
396     to upper bounds.
397 
398     The method computes distance constrained to movement within the
399     nullspace of the equality constraints.
400     The point is scaled, and the distance is computed for the scaled version
401     of the constraints.
402 
403     The lower and upper inequality bounds are treated separately by stacking
404     as follows:
405     \f[
406       \left( \begin{array}{r} -\hat A^{\rm ineq} \\
407              \hat A^{\rm ineq} \end{array}
408       \right)
409       \tilde x \le
410       \left( \begin{array}{r} -\hat b^{\rm lower} \\
411              \hat b^{\rm upper}\end{array}
412       \right).
413     \f]
414     Let \f$ Z \f$ be a matrix whose columns form an orthonormal basis for
415     the null space of \f$ \tilde A^{eq} \f$,
416     let \f$ \epsilon \f$ be the value returned by getActiveTol(),
417     and define
418     \f[
419       C = \left( \begin{array}{r} -\hat A^{\rm ineq} \\
420                  \hat A^{\rm ineq} \end{array}
421           \right),
422       \; {\rm and } \quad \;
423       d = \left( \begin{array}{r} -\hat b^{\rm lower} \\
424                  \hat b^{\rm upper}\end{array}
425           \right),
426     \f]
427     Then xdist is
428     \f[
429       {\rm xdist}(i) = \left\{
430         \begin{array}{ll}
431           | c_i^T \tilde x - d_i | / \|Z^T c_i\|_2
432               & {\rm if } \; \|Z^T c_i\| > \epsilon, \\
433           0   & {\rm if }  \; \|Z^T c_i \| < \epsilon,
434                 \;{\rm and }\; |c_i^T \tilde x - d_i| < \epsilon, \\
435           \infty
436               & {\rm if } \; \|Z^T c_i \| < \epsilon,
437                 \;{\rm and }\; |c_i^T \tilde x - d_i| > \epsilon.
438         \end{array}
439       \right.
440     \f]
441     If \f$ |d_i| = \infty \f$ then \f$ {\rm xdist}(i) = \infty \f$.
442 
443     \note
444     In exact arithmetic, the
445     distance \f$ r(x,a,b) \f$ from a point \f$ x \f$ to the constraint
446     \f$ a^T y \le b \f$ within the space spanned by orthonormal
447     matrix \f$ Z \f$ is given by
448     \f[
449       r(x,a,b) = \left\{
450         \begin{array}{ll}
451         | a^T x - b | / \|Z^T a\|_2 & {\rm if }\;  Z^T a \ne 0, \\
452         0 & {\rm if } \;  Z^T a = 0 \; {\rm and } \; |a^T x - b| = 0, \\
453         \infty & {\rm if }\; Z^T a  = 0 \; {\rm and } \; |a^T x - b| > 0. \\
454         \end{array}
455       \right.
456     \f]
457   */
458   void formDistanceVector(const Vector& x, Vector& xdist) const;
459 
460   //! Find the closest point that lies on all linear constraints within a given distance.
461   /*!
462      \param[in,out] x Current point, replaced by snapped point.
463                       In both cases the point is unscaled.
464      \param[in] esnap Radius of a ball about x that defines "nearby" constraints.
465 
466      The primary purpose of this method is to quickly guess a solution point
467      at the "corner" of the feasible region.
468      Many derivative-free algorithms will "half-step" towards a boundary,
469      asymptotically approaching it.  If the solution is on the boundary, then
470      convergence to a specified tolerance may take a long time.  Snapping to
471      the constraint is faster, and more accurate if the solution is at a corner.
472 
473      This method computes the closest point to the current x that satisfies
474      all linear constraints lying within the distance esnap.
475      If x violates any linear equality constraints, then the method only
476      computes a point satisfying the equality constraints.
477 
478      The method begins by scaling the variables and determining all "nearby"
479      inequality constraints using the argument esnap.
480      A matrix \f$ A_{\rm esnap} \f$ is then formed that consists of the rows
481      \f$ \tilde A^{Eq} \f$ followed by the rows of \f$ \hat A \f$ that
482      correspond to "nearby" constraints.
483      An LQ factorization is formed and \f$ A_{\rm esnap} \f$ redefined if
484      necessary to have full row rank, based on the value of getActiveTol().
485      The corresponding right-hand side vector \f$ b_{\rm esnap} \f$ is
486      also formed.
487 
488      To find the point, the method solves an equality-constrained linear least
489      squares problem and replaces x with the solution \f$ y^{*} \f$:
490      \f[
491        \begin{array}{cc}
492          \mbox{minimize}    & \|y - x\| \\
493          \mbox{subject to}  & A_{\rm esnap} y = b_{\rm esnap}.
494        \end{array}
495      \f]
496   */
497   void snapToBoundary(Vector& x, double esnap) const;
498 
499   //! Find the closest point to x that satisfies all constraints.
500   /*!
501      \param[in,out] x Current point, replaced by feasible point.
502                       In both cases the point is unscaled.
503      \return          true if successful.
504 
505      The modified point will be feasible with respect to linear constraints
506      and bound constraints.
507   */
508   bool  projectToFeasibility (Vector &  x) const;
509 
510   //@}
511 
512   //! Print the linear constraint definition.
513   /*!
514    *  @param [in]  bDisplayFull  If true, display all constraint details,
515    *                             else just a summary.
516    */
517   void printDefinition (const bool  bDisplayFull) const;
518 
519 private:
520 
521   /*! \brief State of either the upper or lower (not both) bound of a
522     constraint with respect to a given point.
523   */
524   enum StateType {
525     //! Constraint does not exist, i.e., bound is \f$ \pm \infty \f$.
526     DNE,
527     //! Constraint is violated at the point.
528     VIOLATED,
529     //! Constraint is active at the point (within a tolerance).
530     ACTIVE,
531     //! Constraint is not active and the point is feasible.
532     INACTIVE
533   };
534 
535   //! Specify upper or lower bound type
536   enum BoundType {
537     //! Upper bound
538     UPPER_BOUND,
539     //! Lower bound
540     LOWER_BOUND
541   };
542 
543   //! By design, there is no copy constructor.
544   LinConstr (const LinConstr &);
545   //! By design, there is assignment operator.
546   LinConstr & operator= (const LinConstr &);
547 
548   //@{ \name Constructor helper methods.
549 
550   //! Read the coefficient matrix for linear constraints.
551   bool setupMatrix(const ParameterList& params);
552 
553   //! Read the right-hand side for linear constraints.
554   bool setupRhs(const ParameterList& params);
555 
556   //! Form the scaled system of constraints.
557   bool setupScaledSystem();
558 
559   //@}
560 
561   //@{ \name Constraint categorizers.
562 
563   //! Return the state of inequality constraint i with respect to a given point.
564   /*!
565     Computes the state of inequality constraint i with respect to the scaled
566     point \f$ \tilde x \f$.  The scaled distance to the constraint is calculated
567     as
568 
569     \f[
570       \frac{ | (\hat a_i^{\rm ineq})^T \tilde x - \hat b_i^{\rm lower} | }
571            { \| \hat a_i^{\rm ineq} \| } \leq \epsilon
572     \f]
573     If the scaled distance is within plus or minus getActiveTol(), then the
574     constraint is deemed ACTIVE.  If feasible and more than getActiveTol() away,
575     then the constraint is INACTIVE.  If infeasible and more than getActiveTol()
576     away, then it is VIOLATED.
577 
578     \param i (input) Constraint index.  Let \f$ n \f$ be the number
579              of variables and \f$m\f$ the number of linear inequality
580              constraints.  Constraints 0 thru \f$ n-1 \f$ correspond to
581              variable bounds, and constraints \f$ n \f$ thru \f$ n+m-1 \f$
582              correspond to linear inequalities.
583     \param bType (input) Request UPPER or LOWER bound.
584     \param xTilde (input) Scaled and shifted vector.
585     \param bPrintViolationInfo (input) If true, then print violation info.
586   */
587   StateType getIneqState(const int       i,
588                          const BoundType bType,
589                          const Vector&   xTilde,
590                          const bool      bPrintViolationInfo = false) const;
591 
592   //! Return the state of equality constraint i with respect to a given point.
593   /*!
594     Computes the state of equality constraint i with respect to the scaled
595     point \f$ \tilde x \f$.  The scaled distance to the constraint is calculated
596     as
597 
598     \f[
599       \frac{ | (\tilde a_i^{\rm eq})^T \tilde x - \tilde b_i^{\rm eq} | }
600            { \| \tilde a_i^{\rm eq} \| } \leq epsilon
601     \f]
602     If the scaled distance is within plus or minus getActiveTol(), then the
603     constraint is deemed ACTIVE.
604 
605     \param i (input) Constraint index.  Let \f$ n \f$ be the number
606              of variables and \f$ m \f$ the number of linear equality
607              constraints  Constraints 0 thru \f$ n-1 \f$ correspond to
608              variable bounds, and constraints \f$ n \f$ thru \f$ n+m-1 \f$
609              correspond to linear equalities.
610     \param xTilde (input) Scaled and shifted vector.
611     \param bPrintViolationInfo (input) If true, then print violation info.
612   */
613   StateType getEqState(const int     i,
614                        const Vector& xTilde,
615                        const bool    bPrintViolationInfo = false) const;
616 
617   //! Return true if getEqState() finds all equality constraints are feasible.
618   bool isEqualityFeasible(const Vector& xtilde,
619                           const bool    bPrintViolationInfo = false) const;
620 
621   //! Return true if getIneqState() finds all inequality constraints are feasible.
622   bool isInequalityFeasible(const Vector& xtilde,
623                             const bool    bPrintViolationInfo = false) const;
624 
625   //@}
626 
627   //! Form quantities needed to snap a point to the boundary.
628   /*!
629    *  @param[in] xtilde  The point to be snapped to the boundary.
630    *  @param[in] esnap  Radius of a ball that defines "nearby" constraints.
631    *  @param[out] Asnap  Scaled matrix of equalities and nearby inequalities.
632    *  @param[out] bsnap  Corresponding right-hand side of constraints.
633   */
634   void formSnapSystem(const Vector& xtilde, double esnap,
635                       Matrix& Asnap, Vector& bsnap) const;
636 
637   //! Print an error message and throw an exception.
638   void throwError(const string& fname, const string& msg) const;
639 
640   //! Print a count of all constraints.
641   void printCounts_ (void) const;
642 
643   //! Print the name of an inequality constraint.
644   void printIneqName_ (const int  nIneqNum) const;
645 
646   //! Print the name of an equality constraint.
647   void printEqName_ (const int  nEqNum) const;
648 
649 
650   //! Problem definition, including bound constraints and variable scaling.
651   const ProblemDef &  probDef;
652 
653   //! Feasibility and active set tolerance.
654   double _dActiveTol;
655 
656   //! Value of 'Display' parameter.
657   int _nDisplayFlag;
658 
659   //! Variable scaling
660   const Vector & scaling;
661 
662 //@{ \name Unscaled-sytem members.
663   //! The coefficient matrix of the unscaled linear inequality constraints.
664   Matrix aIneq;
665 
666   //! The coefficient matrix of unscaled linear equality constraints.
667   Matrix aEq;
668 
669   //! The unscaled lower bounds on linear inequality constraints.
670   Vector bIneqLower;
671 
672   //! The unscaled upper bounds on linear inequality constraints.
673   Vector bIneqUpper;
674 
675   //! The right-hand side of unscaled equality constraints.
676   Vector bEq;
677 //@}
678 
679 //@{ \name Scaled-sytem members.
680   //! The scaled coefficient matrix of variable bounds and linear inequality constraints.
681   Matrix aHat;
682 
683   //! Holds two norms of rows of aHat projected into the nullspace of the scaled equality constraints.
684   Vector aHatZNorm;
685 
686   //! The scaled lower bounds on the variable bounds and linear inequality constraints.
687   Vector bHatLower;
688 
689   //! The scaled upper bounds on the variable bounds and linear inequality constraints.
690   Vector bHatUpper;
691 
692   //! The scaled coefficient matrix of linear equality constraints.
693   Matrix aTildeEq;
694 
695   //! The scaled right-hand side of equality coefficient matrix.
696   Vector bTildeEq;
697 
698   //! Used in transforming x to scaled and shifted space.
699   /*!
700     Scaled \f$ \tilde{x} \f$ is related to unscaled \f$ x \f$ via the
701     affine transformation \f$ x = S \tilde{x} + \hat{l} \f$.
702   */
703   Vector lHat;
704 //@}
705 
706 };
707 
708 }          //-- namespace HOPSPACK
709 
710 #endif     //-- HOPSPACK_LINCONSTR_HPP
711