You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							200 lines
						
					
					
						
							6.6 KiB
						
					
					
				
			
		
		
	
	
							200 lines
						
					
					
						
							6.6 KiB
						
					
					
				// Copyright (C) 2004, 2006 International Business Machines and others.
 | 
						|
// All Rights Reserved.
 | 
						|
// This code is published under the Eclipse Public License.
 | 
						|
//
 | 
						|
// $Id: IpAugSystemSolver.hpp 2269 2013-05-05 11:32:40Z stefan $
 | 
						|
//
 | 
						|
// Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
 | 
						|
 | 
						|
#ifndef __IP_AUGSYSTEMSOLVER_HPP__
 | 
						|
#define __IP_AUGSYSTEMSOLVER_HPP__
 | 
						|
 | 
						|
#include "IpSymMatrix.hpp"
 | 
						|
#include "IpSymLinearSolver.hpp"
 | 
						|
#include "IpAlgStrategy.hpp"
 | 
						|
 | 
						|
namespace Ipopt
 | 
						|
{
 | 
						|
  DECLARE_STD_EXCEPTION(FATAL_ERROR_IN_LINEAR_SOLVER);
 | 
						|
 | 
						|
  /** Base class for Solver for the augmented system.  This is the
 | 
						|
   *  base class for linear solvers that solve the augmented system,
 | 
						|
   *  which is defined as
 | 
						|
   *
 | 
						|
   *  \f$\left[\begin{array}{cccc}
 | 
						|
   *  W + D_x + \delta_xI & 0 & J_c^T & J_d^T\\
 | 
						|
   *  0 & D_s + \delta_sI & 0 & -I \\
 | 
						|
   *  J_c & 0 & D_c - \delta_cI & 0\\
 | 
						|
   *  J_d & -I & 0 & D_d - \delta_dI
 | 
						|
   *  \end{array}\right]
 | 
						|
   *  \left(\begin{array}{c}sol_x\\sol_s\\sol_c\\sol_d\end{array}\right)=
 | 
						|
   *  \left(\begin{array}{c}rhs_x\\rhs_s\\rhs_c\\rhs_d\end{array}\right)\f$
 | 
						|
   *
 | 
						|
   *  Since this system might be solved repeatedly for different right
 | 
						|
   *  hand sides, it is desirable to step the factorization of a
 | 
						|
   *  direct linear solver if possible.
 | 
						|
   */
 | 
						|
  class AugSystemSolver: public AlgorithmStrategyObject
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    /**@name Constructors/Destructors */
 | 
						|
    //@{
 | 
						|
    /** Default constructor. */
 | 
						|
    AugSystemSolver()
 | 
						|
    {}
 | 
						|
    /** Default destructor */
 | 
						|
    virtual ~AugSystemSolver()
 | 
						|
    {}
 | 
						|
    //@}
 | 
						|
 | 
						|
    /** overloaded from AlgorithmStrategyObject */
 | 
						|
    virtual bool InitializeImpl(const OptionsList& options,
 | 
						|
                                const std::string& prefix) = 0;
 | 
						|
 | 
						|
    /** Set up the augmented system and solve it for a given right hand
 | 
						|
     *  side.  If desired (i.e. if check_NegEVals is true), then the
 | 
						|
     *  solution is only computed if the number of negative eigenvalues
 | 
						|
     *  matches numberOfNegEVals.
 | 
						|
     *
 | 
						|
     *  The return value is the return value of the linear solver object.
 | 
						|
     */
 | 
						|
    virtual ESymSolverStatus Solve(
 | 
						|
      const SymMatrix* W,
 | 
						|
      double W_factor,
 | 
						|
      const Vector* D_x,
 | 
						|
      double delta_x,
 | 
						|
      const Vector* D_s,
 | 
						|
      double delta_s,
 | 
						|
      const Matrix* J_c,
 | 
						|
      const Vector* D_c,
 | 
						|
      double delta_c,
 | 
						|
      const Matrix* J_d,
 | 
						|
      const Vector* D_d,
 | 
						|
      double delta_d,
 | 
						|
      const Vector& rhs_x,
 | 
						|
      const Vector& rhs_s,
 | 
						|
      const Vector& rhs_c,
 | 
						|
      const Vector& rhs_d,
 | 
						|
      Vector& sol_x,
 | 
						|
      Vector& sol_s,
 | 
						|
      Vector& sol_c,
 | 
						|
      Vector& sol_d,
 | 
						|
      bool check_NegEVals,
 | 
						|
      Index numberOfNegEVals)
 | 
						|
    {
 | 
						|
      std::vector<SmartPtr<const Vector> > rhs_xV(1);
 | 
						|
      rhs_xV[0] = &rhs_x;
 | 
						|
      std::vector<SmartPtr<const Vector> > rhs_sV(1);
 | 
						|
      rhs_sV[0] = &rhs_s;
 | 
						|
      std::vector<SmartPtr<const Vector> > rhs_cV(1);
 | 
						|
      rhs_cV[0] = &rhs_c;
 | 
						|
      std::vector<SmartPtr<const Vector> > rhs_dV(1);
 | 
						|
      rhs_dV[0] = &rhs_d;
 | 
						|
      std::vector<SmartPtr<Vector> > sol_xV(1);
 | 
						|
      sol_xV[0] = &sol_x;
 | 
						|
      std::vector<SmartPtr<Vector> > sol_sV(1);
 | 
						|
      sol_sV[0] = &sol_s;
 | 
						|
      std::vector<SmartPtr<Vector> > sol_cV(1);
 | 
						|
      sol_cV[0] = &sol_c;
 | 
						|
      std::vector<SmartPtr<Vector> > sol_dV(1);
 | 
						|
      sol_dV[0] = &sol_d;
 | 
						|
      return MultiSolve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c,
 | 
						|
                        J_d, D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV,
 | 
						|
                        sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals,
 | 
						|
                        numberOfNegEVals);
 | 
						|
    }
 | 
						|
 | 
						|
    /** Like Solve, but for multiple right hand sides.  The inheriting
 | 
						|
     *  class has to be overload at least one of Solve and
 | 
						|
     *  MultiSolve. */
 | 
						|
    virtual ESymSolverStatus MultiSolve(
 | 
						|
      const SymMatrix* W,
 | 
						|
      double W_factor,
 | 
						|
      const Vector* D_x,
 | 
						|
      double delta_x,
 | 
						|
      const Vector* D_s,
 | 
						|
      double delta_s,
 | 
						|
      const Matrix* J_c,
 | 
						|
      const Vector* D_c,
 | 
						|
      double delta_c,
 | 
						|
      const Matrix* J_d,
 | 
						|
      const Vector* D_d,
 | 
						|
      double delta_d,
 | 
						|
      std::vector<SmartPtr<const Vector> >& rhs_xV,
 | 
						|
      std::vector<SmartPtr<const Vector> >& rhs_sV,
 | 
						|
      std::vector<SmartPtr<const Vector> >& rhs_cV,
 | 
						|
      std::vector<SmartPtr<const Vector> >& rhs_dV,
 | 
						|
      std::vector<SmartPtr<Vector> >& sol_xV,
 | 
						|
      std::vector<SmartPtr<Vector> >& sol_sV,
 | 
						|
      std::vector<SmartPtr<Vector> >& sol_cV,
 | 
						|
      std::vector<SmartPtr<Vector> >& sol_dV,
 | 
						|
      bool check_NegEVals,
 | 
						|
      Index numberOfNegEVals)
 | 
						|
    {
 | 
						|
      // Solve for one right hand side after the other
 | 
						|
      Index nrhs = (Index)rhs_xV.size();
 | 
						|
      DBG_ASSERT(nrhs>0);
 | 
						|
      DBG_ASSERT(nrhs==(Index)rhs_sV.size());
 | 
						|
      DBG_ASSERT(nrhs==(Index)rhs_cV.size());
 | 
						|
      DBG_ASSERT(nrhs==(Index)rhs_dV.size());
 | 
						|
      DBG_ASSERT(nrhs==(Index)sol_xV.size());
 | 
						|
      DBG_ASSERT(nrhs==(Index)sol_sV.size());
 | 
						|
      DBG_ASSERT(nrhs==(Index)sol_cV.size());
 | 
						|
      DBG_ASSERT(nrhs==(Index)sol_dV.size());
 | 
						|
 | 
						|
      ESymSolverStatus retval=SYMSOLVER_SUCCESS;
 | 
						|
      for (Index i=0; i<nrhs; i++) {
 | 
						|
        retval = Solve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c,
 | 
						|
                       J_d, D_d, delta_d,
 | 
						|
                       *rhs_xV[i], *rhs_sV[i], *rhs_cV[i], *rhs_dV[i],
 | 
						|
                       *sol_xV[i], *sol_sV[i], *sol_cV[i], *sol_dV[i],
 | 
						|
                       check_NegEVals, numberOfNegEVals);
 | 
						|
        if (retval!=SYMSOLVER_SUCCESS) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return retval;
 | 
						|
    }
 | 
						|
 | 
						|
    /** Number of negative eigenvalues detected during last
 | 
						|
     * solve.  Returns the number of negative eigenvalues of
 | 
						|
     * the most recent factorized matrix.  This must not be called if
 | 
						|
     * the linear solver does not compute this quantities (see
 | 
						|
     * ProvidesInertia).
 | 
						|
     */
 | 
						|
    virtual Index NumberOfNegEVals() const =0;
 | 
						|
 | 
						|
    /** Query whether inertia is computed by linear solver.
 | 
						|
     *  Returns true, if linear solver provides inertia.
 | 
						|
     */
 | 
						|
    virtual bool ProvidesInertia() const =0;
 | 
						|
 | 
						|
    /** Request to increase quality of solution for next solve.  Ask
 | 
						|
     *  underlying linear solver to increase quality of solution for
 | 
						|
     *  the next solve (e.g. increase pivot tolerance).  Returns
 | 
						|
     *  false, if this is not possible (e.g. maximal pivot tolerance
 | 
						|
     *  already used.)
 | 
						|
     */
 | 
						|
    virtual bool IncreaseQuality() =0;
 | 
						|
 | 
						|
  private:
 | 
						|
    /**@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 */
 | 
						|
    AugSystemSolver(const AugSystemSolver&);
 | 
						|
 | 
						|
    /** Overloaded Equals Operator */
 | 
						|
    void operator=(const AugSystemSolver&);
 | 
						|
    //@}
 | 
						|
 | 
						|
  };
 | 
						|
 | 
						|
} // namespace Ipopt
 | 
						|
 | 
						|
#endif
 | 
						|
 |