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
|
|
|