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.
		
		
		
		
			
				
					201 lines
				
				6.6 KiB
			
		
		
			
		
	
	
					201 lines
				
				6.6 KiB
			| 
								 
											6 years ago
										 
									 | 
							
								// 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
							 |