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.
		
		
		
		
			
				
					3868 lines
				
				90 KiB
			
		
		
			
		
	
	
					3868 lines
				
				90 KiB
			| 
								 
											6 years ago
										 
									 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	This file is part of qpOASES.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	qpOASES -- An Implementation of the Online Active Set Strategy.
							 | 
						||
| 
								 | 
							
								 *	Copyright (C) 2007-2008 by Hans Joachim Ferreau et al. All rights reserved.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	qpOASES is free software; you can redistribute it and/or
							 | 
						||
| 
								 | 
							
								 *	modify it under the terms of the GNU Lesser General Public
							 | 
						||
| 
								 | 
							
								 *	License as published by the Free Software Foundation; either
							 | 
						||
| 
								 | 
							
								 *	version 2.1 of the License, or (at your option) any later version.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	qpOASES is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
							 | 
						||
| 
								 | 
							
								 *	Lesser General Public License for more details.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	You should have received a copy of the GNU Lesser General Public
							 | 
						||
| 
								 | 
							
								 *	License along with qpOASES; if not, write to the Free Software
							 | 
						||
| 
								 | 
							
								 *	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 *	\file SRC/QProblem.cpp
							 | 
						||
| 
								 | 
							
								 *	\author Hans Joachim Ferreau
							 | 
						||
| 
								 | 
							
								 *	\version 1.3embedded
							 | 
						||
| 
								 | 
							
								 *	\date 2007-2008
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *	Implementation of the QProblem class which is able to use the newly
							 | 
						||
| 
								 | 
							
								 *	developed online active set strategy for parametric quadratic programming.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <QProblem.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void printmatrix2(char *name, double *A, int m, int n) {
							 | 
						||
| 
								 | 
							
								  int i, j;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  printf("%s = [...\n", name);
							 | 
						||
| 
								 | 
							
								  for (i = 0; i < m; i++) {
							 | 
						||
| 
								 | 
							
								    for (j = 0; j < n; j++)
							 | 
						||
| 
								 | 
							
								        printf("  % 9.4f", A[i*n+j]);
							 | 
						||
| 
								 | 
							
								    printf(",\n");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  printf("];\n");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//#define __PERFORM_KKT_TEST__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*****************************************************************************
							 | 
						||
| 
								 | 
							
								 *  P U B L I C                                                              *
							 | 
						||
| 
								 | 
							
								 *****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	Q P r o b l e m
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								QProblem::QProblem( ) : QProblemB( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									constraints.init( 0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									sizeT = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									cyclingManager.init( 0,0 );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	Q P r o b l e m
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								QProblem::QProblem( int _nV, int _nC ) : QProblemB( _nV )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* consistency checks */
							 | 
						||
| 
								 | 
							
									if ( _nV <= 0 )
							 | 
						||
| 
								 | 
							
										_nV = 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( _nC < 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										_nC = 0;
							 | 
						||
| 
								 | 
							
										THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constraints.init( _nC );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									sizeT = _nC;
							 | 
						||
| 
								 | 
							
									if ( _nC > _nV )
							 | 
						||
| 
								 | 
							
										sizeT = _nV;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									cyclingManager.init( _nV,_nC );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	Q P r o b l e m
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								QProblem::QProblem( const QProblem& rhs ) :	QProblemB( rhs )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int _nV = rhs.bounds.getNV( );
							 | 
						||
| 
								 | 
							
									int _nC = rhs.constraints.getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<_nV; ++j )
							 | 
						||
| 
								 | 
							
											A[i*NVMAX + j] = rhs.A[i*NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
										lbA[i] = rhs.lbA[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
											ubA[i] = rhs.ubA[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constraints = rhs.constraints;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<(_nV+_nC); ++i )
							 | 
						||
| 
								 | 
							
										y[i] = rhs.y[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									sizeT = rhs.sizeT;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<sizeT; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<sizeT; ++j )
							 | 
						||
| 
								 | 
							
											T[i*NVMAX + j] = rhs.T[i*NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<_nV; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<_nV; ++j )
							 | 
						||
| 
								 | 
							
											Q[i*NVMAX + j] = rhs.Q[i*NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
										Ax[i] = rhs.Ax[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									cyclingManager = rhs.cyclingManager;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	~ Q P r o b l e m
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								QProblem::~QProblem( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	o p e r a t o r =
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								QProblem& QProblem::operator=( const QProblem& rhs )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( this != &rhs )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										QProblemB::operator=( rhs );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										int _nV = rhs.bounds.getNV( );
							 | 
						||
| 
								 | 
							
										int _nC = rhs.constraints.getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
											for( j=0; j<_nV; ++j )
							 | 
						||
| 
								 | 
							
												A[i*NVMAX + j] = rhs.A[i*NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
											lbA[i] = rhs.lbA[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
											ubA[i] = rhs.ubA[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										constraints = rhs.constraints;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<(_nV+_nC); ++i )
							 | 
						||
| 
								 | 
							
											y[i] = rhs.y[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										sizeT = rhs.sizeT;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<sizeT; ++i )
							 | 
						||
| 
								 | 
							
											for( j=0; j<sizeT; ++j )
							 | 
						||
| 
								 | 
							
												T[i*NVMAX + j] = rhs.T[i*NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<_nV; ++i )
							 | 
						||
| 
								 | 
							
											for( j=0; j<_nV; ++j )
							 | 
						||
| 
								 | 
							
												Q[i*NVMAX + j] = rhs.Q[i*NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<_nC; ++i )
							 | 
						||
| 
								 | 
							
											Ax[i] = rhs.Ax[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										cyclingManager = rhs.cyclingManager;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return *this;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	r e s e t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::reset( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Reset bounds, Cholesky decomposition and status flags. */
							 | 
						||
| 
								 | 
							
									if ( QProblemB::reset( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_RESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Reset constraints. */
							 | 
						||
| 
								 | 
							
									constraints.init( nC );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Reset TQ factorisation. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<sizeT; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<sizeT; ++j )
							 | 
						||
| 
								 | 
							
											T[i*NVMAX + j] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
											Q[i*NVMAX + j] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 4) Reset cycling manager. */
							 | 
						||
| 
								 | 
							
									if ( cyclingManager.clearCyclingData( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_RESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	i n i t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::init(	const real_t* const _H, const real_t* const _g, const real_t* const _A,
							 | 
						||
| 
								 | 
							
															const real_t* const _lb, const real_t* const _ub,
							 | 
						||
| 
								 | 
							
															const real_t* const _lbA, const real_t* const _ubA,
							 | 
						||
| 
								 | 
							
															int& nWSR, const real_t* const yOpt, real_t* const cputime
							 | 
						||
| 
								 | 
							
															)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* 1) Setup QP data. */
							 | 
						||
| 
								 | 
							
									if (setupQPdata(_H, 0, _g, _A, _lb, _ub, _lbA, _ubA) != SUCCESSFUL_RETURN)
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Call to main initialisation routine (without any additional information). */
							 | 
						||
| 
								 | 
							
									return solveInitialQP( 0,yOpt,0,0, nWSR,cputime );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								returnValue QProblem::init(	const real_t* const _H, const real_t* const _R, const real_t* const _g, const real_t* const _A,
							 | 
						||
| 
								 | 
							
															const real_t* const _lb, const real_t* const _ub,
							 | 
						||
| 
								 | 
							
															const real_t* const _lbA, const real_t* const _ubA,
							 | 
						||
| 
								 | 
							
															int& nWSR, const real_t* const yOpt, real_t* const cputime
							 | 
						||
| 
								 | 
							
															)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* 1) Setup QP data. */
							 | 
						||
| 
								 | 
							
									if (setupQPdata(_H, _R, _g, _A, _lb, _ub, _lbA, _ubA) != SUCCESSFUL_RETURN)
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Call to main initialisation routine (without any additional information). */
							 | 
						||
| 
								 | 
							
									return solveInitialQP( 0,yOpt,0,0, nWSR,cputime );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	h o t s t a r t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::hotstart(	const real_t* const g_new, const real_t* const lb_new, const real_t* const ub_new,
							 | 
						||
| 
								 | 
							
																const real_t* const lbA_new, const real_t* const ubA_new,
							 | 
						||
| 
								 | 
							
																int& nWSR, real_t* const cputime
							 | 
						||
| 
								 | 
							
																)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int l;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency check */
							 | 
						||
| 
								 | 
							
									if ( ( getStatus( ) == QPS_NOTINITIALISED )       ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_PERFORMINGHOMOTOPY )   )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* start runtime measurement */
							 | 
						||
| 
								 | 
							
									real_t starttime = 0.0;
							 | 
						||
| 
								 | 
							
									if ( cputime != 0 )
							 | 
						||
| 
								 | 
							
										starttime = getCPUtime( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) PREPARATIONS */
							 | 
						||
| 
								 | 
							
									/* 1) Reset cycling and status flags and increase QP counter. */
							 | 
						||
| 
								 | 
							
									cyclingManager.clearCyclingData( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									infeasible = BT_FALSE;
							 | 
						||
| 
								 | 
							
									unbounded = BT_FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									++count;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Allocate delta vectors of gradient and (constraints') bounds. */
							 | 
						||
| 
								 | 
							
									returnValue returnvalue;
							 | 
						||
| 
								 | 
							
									BooleanType Delta_bC_isZero, Delta_bB_isZero;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									int FX_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									int AC_idx[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									int IAC_idx[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t delta_g[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t delta_lb[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t delta_ub[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t delta_lbA[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t delta_ubA[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t delta_xFR[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t delta_xFX[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t delta_yAC[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t delta_yFX[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t delta_Ax[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int BC_idx;
							 | 
						||
| 
								 | 
							
									SubjectToStatus BC_status;
							 | 
						||
| 
								 | 
							
									BooleanType BC_isBound;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
									char messageString[80];
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) MAIN HOMOTOPY LOOP */
							 | 
						||
| 
								 | 
							
									for( l=0; l<nWSR; ++l )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										status = QPS_PERFORMINGHOMOTOPY;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
											sprintf( messageString,"%d ...",l );
							 | 
						||
| 
								 | 
							
										  	getGlobalMessageHandler( )->throwInfo( RET_ITERATION_STARTED,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
							 | 
						||
| 
								 | 
							
											#endif
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 1) Setup index arrays. */
							 | 
						||
| 
								 | 
							
										if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_HOTSTART_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( bounds.getFixed( )->getNumberArray( FX_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_HOTSTART_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_HOTSTART_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( constraints.getInactive( )->getNumberArray( IAC_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_HOTSTART_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 2) Detemination of shift direction of the gradient and the (constraints') bounds. */
							 | 
						||
| 
								 | 
							
										returnvalue = hotstart_determineDataShift(  FX_idx, AC_idx,
							 | 
						||
| 
								 | 
							
																					g_new,lbA_new,ubA_new,lb_new,ub_new,
							 | 
						||
| 
								 | 
							
																					delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub,
							 | 
						||
| 
								 | 
							
																					Delta_bC_isZero, Delta_bB_isZero );
							 | 
						||
| 
								 | 
							
										if ( returnvalue != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nWSR = l;
							 | 
						||
| 
								 | 
							
											THROWERROR( RET_SHIFT_DETERMINATION_FAILED );
							 | 
						||
| 
								 | 
							
											return returnvalue;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 3) Determination of step direction of X and Y. */
							 | 
						||
| 
								 | 
							
										returnvalue = hotstart_determineStepDirection(	FR_idx,FX_idx,AC_idx,
							 | 
						||
| 
								 | 
							
																						delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub,
							 | 
						||
| 
								 | 
							
																						Delta_bC_isZero, Delta_bB_isZero,
							 | 
						||
| 
								 | 
							
																						delta_xFX,delta_xFR,delta_yAC,delta_yFX
							 | 
						||
| 
								 | 
							
																						);
							 | 
						||
| 
								 | 
							
										if ( returnvalue != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nWSR = l;
							 | 
						||
| 
								 | 
							
											THROWERROR( RET_STEPDIRECTION_DETERMINATION_FAILED );
							 | 
						||
| 
								 | 
							
											return returnvalue;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 4) Determination of step length TAU. */
							 | 
						||
| 
								 | 
							
										returnvalue = hotstart_determineStepLength(	FR_idx,FX_idx,AC_idx,IAC_idx,
							 | 
						||
| 
								 | 
							
																					delta_lbA,delta_ubA,delta_lb,delta_ub,
							 | 
						||
| 
								 | 
							
																					delta_xFX,delta_xFR,delta_yAC,delta_yFX,delta_Ax,
							 | 
						||
| 
								 | 
							
																					BC_idx,BC_status,BC_isBound
							 | 
						||
| 
								 | 
							
																					);
							 | 
						||
| 
								 | 
							
										if ( returnvalue != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nWSR = l;
							 | 
						||
| 
								 | 
							
											THROWERROR( RET_STEPLENGTH_DETERMINATION_FAILED );
							 | 
						||
| 
								 | 
							
											return returnvalue;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 5) Realisation of the homotopy step. */
							 | 
						||
| 
								 | 
							
										returnvalue = hotstart_performStep(	FR_idx,FX_idx,AC_idx,IAC_idx,
							 | 
						||
| 
								 | 
							
																			delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub,
							 | 
						||
| 
								 | 
							
																			delta_xFX,delta_xFR,delta_yAC,delta_yFX,delta_Ax,
							 | 
						||
| 
								 | 
							
																			BC_idx,BC_status,BC_isBound
							 | 
						||
| 
								 | 
							
																			);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( returnvalue != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nWSR = l;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* stop runtime measurement */
							 | 
						||
| 
								 | 
							
											if ( cputime != 0 )
							 | 
						||
| 
								 | 
							
													*cputime = getCPUtime( ) - starttime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* optimal solution found? */
							 | 
						||
| 
								 | 
							
											if ( returnvalue == RET_OPTIMAL_SOLUTION_FOUND )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												status = QPS_SOLVED;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
													THROWINFO( RET_OPTIMAL_SOLUTION_FOUND );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
									 			if ( printIteration( l,BC_idx,BC_status,BC_isBound ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													THROWERROR( RET_PRINT_ITERATION_FAILED ); /* do not pass this as return value! */
							 | 
						||
| 
								 | 
							
												#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* check KKT optimality conditions */
							 | 
						||
| 
								 | 
							
												return checkKKTconditions( );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* checks for infeasibility... */
							 | 
						||
| 
								 | 
							
												if ( isInfeasible( ) == BT_TRUE )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													status = QPS_HOMOTOPYQPSOLVED;
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_HOTSTART_STOPPED_INFEASIBILITY );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* ...unboundedness... */
							 | 
						||
| 
								 | 
							
												if ( unbounded == BT_TRUE ) /* not necessary since objective function convex! */
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_HOTSTART_STOPPED_UNBOUNDEDNESS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* ... and throw unspecific error otherwise */
							 | 
						||
| 
								 | 
							
												THROWERROR( RET_HOMOTOPY_STEP_FAILED );
							 | 
						||
| 
								 | 
							
												return returnvalue;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 6) Output information of successful QP iteration. */
							 | 
						||
| 
								 | 
							
										status = QPS_HOMOTOPYQPSOLVED;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
										if ( printIteration( l,BC_idx,BC_status,BC_isBound ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											THROWERROR( RET_PRINT_ITERATION_FAILED ); /* do not pass this as return value! */
							 | 
						||
| 
								 | 
							
										#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* stop runtime measurement */
							 | 
						||
| 
								 | 
							
									if ( cputime != 0 )
							 | 
						||
| 
								 | 
							
										*cputime = getCPUtime( ) - starttime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* if programm gets to here, output information that QP could not be solved
							 | 
						||
| 
								 | 
							
									 * within the given maximum numbers of working set changes */
							 | 
						||
| 
								 | 
							
									if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
										sprintf( messageString,"(nWSR = %d)",nWSR );
							 | 
						||
| 
								 | 
							
										return getGlobalMessageHandler( )->throwWarning( RET_MAX_NWSR_REACHED,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
							 | 
						||
| 
								 | 
							
										#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Finally check KKT optimality conditions. */
							 | 
						||
| 
								 | 
							
									returnValue returnvalueKKTcheck = checkKKTconditions( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( returnvalueKKTcheck != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return returnvalueKKTcheck;
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										return RET_MAX_NWSR_REACHED;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	g e t N Z
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int QProblem::getNZ( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* nZ = nFR - nAC */
							 | 
						||
| 
								 | 
							
									return bounds.getFree( )->getLength( ) - constraints.getActive( )->getLength( );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	g e t D u a l S o l u t i o n
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::getDualSolution( real_t* const yOpt ) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* return optimal dual solution vector
							 | 
						||
| 
								 | 
							
									 * only if current QP has been solved */
							 | 
						||
| 
								 | 
							
									if ( ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED )  ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_SOLVED ) )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<getNV( )+getNC( ); ++i )
							 | 
						||
| 
								 | 
							
											yOpt[i] = y[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return RET_QP_NOT_SOLVED;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*****************************************************************************
							 | 
						||
| 
								 | 
							
								 *  P R O T E C T E D                                                        *
							 | 
						||
| 
								 | 
							
								 *****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s e t u p S u b j e c t T o T y p e
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupSubjectToType( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) SETUP SUBJECTTOTYPE FOR BOUNDS */
							 | 
						||
| 
								 | 
							
									if ( QProblemB::setupSubjectToType( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_SETUPSUBJECTTOTYPE_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) SETUP SUBJECTTOTYPE FOR CONSTRAINTS */
							 | 
						||
| 
								 | 
							
									/* 1) Check if lower constraints' bounds are present. */
							 | 
						||
| 
								 | 
							
									constraints.setNoLower( BT_TRUE );
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( lbA[i] > -INFTY )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											constraints.setNoLower( BT_FALSE );
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Check if upper constraints' bounds are present. */
							 | 
						||
| 
								 | 
							
									constraints.setNoUpper( BT_TRUE );
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( ubA[i] < INFTY )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											constraints.setNoUpper( BT_FALSE );
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Determine implicit equality constraints and unbounded constraints. */
							 | 
						||
| 
								 | 
							
									int nEC = 0;
							 | 
						||
| 
								 | 
							
									int nUC = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( ( lbA[i] < -INFTY + BOUNDTOL ) && ( ubA[i] > INFTY - BOUNDTOL ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											constraints.setType( i,ST_UNBOUNDED );
							 | 
						||
| 
								 | 
							
											++nUC;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( lbA[i] > ubA[i] - BOUNDTOL )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												constraints.setType( i,ST_EQUALITY );
							 | 
						||
| 
								 | 
							
												++nEC;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												constraints.setType( i,ST_BOUNDED );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 4) Set dimensions of constraints structure. */
							 | 
						||
| 
								 | 
							
									constraints.setNEC( nEC );
							 | 
						||
| 
								 | 
							
									constraints.setNUC( nUC );
							 | 
						||
| 
								 | 
							
									constraints.setNIC( nC - nEC - nUC );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	c h o l e s k y D e c o m p o s i t i o n P r o j e c t e d
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupCholeskyDecompositionProjected( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, k, ii, kk;
							 | 
						||
| 
								 | 
							
									int nV  = getNV( );
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Initialises R with all zeros. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
											R[i*NVMAX + j] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Calculate Cholesky decomposition of projected Hessian Z'*H*Z. */
							 | 
						||
| 
								 | 
							
									if ( hessianType == HST_IDENTITY )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* if Hessian is identity, so is its Cholesky factor. */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
											R[i*NVMAX + i] = 1.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( nZ > 0 )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
											if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_INDEXLIST_CORRUPTED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
											real_t HZ[NVMAX*NVMAX];
							 | 
						||
| 
								 | 
							
											real_t ZHZ[NVMAX*NVMAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* calculate H*Z */
							 | 
						||
| 
								 | 
							
											for ( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for ( j=0; j<nZ; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													real_t sum = 0.0;
							 | 
						||
| 
								 | 
							
													for ( k=0; k<nFR; ++k )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														kk = FR_idx[k];
							 | 
						||
| 
								 | 
							
														sum += H[ii*NVMAX + kk] * Q[kk*NVMAX + j];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													HZ[i * NVMAX + j] = sum;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* calculate Z'*H*Z */
							 | 
						||
| 
								 | 
							
											for ( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
												for ( j=0; j<nZ; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													real_t sum = 0.0;
							 | 
						||
| 
								 | 
							
													for ( k=0; k<nFR; ++k )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														kk = FR_idx[k];
							 | 
						||
| 
								 | 
							
														sum += Q[kk*NVMAX + i] * HZ[k*NVMAX + j];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													ZHZ[i * NVMAX + j] = sum;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* R'*R = Z'*H*Z */
							 | 
						||
| 
								 | 
							
											real_t sum, inv;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* j == i */
							 | 
						||
| 
								 | 
							
												sum = ZHZ[i*NVMAX + i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( k=(i-1); k>=0; --k )
							 | 
						||
| 
								 | 
							
													sum -= R[k*NVMAX + i] * R[k*NVMAX + i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( sum > 0.0 )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													R[i*NVMAX + i] = sqrt( sum );
							 | 
						||
| 
								 | 
							
													inv = 1.0 / R[i * NVMAX + i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													hessianType = HST_SEMIDEF;
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_HESSIAN_NOT_SPD );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( j=(i+1); j<nZ; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													sum = ZHZ[j*NVMAX + i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													for( k=(i-1); k>=0; --k )
							 | 
						||
| 
								 | 
							
														sum -= R[k*NVMAX + i] * R[k*NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													R[i*NVMAX + j] = sum * inv;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
											real_t HZ[NVMAX];
							 | 
						||
| 
								 | 
							
											real_t ZHZ[NVMAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											real_t sum, inv;
							 | 
						||
| 
								 | 
							
											for (j = 0; j < nZ; ++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* Cache one column of Z. */
							 | 
						||
| 
								 | 
							
												for (i = 0; i < NVMAX; ++i)
							 | 
						||
| 
								 | 
							
													ZHZ[i] = Q[i * NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* Create one column of the product H * Z. */
							 | 
						||
| 
								 | 
							
												for (i = 0; i < nFR; ++i)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													sum = 0.0;
							 | 
						||
| 
								 | 
							
													for (k = 0; k < nFR; ++k)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														kk = FR_idx[k];
							 | 
						||
| 
								 | 
							
														sum += H[ii * NVMAX + kk] * ZHZ[kk];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													HZ[ii] = sum;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* Create one column of the product Z^T * H * Z. */
							 | 
						||
| 
								 | 
							
												for (i = j; i < nZ; ++i)
							 | 
						||
| 
								 | 
							
													ZHZ[ i ] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for (k = 0; k < nFR; ++k)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													kk = FR_idx[k];
							 | 
						||
| 
								 | 
							
													real_t q = HZ[kk];
							 | 
						||
| 
								 | 
							
													for (i = j; i < nZ; ++i)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														ZHZ[i] += Q[kk * NVMAX + i] * q;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* Use the computed column to update the factorization. */
							 | 
						||
| 
								 | 
							
												/* j == i */
							 | 
						||
| 
								 | 
							
												sum = ZHZ[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for (k = (j - 1); k >= 0; --k)
							 | 
						||
| 
								 | 
							
													sum -= R[k * NVMAX + j] * R[k * NVMAX + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if (sum > 0.0)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													R[j * NVMAX + j] = sqrt(sum);
							 | 
						||
| 
								 | 
							
													inv = 1.0 / R[j * NVMAX + j];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													hessianType = HST_SEMIDEF;
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_HESSIAN_NOT_SPD );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for (i = (j + 1); i < nZ; ++i)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													sum = ZHZ[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													for (k = (j - 1); k >= 0; --k)
							 | 
						||
| 
								 | 
							
														sum -= R[k * NVMAX + j] * R[k * NVMAX + i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													R[j * NVMAX + i] = sum * inv;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s e t u p T Q f a c t o r i s a t i o n
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupTQfactorisation( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii;
							 | 
						||
| 
								 | 
							
									int nV  = getNV( );
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INDEXLIST_CORRUPTED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Set Q to unity matrix. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
											Q[i*NVMAX + j] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
										Q[ii*NVMAX + i] = 1.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 	/* 2) Set T to zero matrix. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<sizeT; ++i )
							 | 
						||
| 
								 | 
							
										for( j=0; j<sizeT; ++j )
							 | 
						||
| 
								 | 
							
											T[i*NVMAX + j] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s o l v e I n i t i a l Q P
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::solveInitialQP(	const real_t* const xOpt, const real_t* const yOpt,
							 | 
						||
| 
								 | 
							
																		const Bounds* const guessedBounds, const Constraints* const guessedConstraints,
							 | 
						||
| 
								 | 
							
																		int& nWSR, real_t* const cputime
							 | 
						||
| 
								 | 
							
																		)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* some definitions */
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* start runtime measurement */
							 | 
						||
| 
								 | 
							
									real_t starttime = 0.0;
							 | 
						||
| 
								 | 
							
									if ( cputime != 0 )
							 | 
						||
| 
								 | 
							
										starttime = getCPUtime( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									status = QPS_NOTINITIALISED;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) ANALYSE QP DATA: */
							 | 
						||
| 
								 | 
							
									/* 1) Check if Hessian happens to be the identity matrix. */
							 | 
						||
| 
								 | 
							
									if ( checkForIdentityHessian( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Setup type of bounds and constraints (i.e. unbounded, implicitly fixed etc.). */
							 | 
						||
| 
								 | 
							
									if ( setupSubjectToType( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Initialise cycling manager. */
							 | 
						||
| 
								 | 
							
									cyclingManager.clearCyclingData( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									status = QPS_PREPARINGAUXILIARYQP;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) SETUP AUXILIARY QP WITH GIVEN OPTIMAL SOLUTION: */
							 | 
						||
| 
								 | 
							
									/* 1) Setup bounds and constraints data structure. */
							 | 
						||
| 
								 | 
							
									if ( bounds.setupAllFree( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( constraints.setupAllInactive( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Setup optimal primal/dual solution for auxiliary QP. */
							 | 
						||
| 
								 | 
							
									if ( setupAuxiliaryQPsolution( xOpt,yOpt ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Obtain linear independent working set for auxiliary QP. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static Bounds auxiliaryBounds;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									auxiliaryBounds.init( nV );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static Constraints auxiliaryConstraints;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									auxiliaryConstraints.init( nC );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( obtainAuxiliaryWorkingSet(	xOpt,yOpt,guessedBounds,guessedConstraints,
							 | 
						||
| 
								 | 
							
																	&auxiliaryBounds,&auxiliaryConstraints ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 4) Setup working set of auxiliary QP and setup matrix factorisations. */
							 | 
						||
| 
								 | 
							
									if ( setupTQfactorisation( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED_TQ );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( setupAuxiliaryWorkingSet( &auxiliaryBounds,&auxiliaryConstraints,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( getNAC( ) + getNFX( ) ) == 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* Factorise full Hessian if no bounds/constraints are active. */
							 | 
						||
| 
								 | 
							
										if (hasCholesky == BT_FALSE)
							 | 
						||
| 
								 | 
							
											if ( setupCholeskyDecomposition( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_INIT_FAILED_CHOLESKY );
							 | 
						||
| 
								 | 
							
										/* ... else we use user provided Cholesky factorization. At the moment
							 | 
						||
| 
								 | 
							
										 * we can do that only for cold-started solver. */
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* Factorise projected Hessian if there active bounds/constraints. */
							 | 
						||
| 
								 | 
							
										if ( setupCholeskyDecompositionProjected( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_INIT_FAILED_CHOLESKY );
							 | 
						||
| 
								 | 
							
										/* TODO: use user-supplied Hessian decomposition. R_Z = R * Z. */
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 5) Store original QP formulation... */
							 | 
						||
| 
								 | 
							
									real_t g_original[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t lb_original[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t ub_original[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t lbA_original[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t ubA_original[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										g_original[i] = g[i];
							 | 
						||
| 
								 | 
							
										lb_original[i] = lb[i];
							 | 
						||
| 
								 | 
							
										ub_original[i] = ub[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										lbA_original[i] = lbA[i];
							 | 
						||
| 
								 | 
							
										ubA_original[i] = ubA[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* ... and setup QP data of an auxiliary QP having an optimal solution
							 | 
						||
| 
								 | 
							
									 * as specified by the user (or xOpt = yOpt = 0, by default). */
							 | 
						||
| 
								 | 
							
									if ( setupAuxiliaryQPgradient( ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( setupAuxiliaryQPbounds( &auxiliaryBounds,&auxiliaryConstraints,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									status = QPS_AUXILIARYQPSOLVED;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* III) SOLVE ACTUAL INITIAL QP: */
							 | 
						||
| 
								 | 
							
									/* Use hotstart method to find the solution of the original initial QP,... */
							 | 
						||
| 
								 | 
							
									returnValue returnvalue = hotstart( g_original,lb_original,ub_original,lbA_original,ubA_original, nWSR,0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* ... check for infeasibility and unboundedness... */
							 | 
						||
| 
								 | 
							
									if ( isInfeasible( ) == BT_TRUE )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED_INFEASIBILITY );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( isUnbounded( ) == BT_TRUE )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED_UNBOUNDEDNESS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* ... and internal errors. */
							 | 
						||
| 
								 | 
							
									if ( ( returnvalue != SUCCESSFUL_RETURN ) && ( returnvalue != RET_MAX_NWSR_REACHED )  &&
							 | 
						||
| 
								 | 
							
									     ( returnvalue != RET_INACCURATE_SOLUTION ) && ( returnvalue != RET_NO_SOLUTION ) )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INIT_FAILED_HOTSTART );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* stop runtime measurement */
							 | 
						||
| 
								 | 
							
									if ( cputime != 0 )
							 | 
						||
| 
								 | 
							
										*cputime = getCPUtime( ) - starttime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
										THROWINFO( RET_INIT_SUCCESSFUL );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return returnvalue;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	o b t a i n A u x i l i a r y W o r k i n g S e t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::obtainAuxiliaryWorkingSet(	const real_t* const xOpt, const real_t* const yOpt,
							 | 
						||
| 
								 | 
							
																					const Bounds* const guessedBounds, const Constraints* const guessedConstraints,
							 | 
						||
| 
								 | 
							
																					Bounds* auxiliaryBounds, Constraints* auxiliaryConstraints
							 | 
						||
| 
								 | 
							
																					) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i = 0;
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Ensure that desiredBounds is allocated (and different from guessedBounds). */
							 | 
						||
| 
								 | 
							
									if ( ( auxiliaryBounds == 0 ) || ( auxiliaryBounds == guessedBounds ) )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( auxiliaryConstraints == 0 ) || ( auxiliaryConstraints == guessedConstraints ) )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									SubjectToStatus guessedStatus;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Setup working set of bounds for auxiliary initial QP. */
							 | 
						||
| 
								 | 
							
									if ( QProblemB::obtainAuxiliaryWorkingSet( xOpt,yOpt,guessedBounds, auxiliaryBounds ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Setup working set of constraints for auxiliary initial QP. */
							 | 
						||
| 
								 | 
							
									if ( guessedConstraints != 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* If an initial working set is specific, use it!
							 | 
						||
| 
								 | 
							
										 * Moreover, add all equality constraints if specified. */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											guessedStatus = guessedConstraints->getStatus( i );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( constraints.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( auxiliaryConstraints->setupConstraint( i,guessedStatus ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else	/* No initial working set specified. */
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* Obtain initial working set by "clipping". */
							 | 
						||
| 
								 | 
							
										if ( ( xOpt != 0 ) && ( yOpt == 0 ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( Ax[i] <= lbA[i] + BOUNDTOL )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
													continue;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( Ax[i] >= ubA[i] - BOUNDTOL )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_UPPER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
															return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
													continue;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* Moreover, add all equality constraints if specified. */
							 | 
						||
| 
								 | 
							
												if ( constraints.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Obtain initial working set in accordance to sign of dual solution vector. */
							 | 
						||
| 
								 | 
							
										if ( ( xOpt == 0 ) && ( yOpt != 0 ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( yOpt[nV+i] > ZERO )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
													continue;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( yOpt[nV+i] < -ZERO )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_UPPER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
													continue;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* Moreover, add all equality constraints if specified. */
							 | 
						||
| 
								 | 
							
												if ( constraints.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* If xOpt and yOpt are null pointer and no initial working is specified,
							 | 
						||
| 
								 | 
							
										 * start with empty working set (or implicitly fixed bounds and equality constraints only)
							 | 
						||
| 
								 | 
							
										 * for auxiliary QP. */
							 | 
						||
| 
								 | 
							
										if ( ( xOpt == 0 ) && ( yOpt == 0 ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* Only add all equality constraints if specified. */
							 | 
						||
| 
								 | 
							
												if ( constraints.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s e t u p A u x i l i a r y W o r k i n g S e t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupAuxiliaryWorkingSet(	const Bounds* const auxiliaryBounds,
							 | 
						||
| 
								 | 
							
																				const Constraints* const auxiliaryConstraints,
							 | 
						||
| 
								 | 
							
																				BooleanType setupAfresh
							 | 
						||
| 
								 | 
							
																				)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency checks */
							 | 
						||
| 
								 | 
							
									if ( auxiliaryBounds != 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
											if ( ( bounds.getStatus( i ) == ST_UNDEFINED ) || ( auxiliaryBounds->getStatus( i ) == ST_UNDEFINED ) )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( auxiliaryConstraints != 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
											if ( ( constraints.getStatus( i ) == ST_UNDEFINED ) || ( auxiliaryConstraints->getStatus( i ) == ST_UNDEFINED ) )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) SETUP CHOLESKY FLAG:
							 | 
						||
| 
								 | 
							
									 *    Cholesky decomposition shall only be updated if working set
							 | 
						||
| 
								 | 
							
									 *    shall be updated (i.e. NOT setup afresh!) */
							 | 
						||
| 
								 | 
							
									BooleanType updateCholesky;
							 | 
						||
| 
								 | 
							
									if ( setupAfresh == BT_TRUE )
							 | 
						||
| 
								 | 
							
										updateCholesky = BT_FALSE;
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										updateCholesky = BT_TRUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) REMOVE FORMERLY ACTIVE (CONSTRAINTS') BOUNDS (IF NECESSARY): */
							 | 
						||
| 
								 | 
							
									if ( setupAfresh == BT_FALSE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* 1) Remove all active constraints that shall be inactive AND
							 | 
						||
| 
								 | 
							
										*    all active constraints that are active at the wrong bound. */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( constraints.getStatus( i ) == ST_LOWER ) && ( auxiliaryConstraints->getStatus( i ) != ST_LOWER ) )
							 | 
						||
| 
								 | 
							
												if ( removeConstraint( i,updateCholesky ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( ( constraints.getStatus( i ) == ST_UPPER ) && ( auxiliaryConstraints->getStatus( i ) != ST_UPPER ) )
							 | 
						||
| 
								 | 
							
												if ( removeConstraint( i,updateCholesky ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 2) Remove all active bounds that shall be inactive AND
							 | 
						||
| 
								 | 
							
										*    all active bounds that are active at the wrong bound. */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( bounds.getStatus( i ) == ST_LOWER ) && ( auxiliaryBounds->getStatus( i ) != ST_LOWER ) )
							 | 
						||
| 
								 | 
							
												if ( removeBound( i,updateCholesky ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( ( bounds.getStatus( i ) == ST_UPPER ) && ( auxiliaryBounds->getStatus( i ) != ST_UPPER ) )
							 | 
						||
| 
								 | 
							
												if ( removeBound( i,updateCholesky ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* III) ADD NEWLY ACTIVE (CONSTRAINTS') BOUNDS: */
							 | 
						||
| 
								 | 
							
									/* 1) Add all inactive bounds that shall be active AND
							 | 
						||
| 
								 | 
							
									 *    all formerly active bounds that have been active at the wrong bound. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( ( bounds.getStatus( i ) == ST_INACTIVE ) && ( auxiliaryBounds->getStatus( i ) != ST_INACTIVE ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* Add bound only if it is linearly independent from the current working set. */
							 | 
						||
| 
								 | 
							
											if ( addBound_checkLI( i ) == RET_LINEARLY_INDEPENDENT )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( addBound( i,auxiliaryBounds->getStatus( i ),updateCholesky ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Add all inactive constraints that shall be active AND
							 | 
						||
| 
								 | 
							
									 *    all formerly active constraints that have been active at the wrong bound. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( ( auxiliaryConstraints->getStatus( i ) == ST_LOWER ) || ( auxiliaryConstraints->getStatus( i ) == ST_UPPER ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* formerly inactive */
							 | 
						||
| 
								 | 
							
											if ( constraints.getStatus( i ) == ST_INACTIVE )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* Add constraint only if it is linearly independent from the current working set. */
							 | 
						||
| 
								 | 
							
												if ( addConstraint_checkLI( i ) == RET_LINEARLY_INDEPENDENT )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( addConstraint( i,auxiliaryConstraints->getStatus( i ),updateCholesky ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
														return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s e t u p A u x i l i a r y Q P s o l u t i o n
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupAuxiliaryQPsolution(	const real_t* const xOpt, const real_t* const yOpt
							 | 
						||
| 
								 | 
							
																				)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Setup primal/dual solution vector for auxiliary initial QP:
							 | 
						||
| 
								 | 
							
									 * if a null pointer is passed, a zero vector is assigned;
							 | 
						||
| 
								 | 
							
									 *  old solution vector is kept if pointer to internal solution vevtor is passed. */
							 | 
						||
| 
								 | 
							
									if ( xOpt != 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( xOpt != x )
							 | 
						||
| 
								 | 
							
											for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
												x[i] = xOpt[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( j=0; j<nC; ++j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											Ax[j] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
												Ax[j] += A[j*NVMAX + i] * x[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
											x[i] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( j=0; j<nC; ++j )
							 | 
						||
| 
								 | 
							
											Ax[j] = 0.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( yOpt != 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( yOpt != y )
							 | 
						||
| 
								 | 
							
											for( i=0; i<nV+nC; ++i )
							 | 
						||
| 
								 | 
							
												y[i] = yOpt[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nV+nC; ++i )
							 | 
						||
| 
								 | 
							
											y[i] = 0.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s e t u p A u x i l i a r y Q P g r a d i e n t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupAuxiliaryQPgradient( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Setup gradient vector: g = -H*x + [Id A]'*[yB yC]. */
							 | 
						||
| 
								 | 
							
									for ( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* Id'*yB */
							 | 
						||
| 
								 | 
							
										g[i] = y[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* A'*yC */
							 | 
						||
| 
								 | 
							
										for ( j=0; j<nC; ++j )
							 | 
						||
| 
								 | 
							
											g[i] += A[j*NVMAX + i] * y[nV+j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* -H*x */
							 | 
						||
| 
								 | 
							
										for ( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
											g[i] -= H[i*NVMAX + j] * x[j];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s e t u p A u x i l i a r y Q P b o u n d s
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupAuxiliaryQPbounds(	const Bounds* const auxiliaryBounds,
							 | 
						||
| 
								 | 
							
																				const Constraints* const auxiliaryConstraints,
							 | 
						||
| 
								 | 
							
																				BooleanType useRelaxation
							 | 
						||
| 
								 | 
							
																				)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Setup bound vectors. */
							 | 
						||
| 
								 | 
							
									for ( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										switch ( bounds.getStatus( i ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											case ST_INACTIVE:
							 | 
						||
| 
								 | 
							
												if ( useRelaxation == BT_TRUE )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( bounds.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														lb[i] = x[i];
							 | 
						||
| 
								 | 
							
														ub[i] = x[i];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														/* If a bound is inactive although it was supposed to be
							 | 
						||
| 
								 | 
							
														* active by the auxiliaryBounds, it could not be added
							 | 
						||
| 
								 | 
							
														* due to linear dependence. Thus set it "strongly inactive". */
							 | 
						||
| 
								 | 
							
														if ( auxiliaryBounds->getStatus( i ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
															lb[i] = x[i];
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
															lb[i] = x[i] - BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														if ( auxiliaryBounds->getStatus( i ) == ST_UPPER )
							 | 
						||
| 
								 | 
							
															ub[i] = x[i];
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
															ub[i] = x[i] + BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case ST_LOWER:
							 | 
						||
| 
								 | 
							
												lb[i] = x[i];
							 | 
						||
| 
								 | 
							
												if ( bounds.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ub[i] = x[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( useRelaxation == BT_TRUE )
							 | 
						||
| 
								 | 
							
														ub[i] = x[i] + BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case ST_UPPER:
							 | 
						||
| 
								 | 
							
												ub[i] = x[i];
							 | 
						||
| 
								 | 
							
												if ( bounds.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													lb[i] = x[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( useRelaxation == BT_TRUE )
							 | 
						||
| 
								 | 
							
														lb[i] = x[i] - BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Setup constraints vectors. */
							 | 
						||
| 
								 | 
							
									for ( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										switch ( constraints.getStatus( i ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											case ST_INACTIVE:
							 | 
						||
| 
								 | 
							
												if ( useRelaxation == BT_TRUE )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( constraints.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														lbA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
														ubA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														/* If a constraint is inactive although it was supposed to be
							 | 
						||
| 
								 | 
							
														* active by the auxiliaryConstraints, it could not be added
							 | 
						||
| 
								 | 
							
														* due to linear dependence. Thus set it "strongly inactive". */
							 | 
						||
| 
								 | 
							
														if ( auxiliaryConstraints->getStatus( i ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
															lbA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
															lbA[i] = Ax[i] - BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														if ( auxiliaryConstraints->getStatus( i ) == ST_UPPER )
							 | 
						||
| 
								 | 
							
															ubA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
															ubA[i] = Ax[i] + BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case ST_LOWER:
							 | 
						||
| 
								 | 
							
												lbA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
												if ( constraints.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ubA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( useRelaxation == BT_TRUE )
							 | 
						||
| 
								 | 
							
														ubA[i] = Ax[i] + BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case ST_UPPER:
							 | 
						||
| 
								 | 
							
												ubA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
												if ( constraints.getType( i ) == ST_EQUALITY )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													lbA[i] = Ax[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( useRelaxation == BT_TRUE )
							 | 
						||
| 
								 | 
							
														lbA[i] = Ax[i] - BOUNDRELAXATION;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	a d d C o n s t r a i n t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::addConstraint(	int number, SubjectToStatus C_status,
							 | 
						||
| 
								 | 
							
																		BooleanType updateCholesky
							 | 
						||
| 
								 | 
							
																		)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency checks */
							 | 
						||
| 
								 | 
							
									if ( constraints.getStatus( number ) != ST_INACTIVE )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_CONSTRAINT_ALREADY_ACTIVE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( constraints.getNC( ) - getNAC( ) ) == constraints.getNUC( ) )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ALL_CONSTRAINTS_ACTIVE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( getStatus( ) == QPS_NOTINITIALISED )    ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED )  ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_SOLVED )            )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) ENSURE LINEAR INDEPENDENCE OF THE WORKING SET,
							 | 
						||
| 
								 | 
							
									 *    i.e. remove a constraint or bound if linear dependence occurs. */
							 | 
						||
| 
								 | 
							
									/* check for LI only if Cholesky decomposition shall be updated! */
							 | 
						||
| 
								 | 
							
									if ( updateCholesky == BT_TRUE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										returnValue ensureLIreturnvalue = addConstraint_ensureLI( number,C_status );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch ( ensureLIreturnvalue )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											case SUCCESSFUL_RETURN:
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case RET_LI_RESOLVED:
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case RET_ENSURELI_FAILED_NOINDEX:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_ADDCONSTRAINT_FAILED_INFEASIBILITY );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case RET_ENSURELI_FAILED_CYCLING:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_ADDCONSTRAINT_FAILED_INFEASIBILITY );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* some definitions */
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int tcol = sizeT - nAC;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ADDCONSTRAINT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t aFR[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t wZ[NVMAX];
							 | 
						||
| 
								 | 
							
									for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
										wZ[i] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) ADD NEW ACTIVE CONSTRAINT TO MATRIX T: */
							 | 
						||
| 
								 | 
							
									/* 1) Add row [wZ wY] = aFR'*[Z Y] to the end of T: assign aFR. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
										aFR[i] = A[number*NVMAX + ii];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* calculate wZ */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
										for( j=0; j<nZ; ++j )
							 | 
						||
| 
								 | 
							
											wZ[j] += aFR[i] * Q[ii*NVMAX + j];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Calculate wY and store it directly into T. */
							 | 
						||
| 
								 | 
							
									if ( nAC > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
											T[nAC*NVMAX + tcol+j] = 0.0;
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
											for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
												T[nAC*NVMAX + tcol+j] += aFR[i] * Q[ii*NVMAX + nZ+j];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t c, s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( nZ > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* II) RESTORE TRIANGULAR FORM OF T: */
							 | 
						||
| 
								 | 
							
										/*     Use column-wise Givens rotations to restore reverse triangular form
							 | 
						||
| 
								 | 
							
										*      of T, simultanenous change of Q (i.e. Z) and R. */
							 | 
						||
| 
								 | 
							
										for( j=0; j<nZ-1; ++j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											computeGivens( wZ[j+1],wZ[j], wZ[j+1],wZ[j],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<=j+1; ++i )
							 | 
						||
| 
								 | 
							
													applyGivens( c,s,R[i*NVMAX + 1+j],R[i*NVMAX + j], R[i*NVMAX + 1+j],R[i*NVMAX + j] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										T[nAC*NVMAX + tcol-1] = wZ[nZ-1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* III) RESTORE TRIANGULAR FORM OF R:
							 | 
						||
| 
								 | 
							
											 *      Use row-wise Givens rotations to restore upper triangular form of R. */
							 | 
						||
| 
								 | 
							
											for( i=0; i<nZ-1; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												computeGivens( R[i*NVMAX + i],R[(1+i)*NVMAX + i], R[i*NVMAX + i],R[(1+i)*NVMAX + i],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( j=(1+i); j<(nZ-1); ++j ) /* last column of R is thrown away */
							 | 
						||
| 
								 | 
							
													applyGivens( c,s,R[i*NVMAX + j],R[(1+i)*NVMAX + j], R[i*NVMAX + j],R[(1+i)*NVMAX + j] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											/* last column of R is thrown away */
							 | 
						||
| 
								 | 
							
											for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
												R[i*NVMAX + nZ-1] = 0.0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* IV) UPDATE INDICES */
							 | 
						||
| 
								 | 
							
									if ( constraints.moveInactiveToActive( number,C_status ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ADDCONSTRAINT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	a d d C o n s t r a i n t _ c h e c k L I
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::addConstraint_checkLI( int number )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, jj;
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INDEXLIST_CORRUPTED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Check if constraint <number> is linearly independent from the
							 | 
						||
| 
								 | 
							
									   the active ones (<=> is element of null space of Afr). */
							 | 
						||
| 
								 | 
							
									real_t sum;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										sum = 0.0;
							 | 
						||
| 
								 | 
							
										for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
											sum += Q[jj*NVMAX + i] * A[number*NVMAX + jj];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( getAbs( sum ) > 10.0*EPS )
							 | 
						||
| 
								 | 
							
											return RET_LINEARLY_INDEPENDENT;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return RET_LINEARLY_DEPENDENT;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	a d d C o n s t r a i n t _ e n s u r e L I
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::addConstraint_ensureLI( int number, SubjectToStatus C_status )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii, jj;
							 | 
						||
| 
								 | 
							
									int nV  = getNV( );
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nFX = getNFX( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) Check if new constraint is linearly independent from the active ones. */
							 | 
						||
| 
								 | 
							
									returnValue returnvalueCheckLI = addConstraint_checkLI( number );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( returnvalueCheckLI == RET_INDEXLIST_CORRUPTED )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT )
							 | 
						||
| 
								 | 
							
										return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 	/* II) NEW CONSTRAINT IS LINEARLY DEPENDENT: */
							 | 
						||
| 
								 | 
							
									/* 1) Determine coefficients of linear combination,
							 | 
						||
| 
								 | 
							
									 *    cf. M.J. Best. Applied Mathematics and Parallel Computing, chapter:
							 | 
						||
| 
								 | 
							
									 *    An Algorithm for the Solution of the Parametric Quadratic Programming
							 | 
						||
| 
								 | 
							
									 *    Problem, pages 57-76. Physica-Verlag, Heidelberg, 1996. */
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FX_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFixed( )->getNumberArray( FX_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t xiC[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t xiC_TMP[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t xiB[NVMAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Calculate xiC */
							 | 
						||
| 
								 | 
							
									if ( nAC > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( C_status == ST_LOWER )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												xiC_TMP[i] = 0.0;
							 | 
						||
| 
								 | 
							
												for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
													xiC_TMP[i] += Q[jj*NVMAX + nZ+i] * A[number*NVMAX + jj];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												xiC_TMP[i] = 0.0;
							 | 
						||
| 
								 | 
							
												for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
													xiC_TMP[i] -= Q[jj*NVMAX + nZ+i] * A[number*NVMAX + jj];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( backsolveT( xiC_TMP, BT_TRUE, xiC ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_ENSURELI_FAILED_TQ );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Calculate xiB. */
							 | 
						||
| 
								 | 
							
									int AC_idx[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( C_status == ST_LOWER )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
											xiB[i] = A[number*NVMAX + ii];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												jj = AC_idx[j];
							 | 
						||
| 
								 | 
							
												xiB[i] -= A[jj*NVMAX + ii] * xiC[j];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
											xiB[i] = -A[number*NVMAX + ii];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												jj = AC_idx[j];
							 | 
						||
| 
								 | 
							
												xiB[i] -= A[jj*NVMAX + ii] * xiC[j];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* III) DETERMINE CONSTRAINT/BOUND TO BE REMOVED. */
							 | 
						||
| 
								 | 
							
									real_t y_min = INFTY * INFTY;
							 | 
						||
| 
								 | 
							
									int y_min_number = -1;
							 | 
						||
| 
								 | 
							
									BooleanType y_min_isBound = BT_FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Constraints. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( constraints.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiC[i] > ZERO ) && ( y[nV+ii] >= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[nV+ii]/xiC[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[nV+ii]/xiC[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiC[i] < -ZERO ) && ( y[nV+ii] <= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[nV+ii]/xiC[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[nV+ii]/xiC[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Bounds. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( bounds.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiB[i] > ZERO ) && ( y[ii] >= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[ii]/xiB[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[ii]/xiB[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
													y_min_isBound = BT_TRUE;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiB[i] < -ZERO ) && ( y[ii] <= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[ii]/xiB[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[ii]/xiB[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
													y_min_isBound = BT_TRUE;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* setup output preferences */
							 | 
						||
| 
								 | 
							
									#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
									char messageString[80];
							 | 
						||
| 
								 | 
							
									VisibilityStatus visibilityStatus;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
										visibilityStatus = VS_VISIBLE;
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										visibilityStatus = VS_HIDDEN;
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* IV) REMOVE CONSTRAINT/BOUND FOR RESOLVING LINEAR DEPENDENCE: */
							 | 
						||
| 
								 | 
							
									if ( y_min_number >= 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* 1) Check for cycling due to infeasibility. */
							 | 
						||
| 
								 | 
							
										if ( ( cyclingManager.getCyclingStatus( number,BT_FALSE ) == CYC_PREV_REMOVED ) &&
							 | 
						||
| 
								 | 
							
											 ( cyclingManager.getCyclingStatus( y_min_number,y_min_isBound ) == CYC_PREV_ADDED ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											infeasible = BT_TRUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_ENSURELI_FAILED_CYCLING );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* set cycling data */
							 | 
						||
| 
								 | 
							
											cyclingManager.clearCyclingData( );
							 | 
						||
| 
								 | 
							
											cyclingManager.setCyclingStatus( number,BT_FALSE, CYC_PREV_ADDED );
							 | 
						||
| 
								 | 
							
											cyclingManager.setCyclingStatus( y_min_number,y_min_isBound, CYC_PREV_REMOVED );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 2) Update Lagrange multiplier... */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
											y[nV+ii] -= y_min * xiC[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
											y[ii] -= y_min * xiB[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* ... also for newly active constraint... */
							 | 
						||
| 
								 | 
							
										if ( C_status == ST_LOWER )
							 | 
						||
| 
								 | 
							
											y[nV+number] = y_min;
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											y[nV+number] = -y_min;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* ... and for constraint to be removed. */
							 | 
						||
| 
								 | 
							
										if ( y_min_isBound == BT_TRUE )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
											sprintf( messageString,"bound no. %d.",y_min_number );
							 | 
						||
| 
								 | 
							
											getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
											#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( removeBound( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											y[y_min_number] = 0.0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
											sprintf( messageString,"constraint no. %d.",y_min_number );
							 | 
						||
| 
								 | 
							
											getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
											#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( removeConstraint( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											y[nV+y_min_number] = 0.0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* no constraint/bound can be removed => QP is infeasible! */
							 | 
						||
| 
								 | 
							
										infeasible = BT_TRUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED_NOINDEX );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNCTION__,__FILE__,__LINE__,VS_HIDDEN );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	a d d B o u n d
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::addBound(	int number, SubjectToStatus B_status,
							 | 
						||
| 
								 | 
							
																BooleanType updateCholesky
							 | 
						||
| 
								 | 
							
																)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency checks */
							 | 
						||
| 
								 | 
							
									if ( bounds.getStatus( number ) != ST_INACTIVE )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_BOUND_ALREADY_ACTIVE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( getNFR( ) == bounds.getNUV( ) )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ALL_BOUNDS_ACTIVE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( getStatus( ) == QPS_NOTINITIALISED )    ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED )  ||
							 | 
						||
| 
								 | 
							
								 		 ( getStatus( ) == QPS_SOLVED )            )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) ENSURE LINEAR INDEPENDENCE OF THE WORKING SET,
							 | 
						||
| 
								 | 
							
									 *    i.e. remove a constraint or bound if linear dependence occurs. */
							 | 
						||
| 
								 | 
							
									/* check for LI only if Cholesky decomposition shall be updated! */
							 | 
						||
| 
								 | 
							
									if ( updateCholesky == BT_TRUE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										returnValue ensureLIreturnvalue = addBound_ensureLI( number,B_status );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch ( ensureLIreturnvalue )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											case SUCCESSFUL_RETURN:
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case RET_LI_RESOLVED:
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case RET_ENSURELI_FAILED_NOINDEX:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_ADDBOUND_FAILED_INFEASIBILITY );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case RET_ENSURELI_FAILED_CYCLING:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_ADDBOUND_FAILED_INFEASIBILITY );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* some definitions */
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int tcol = sizeT - nAC;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) SWAP INDEXLIST OF FREE VARIABLES:
							 | 
						||
| 
								 | 
							
									 *    move the variable to be fixed to the end of the list of free variables. */
							 | 
						||
| 
								 | 
							
									int lastfreenumber = bounds.getFree( )->getLastNumber( );
							 | 
						||
| 
								 | 
							
									if ( lastfreenumber != number )
							 | 
						||
| 
								 | 
							
										if ( bounds.swapFree( number,lastfreenumber ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											THROWERROR( RET_ADDBOUND_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ADDBOUND_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t w[NVMAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) ADD NEW ACTIVE BOUND TO TOP OF MATRIX T: */
							 | 
						||
| 
								 | 
							
									/* 1) add row [wZ wY] = [Z Y](number) at the top of T: assign w */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
										w[i] = Q[FR_idx[nFR-1]*NVMAX + i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Use column-wise Givens rotations to restore reverse triangular form
							 | 
						||
| 
								 | 
							
									 *    of the first row of T, simultanenous change of Q (i.e. Z) and R. */
							 | 
						||
| 
								 | 
							
									real_t c, s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( j=0; j<nZ-1; ++j )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										computeGivens( w[j+1],w[j], w[j+1],w[j],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
											applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<=j+1; ++i )
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,R[i*NVMAX + 1+j],R[i*NVMAX + j], R[i*NVMAX + 1+j],R[i*NVMAX + j] );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( nAC > 0 )	  /* ( nAC == 0 ) <=> ( nZ == nFR ) <=> Y and T are empty => nothing to do */
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* store new column a in a temporary vector instead of shifting T one column to the left */
							 | 
						||
| 
								 | 
							
										real_t tmp[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
										for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
											tmp[i] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											j = nZ-1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											computeGivens( w[j+1],w[j], w[j+1],w[j],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											applyGivens( c,s,T[(nAC-1)*NVMAX + tcol],tmp[nAC-1], tmp[nAC-1],T[(nAC-1)*NVMAX + tcol] );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( j=nZ; j<nFR-1; ++j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											computeGivens( w[j+1],w[j], w[j+1],w[j],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=(nFR-2-j); i<nAC; ++i )
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,T[i*NVMAX + 1+tcol-nZ+j],tmp[i], tmp[i],T[i*NVMAX + 1+tcol-nZ+j] );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* III) RESTORE TRIANGULAR FORM OF R:
							 | 
						||
| 
								 | 
							
										 *      use row-wise Givens rotations to restore upper triangular form of R */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nZ-1; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											computeGivens( R[i*NVMAX + i],R[(1+i)*NVMAX + i], R[i*NVMAX + i],R[(1+i)*NVMAX + i],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( j=(1+i); j<nZ-1; ++j ) /* last column of R is thrown away */
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,R[i*NVMAX + j],R[(1+i)*NVMAX + j], R[i*NVMAX + j],R[(1+i)*NVMAX + j] );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										/* last column of R is thrown away */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
											R[i*NVMAX + nZ-1] = 0.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* IV) UPDATE INDICES */
							 | 
						||
| 
								 | 
							
									if ( bounds.moveFreeToFixed( number,B_status ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ADDBOUND_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	a d d B o u n d _ c h e c k L I
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::addBound_checkLI( int number )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* some definitions */
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Check if constraint <number> is linearly independent from the
							 | 
						||
| 
								 | 
							
									   the active ones (<=> is element of null space of Afr). */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( getAbs( Q[number*NVMAX + i] ) > EPS )
							 | 
						||
| 
								 | 
							
											return RET_LINEARLY_INDEPENDENT;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return RET_LINEARLY_DEPENDENT;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	a d d B o u n d _ e n s u r e L I
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::addBound_ensureLI( int number, SubjectToStatus B_status )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii, jj;
							 | 
						||
| 
								 | 
							
									int nV  = getNV( );
							 | 
						||
| 
								 | 
							
									int nFX = getNFX( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) Check if new constraint is linearly independent from the active ones. */
							 | 
						||
| 
								 | 
							
									returnValue returnvalueCheckLI = addBound_checkLI( number );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT )
							 | 
						||
| 
								 | 
							
										return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 	/* II) NEW BOUND IS LINEARLY DEPENDENT: */
							 | 
						||
| 
								 | 
							
									/* 1) Determine coefficients of linear combination,
							 | 
						||
| 
								 | 
							
									 *    cf. M.J. Best. Applied Mathematics and Parallel Computing, chapter:
							 | 
						||
| 
								 | 
							
									 *    An Algorithm for the Solution of the Parametric Quadratic Programming
							 | 
						||
| 
								 | 
							
									 *    Problem, pages 57-76. Physica-Verlag, Heidelberg, 1996. */
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FX_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFixed( )->getNumberArray( FX_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int AC_idx[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t xiC[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t xiC_TMP[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t xiB[NVMAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Calculate xiC. */
							 | 
						||
| 
								 | 
							
									if ( nAC > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( B_status == ST_LOWER )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
												xiC_TMP[i] = Q[number*NVMAX + nZ+i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
												xiC_TMP[i] = -Q[number*NVMAX + nZ+i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( backsolveT( xiC_TMP, BT_TRUE, xiC ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_ENSURELI_FAILED_TQ );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Calculate xiB. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										xiB[i] = 0.0;
							 | 
						||
| 
								 | 
							
										for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											jj = AC_idx[j];
							 | 
						||
| 
								 | 
							
											xiB[i] -= A[jj*NVMAX + ii] * xiC[j];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* III) DETERMINE CONSTRAINT/BOUND TO BE REMOVED. */
							 | 
						||
| 
								 | 
							
									real_t y_min = INFTY * INFTY;
							 | 
						||
| 
								 | 
							
									int y_min_number = -1;
							 | 
						||
| 
								 | 
							
									BooleanType y_min_isBound = BT_FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Constraints. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( constraints.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiC[i] > ZERO ) && ( y[nV+ii] >= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[nV+ii]/xiC[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[nV+ii]/xiC[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiC[i] < -ZERO ) && ( y[nV+ii] <= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[nV+ii]/xiC[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[nV+ii]/xiC[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Bounds. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( bounds.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiB[i] > ZERO ) && ( y[ii] >= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[ii]/xiB[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[ii]/xiB[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
													y_min_isBound = BT_TRUE;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( xiB[i] < -ZERO ) && ( y[ii] <= 0.0 ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( y[ii]/xiB[i] < y_min )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													y_min = y[ii]/xiB[i];
							 | 
						||
| 
								 | 
							
													y_min_number = ii;
							 | 
						||
| 
								 | 
							
													y_min_isBound = BT_TRUE;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* setup output preferences */
							 | 
						||
| 
								 | 
							
									#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
									char messageString[80];
							 | 
						||
| 
								 | 
							
									VisibilityStatus visibilityStatus;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
										visibilityStatus = VS_VISIBLE;
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										visibilityStatus = VS_HIDDEN;
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* IV) REMOVE CONSTRAINT/BOUND FOR RESOLVING LINEAR DEPENDENCE: */
							 | 
						||
| 
								 | 
							
									if ( y_min_number >= 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* 1) Check for cycling due to infeasibility. */
							 | 
						||
| 
								 | 
							
										if ( ( cyclingManager.getCyclingStatus( number,BT_TRUE ) == CYC_PREV_REMOVED ) &&
							 | 
						||
| 
								 | 
							
											 ( cyclingManager.getCyclingStatus( y_min_number,y_min_isBound ) == CYC_PREV_ADDED ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											infeasible = BT_TRUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_ENSURELI_FAILED_CYCLING );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* set cycling data */
							 | 
						||
| 
								 | 
							
											cyclingManager.clearCyclingData( );
							 | 
						||
| 
								 | 
							
											cyclingManager.setCyclingStatus( number,BT_TRUE, CYC_PREV_ADDED );
							 | 
						||
| 
								 | 
							
											cyclingManager.setCyclingStatus( y_min_number,y_min_isBound, CYC_PREV_REMOVED );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 2) Update Lagrange multiplier... */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
											y[nV+ii] -= y_min * xiC[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
											y[ii] -= y_min * xiB[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* ... also for newly active bound ... */
							 | 
						||
| 
								 | 
							
										if ( B_status == ST_LOWER )
							 | 
						||
| 
								 | 
							
											y[number] = y_min;
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											y[number] = -y_min;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* ... and for bound to be removed. */
							 | 
						||
| 
								 | 
							
										if ( y_min_isBound == BT_TRUE )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
											sprintf( messageString,"bound no. %d.",y_min_number );
							 | 
						||
| 
								 | 
							
											getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
											#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( removeBound( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											y[y_min_number] = 0.0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
											sprintf( messageString,"constraint no. %d.",y_min_number );
							 | 
						||
| 
								 | 
							
											getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
											#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( removeConstraint( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											y[nV+y_min_number] = 0.0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* no constraint/bound can be removed => QP is infeasible! */
							 | 
						||
| 
								 | 
							
										infeasible = BT_TRUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_ENSURELI_FAILED_NOINDEX );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNCTION__,__FILE__,__LINE__,VS_HIDDEN );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	r e m o v e C o n s t r a i n t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::removeConstraint(	int number,
							 | 
						||
| 
								 | 
							
																		BooleanType updateCholesky
							 | 
						||
| 
								 | 
							
																		)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii, jj;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency check */
							 | 
						||
| 
								 | 
							
									if ( ( getStatus( ) == QPS_NOTINITIALISED )    ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED )  ||
							 | 
						||
| 
								 | 
							
								 		 ( getStatus( ) == QPS_SOLVED )            )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* some definitions */
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int tcol = sizeT - nAC;
							 | 
						||
| 
								 | 
							
									int number_idx = constraints.getActive( )->getIndex( number );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency checks */
							 | 
						||
| 
								 | 
							
									if ( constraints.getStatus( number ) == ST_INACTIVE )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( number_idx < 0 ) || ( number_idx >= nAC ) )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_REMOVECONSTRAINT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) REMOVE <number>th ROW FROM T,
							 | 
						||
| 
								 | 
							
									 *    i.e. shift rows number+1 through nAC  upwards (instead of the actual
							 | 
						||
| 
								 | 
							
									 *    constraint number its corresponding index within matrix A is used). */
							 | 
						||
| 
								 | 
							
									if ( number_idx < nAC-1 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=(number_idx+1); i<nAC; ++i )
							 | 
						||
| 
								 | 
							
											for( j=(nAC-i-1); j<nAC; ++j )
							 | 
						||
| 
								 | 
							
												T[(i-1)*NVMAX + tcol+j] = T[i*NVMAX + tcol+j];
							 | 
						||
| 
								 | 
							
										/* gimmick: write zeros into the last row of T */
							 | 
						||
| 
								 | 
							
										for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
											T[(nAC-1)*NVMAX + tcol+j] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* II) RESTORE TRIANGULAR FORM OF T,
							 | 
						||
| 
								 | 
							
										 *     use column-wise Givens rotations to restore reverse triangular form
							 | 
						||
| 
								 | 
							
										 *     of T simultanenous change of Q (i.e. Y). */
							 | 
						||
| 
								 | 
							
										real_t c, s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( j=(nAC-2-number_idx); j>=0; --j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											computeGivens( T[(nAC-2-j)*NVMAX + tcol+1+j],T[(nAC-2-j)*NVMAX + tcol+j], T[(nAC-2-j)*NVMAX + tcol+1+j],T[(nAC-2-j)*NVMAX + tcol+j],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=(nAC-j-1); i<(nAC-1); ++i )
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,T[i*NVMAX + tcol+1+j],T[i*NVMAX + tcol+j], T[i*NVMAX + tcol+1+j],T[i*NVMAX + tcol+j] );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j], Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* gimmick: write zeros into the last row of T */
							 | 
						||
| 
								 | 
							
										for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
											T[(nAC-1)*NVMAX + tcol+j] = 0.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* III) UPDATE CHOLESKY DECOMPOSITION,
							 | 
						||
| 
								 | 
							
										 *      calculate new additional column (i.e. [r sqrt(rho2)]')
							 | 
						||
| 
								 | 
							
										 *      of the Cholesky factor R. */
							 | 
						||
| 
								 | 
							
										real_t Hz[NVMAX];
							 | 
						||
| 
								 | 
							
										for ( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
											Hz[i] = 0.0;
							 | 
						||
| 
								 | 
							
										real_t rho2 = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 1) Calculate Hz = H*z, where z is the new rightmost column of Z
							 | 
						||
| 
								 | 
							
										 *    (i.e. the old leftmost column of Y).  */
							 | 
						||
| 
								 | 
							
										for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
											for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												Hz[i] += H[jj*NVMAX + FR_idx[i]] * Q[jj*NVMAX + nZ];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( nZ > 0 )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											real_t ZHz[NVMAX];
							 | 
						||
| 
								 | 
							
											for ( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
												ZHz[i] = 0.0;
							 | 
						||
| 
								 | 
							
											real_t r[NVMAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* 2) Calculate ZHz = Z'*Hz (old Z). */
							 | 
						||
| 
								 | 
							
											for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
													ZHz[i] += Q[jj*NVMAX + i] * Hz[j];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* 3) Calculate r = R^-T * ZHz. */
							 | 
						||
| 
								 | 
							
											if ( backsolveR( ZHz,BT_TRUE,r ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_REMOVECONSTRAINT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* 4) Calculate rho2 = rho^2 = z'*Hz - r'*r
							 | 
						||
| 
								 | 
							
											 *    and store r into R. */
							 | 
						||
| 
								 | 
							
											for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												rho2 -= r[i]*r[i];
							 | 
						||
| 
								 | 
							
												R[i*NVMAX + nZ] = r[i];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
											rho2 += Q[FR_idx[j]*NVMAX + nZ] * Hz[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 5) Store rho into R. */
							 | 
						||
| 
								 | 
							
										if ( rho2 > 0.0 )
							 | 
						||
| 
								 | 
							
											R[nZ*NVMAX + nZ] = sqrt( rho2 );
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											hessianType = HST_SEMIDEF;
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_HESSIAN_NOT_SPD );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* IV) UPDATE INDICES */
							 | 
						||
| 
								 | 
							
									if ( constraints.moveActiveToInactive( number ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_REMOVECONSTRAINT_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	r e m o v e B o u n d
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::removeBound(	int number,
							 | 
						||
| 
								 | 
							
																	BooleanType updateCholesky
							 | 
						||
| 
								 | 
							
																	)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii, jj;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency checks */
							 | 
						||
| 
								 | 
							
									if ( bounds.getStatus( number ) == ST_INACTIVE )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_BOUND_NOT_ACTIVE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( getStatus( ) == QPS_NOTINITIALISED )    ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
							 | 
						||
| 
								 | 
							
										 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED )  ||
							 | 
						||
| 
								 | 
							
								 		 ( getStatus( ) == QPS_SOLVED )            )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_UNKNOWN_BUG );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* some definitions */
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int tcol = sizeT - nAC;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) UPDATE INDICES */
							 | 
						||
| 
								 | 
							
									if ( bounds.moveFixedToFree( number ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_REMOVEBOUND_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int FR_idx[NVMAX];
							 | 
						||
| 
								 | 
							
									if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_REMOVEBOUND_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) APPEND <nFR+1>th UNITY VECOTR TO Q. */
							 | 
						||
| 
								 | 
							
									int nnFRp1 = FR_idx[nFR];
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
										Q[ii*NVMAX + nFR] = 0.0;
							 | 
						||
| 
								 | 
							
										Q[nnFRp1*NVMAX + i] = 0.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									Q[nnFRp1*NVMAX + nFR] = 1.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( nAC > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* store new column a in a temporary vector instead of shifting T one column to the left and appending a */
							 | 
						||
| 
								 | 
							
										int AC_idx[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
										if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_REMOVEBOUND_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										real_t tmp[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
										for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
											tmp[i] =  A[ii*NVMAX + number];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* II) RESTORE TRIANGULAR FORM OF T,
							 | 
						||
| 
								 | 
							
										 *     use column-wise Givens rotations to restore reverse triangular form
							 | 
						||
| 
								 | 
							
										 *     of T = [T A(:,number)], simultanenous change of Q (i.e. Y and Z). */
							 | 
						||
| 
								 | 
							
										real_t c, s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( j=(nAC-1); j>=0; --j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											computeGivens( tmp[nAC-1-j],T[(nAC-1-j)*NVMAX + tcol+j],T[(nAC-1-j)*NVMAX + tcol+j],tmp[nAC-1-j],c,s );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=(nAC-j); i<nAC; ++i )
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,tmp[i],T[i*NVMAX + tcol+j],T[i*NVMAX + tcol+j],tmp[i] );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<=nFR; ++i )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
												/* nZ+1+nAC = nFR+1  /  nZ+(1) = nZ+1 */
							 | 
						||
| 
								 | 
							
												applyGivens( c,s,Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j],Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* III) UPDATE CHOLESKY DECOMPOSITION,
							 | 
						||
| 
								 | 
							
										 *      calculate new additional column (i.e. [r sqrt(rho2)]')
							 | 
						||
| 
								 | 
							
										 *      of the Cholesky factor R: */
							 | 
						||
| 
								 | 
							
										real_t z2 = Q[nnFRp1*NVMAX + nZ];
							 | 
						||
| 
								 | 
							
										real_t rho2 = H[nnFRp1*NVMAX + nnFRp1]*z2*z2; /* rho2 = h2*z2*z2 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( nFR > 0 )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											real_t Hz[NVMAX];
							 | 
						||
| 
								 | 
							
											for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												Hz[i] = 0.0;
							 | 
						||
| 
								 | 
							
											/* 1) Calculate R'*r = Zfr'*Hfr*z1 + z2*Zfr'*h1 =: Zfr'*Hz + z2*Zfr'*h1 =: rhs and
							 | 
						||
| 
								 | 
							
											 *    rho2 = z1'*Hfr*z1 + 2*z2*h1'*z1 + h2*z2^2 - r'*r =: z1'*Hz + 2*z2*h1'*z1 + h2*z2^2 - r'r */
							 | 
						||
| 
								 | 
							
											for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													/*			   H * z1 */
							 | 
						||
| 
								 | 
							
													Hz[i] += H[jj*NVMAX + ii] * Q[jj*NVMAX + nZ];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( nZ > 0 )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												real_t r[NVMAX];
							 | 
						||
| 
								 | 
							
												real_t rhs[NVMAX];
							 | 
						||
| 
								 | 
							
												for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
													rhs[i] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* 2) Calculate rhs. */
							 | 
						||
| 
								 | 
							
												for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
													for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
																		/* Zfr' * ( Hz + z2*h1 ) */
							 | 
						||
| 
								 | 
							
														rhs[i] += Q[jj*NVMAX + i] * ( Hz[j] + z2 * H[nnFRp1*NVMAX + jj] );
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* 3) Calculate r = R^-T * rhs. */
							 | 
						||
| 
								 | 
							
												if ( backsolveR( rhs,BT_TRUE,BT_TRUE,r ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_REMOVEBOUND_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												/* 4) Calculate rho2 = rho^2 = z'*Hz - r'*r
							 | 
						||
| 
								 | 
							
												 *    and store r into R. */
							 | 
						||
| 
								 | 
							
												for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													rho2 -= r[i]*r[i];
							 | 
						||
| 
								 | 
							
													R[i*NVMAX + nZ] = r[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
															/* z1' * ( Hz + 2*z2*h1 ) */
							 | 
						||
| 
								 | 
							
												rho2 += Q[jj*NVMAX + nZ] * ( Hz[j] + 2.0*z2*H[nnFRp1*NVMAX + jj] );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 5) Store rho into R. */
							 | 
						||
| 
								 | 
							
										if ( rho2 > 0.0 )
							 | 
						||
| 
								 | 
							
											R[nZ*NVMAX + nZ] = sqrt( rho2 );
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											hessianType = HST_SEMIDEF;
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_HESSIAN_NOT_SPD );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	b a c k s o l v e R  (CODE DUPLICATE OF QProblemB CLASS!!!)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::backsolveR(	const real_t* const b, BooleanType transposed,
							 | 
						||
| 
								 | 
							
																	real_t* const a
							 | 
						||
| 
								 | 
							
																	)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* Call standard backsolve procedure (i.e. removingBound == BT_FALSE). */
							 | 
						||
| 
								 | 
							
									return backsolveR( b,transposed,BT_FALSE,a );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	b a c k s o l v e R  (CODE DUPLICATE OF QProblemB CLASS!!!)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::backsolveR(	const real_t* const b, BooleanType transposed,
							 | 
						||
| 
								 | 
							
																	BooleanType removingBound,
							 | 
						||
| 
								 | 
							
																	real_t* const a
							 | 
						||
| 
								 | 
							
																	)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
									int nR = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t sum;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* if backsolve is called while removing a bound, reduce nZ by one. */
							 | 
						||
| 
								 | 
							
									if ( removingBound == BT_TRUE )
							 | 
						||
| 
								 | 
							
										--nR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* nothing to do */
							 | 
						||
| 
								 | 
							
									if ( nR <= 0 )
							 | 
						||
| 
								 | 
							
										return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Solve Ra = b, where R might be transposed. */
							 | 
						||
| 
								 | 
							
									if ( transposed == BT_FALSE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* solve Ra = b */
							 | 
						||
| 
								 | 
							
										for( i=(nR-1); i>=0; --i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											sum = b[i];
							 | 
						||
| 
								 | 
							
											for( j=(i+1); j<nR; ++j )
							 | 
						||
| 
								 | 
							
												sum -= R[i*NVMAX + j] * a[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( getAbs( R[i*NVMAX + i] ) > ZERO )
							 | 
						||
| 
								 | 
							
												a[i] = sum / R[i*NVMAX + i];
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_DIV_BY_ZERO );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* solve R^T*a = b */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nR; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											sum = b[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( j=0; j<i; ++j )
							 | 
						||
| 
								 | 
							
												sum -= R[j*NVMAX + i] * a[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( getAbs( R[i*NVMAX + i] ) > ZERO )
							 | 
						||
| 
								 | 
							
												a[i] = sum / R[i*NVMAX + i];
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_DIV_BY_ZERO );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	b a c k s o l v e T
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::backsolveT( const real_t* const b, BooleanType transposed, real_t* const a )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
									int nT = getNAC( );
							 | 
						||
| 
								 | 
							
									int tcol = sizeT - nT;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t sum;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* nothing to do */
							 | 
						||
| 
								 | 
							
									if ( nT <= 0 )
							 | 
						||
| 
								 | 
							
										return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Solve Ta = b, where T might be transposed. */
							 | 
						||
| 
								 | 
							
									if ( transposed == BT_FALSE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* solve Ta = b */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nT; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											sum = b[i];
							 | 
						||
| 
								 | 
							
											for( j=0; j<i; ++j )
							 | 
						||
| 
								 | 
							
												sum -= T[i*NVMAX + sizeT-1-j] * a[nT-1-j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( getAbs( T[i*NVMAX + sizeT-1-i] ) > ZERO )
							 | 
						||
| 
								 | 
							
												a[nT-1-i] = sum / T[i*NVMAX + sizeT-1-i];
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_DIV_BY_ZERO );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* solve T^T*a = b */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nT; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											sum = b[i];
							 | 
						||
| 
								 | 
							
											for( j=0; j<i; ++j )
							 | 
						||
| 
								 | 
							
												sum -= T[(nT-1-j)*NVMAX + tcol+i] * a[nT-1-j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( getAbs( T[(nT-1-i)*NVMAX + tcol+i] ) > ZERO )
							 | 
						||
| 
								 | 
							
												a[nT-1-i] = sum / T[(nT-1-i)*NVMAX + tcol+i];
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												return THROWERROR( RET_DIV_BY_ZERO );
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	h o t s t a r t _ d e t e r m i n e D a t a S h i f t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::hotstart_determineDataShift(  const int* const FX_idx, const int* const AC_idx,
							 | 
						||
| 
								 | 
							
																					const real_t* const g_new, const real_t* const lbA_new, const real_t* const ubA_new,
							 | 
						||
| 
								 | 
							
																					const real_t* const lb_new, const real_t* const ub_new,
							 | 
						||
| 
								 | 
							
																					real_t* const delta_g, real_t* const delta_lbA, real_t* const delta_ubA,
							 | 
						||
| 
								 | 
							
																					real_t* const delta_lb, real_t* const delta_ub,
							 | 
						||
| 
								 | 
							
																					BooleanType& Delta_bC_isZero, BooleanType& Delta_bB_isZero
							 | 
						||
| 
								 | 
							
																					)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, ii;
							 | 
						||
| 
								 | 
							
									int nC  = getNC( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) DETERMINE DATA SHIFT FOR BOUNDS */
							 | 
						||
| 
								 | 
							
									QProblemB::hotstart_determineDataShift( FX_idx,g_new,lb_new,ub_new, delta_g,delta_lb,delta_ub, Delta_bB_isZero );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) DETERMINE DATA SHIFT FOR CONSTRAINTS */
							 | 
						||
| 
								 | 
							
									/* 1) Calculate shift directions. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* if lower constraints' bounds do not exist, shift them to -infinity */
							 | 
						||
| 
								 | 
							
										if ( lbA_new != 0 )
							 | 
						||
| 
								 | 
							
											delta_lbA[i] = lbA_new[i] - lbA[i];
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											delta_lbA[i] = -INFTY - lbA[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* if upper constraints' bounds do not exist, shift them to infinity */
							 | 
						||
| 
								 | 
							
										if ( ubA_new != 0 )
							 | 
						||
| 
								 | 
							
											delta_ubA[i] = ubA_new[i] - ubA[i];
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											delta_ubA[i] = INFTY - ubA[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Determine if active constraints' bounds are to be shifted. */
							 | 
						||
| 
								 | 
							
									Delta_bC_isZero = BT_TRUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for ( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( ( getAbs( delta_lbA[ii] ) > EPS ) || ( getAbs( delta_ubA[ii] ) > EPS ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											Delta_bC_isZero = BT_FALSE;
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	h o t s t a r t _ d e t e r m i n e S t e p D i r e c t i o n
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::hotstart_determineStepDirection(	const int* const FR_idx, const int* const FX_idx, const int* const AC_idx,
							 | 
						||
| 
								 | 
							
																						const real_t* const delta_g, const real_t* const delta_lbA, const real_t* const delta_ubA,
							 | 
						||
| 
								 | 
							
																						const real_t* const delta_lb, const real_t* const delta_ub,
							 | 
						||
| 
								 | 
							
																						BooleanType Delta_bC_isZero, BooleanType Delta_bB_isZero,
							 | 
						||
| 
								 | 
							
																						real_t* const delta_xFX, real_t* const delta_xFR,
							 | 
						||
| 
								 | 
							
																						real_t* const delta_yAC, real_t* const delta_yFX
							 | 
						||
| 
								 | 
							
																						)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii, jj;
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nFX = getNFX( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nZ  = getNZ( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* initialise auxiliary vectors */
							 | 
						||
| 
								 | 
							
									real_t HMX_delta_xFX[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t YFR_delta_xFRy[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t ZFR_delta_xFRz[NVMAX];
							 | 
						||
| 
								 | 
							
									real_t HFR_YFR_delta_xFRy[NVMAX];
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										delta_xFR[i] = 0.0;
							 | 
						||
| 
								 | 
							
										HMX_delta_xFX[i] = 0.0;
							 | 
						||
| 
								 | 
							
										YFR_delta_xFRy[i] = 0.0;
							 | 
						||
| 
								 | 
							
										ZFR_delta_xFRz[i] = 0.0;
							 | 
						||
| 
								 | 
							
										HFR_YFR_delta_xFRy[i] = 0.0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t delta_xFRy[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									real_t delta_xFRz[NVMAX];
							 | 
						||
| 
								 | 
							
									for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
										delta_xFRz[i] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) DETERMINE delta_xFX */
							 | 
						||
| 
								 | 
							
									if ( nFX > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( bounds.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
												delta_xFX[i] = delta_lb[ii];
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												delta_xFX[i] = delta_ub[ii];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) DETERMINE delta_xFR */
							 | 
						||
| 
								 | 
							
									if ( nFR > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* 1) Determine delta_xFRy. */
							 | 
						||
| 
								 | 
							
										if ( nAC > 0 )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( Delta_bC_isZero == BT_TRUE ) && ( Delta_bB_isZero == BT_TRUE ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
													delta_xFRy[i] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
													delta_xFR[i] = 0.0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* auxillary variable */
							 | 
						||
| 
								 | 
							
												real_t delta_xFRy_TMP[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													if ( constraints.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
														delta_xFRy_TMP[i] = delta_lbA[ii];
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														delta_xFRy_TMP[i] = delta_ubA[ii];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													if ( Delta_bB_isZero == BT_FALSE )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														for( j=0; j<nFX; ++j )
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															jj = FX_idx[j];
							 | 
						||
| 
								 | 
							
															delta_xFRy_TMP[i] -= A[ii*NVMAX + jj] * delta_xFX[j];
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( backsolveT( delta_xFRy_TMP, BT_FALSE, delta_xFRy ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_STEPDIRECTION_FAILED_TQ );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
														YFR_delta_xFRy[i] += Q[ii*NVMAX + nZ+j] * delta_xFRy[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													/* delta_xFR = YFR*delta_xFRy (+ ZFR*delta_xFRz) */
							 | 
						||
| 
								 | 
							
													delta_xFR[i] = YFR_delta_xFRy[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 2) Determine delta_xFRz. */
							 | 
						||
| 
								 | 
							
										if ( hessianType == HST_IDENTITY )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
												for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
													delta_xFRz[i] -= Q[jj*NVMAX + i] * delta_g[jj];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( nZ > 0 )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													for( j=0; j<nZ; ++j )
							 | 
						||
| 
								 | 
							
														ZFR_delta_xFRz[i] += Q[ii*NVMAX + j] * delta_xFRz[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													delta_xFR[i] += ZFR_delta_xFRz[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( Delta_bB_isZero == BT_FALSE )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													for( j=0; j<nFX; ++j )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														jj = FX_idx[j];
							 | 
						||
| 
								 | 
							
														HMX_delta_xFX[i] += H[ii*NVMAX + jj] * delta_xFX[j];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( nAC > 0 )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( ( Delta_bC_isZero == BT_FALSE ) || ( Delta_bB_isZero == BT_FALSE ) )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
														for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
															HFR_YFR_delta_xFRy[i] += H[ii*NVMAX + jj] * YFR_delta_xFRy[j];
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( nZ > 0 )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* auxiliary variable */
							 | 
						||
| 
								 | 
							
												real_t delta_xFRz_TMP[NVMAX];
							 | 
						||
| 
								 | 
							
												real_t delta_xFRz_RHS[NVMAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( ( nAC > 0 ) && ( nFX > 0 ) && ( Delta_bB_isZero == BT_FALSE ) )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
														delta_xFRz_RHS[j] = delta_g[jj] + HFR_YFR_delta_xFRy[j] + HMX_delta_xFX[j];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( ( nAC == 0 ) && ( Delta_bB_isZero == BT_TRUE ) )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
															delta_xFRz_RHS[j] = delta_g[jj];
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if ( nAC > 0 ) /* => Delta_bB_isZero == BT_TRUE, as BT_FALSE would imply nFX>0 */
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
															{
							 | 
						||
| 
								 | 
							
																jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
																delta_xFRz_RHS[j] = delta_g[jj] + HFR_YFR_delta_xFRy[j];
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else /* Delta_bB_isZero == BT_FALSE, as nAC==0 */
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
															{
							 | 
						||
| 
								 | 
							
																jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
																delta_xFRz_RHS[j] = delta_g[jj] + HMX_delta_xFX[j];
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
													for( i=0; i<nZ; ++i )
							 | 
						||
| 
								 | 
							
														delta_xFRz[i] -= Q[jj*NVMAX + i] * delta_xFRz_RHS[j];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( backsolveR( delta_xFRz,BT_TRUE,delta_xFRz_TMP ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_STEPDIRECTION_FAILED_CHOLESKY );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( backsolveR( delta_xFRz_TMP,BT_FALSE,delta_xFRz ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_STEPDIRECTION_FAILED_CHOLESKY );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													for( j=0; j<nZ; ++j )
							 | 
						||
| 
								 | 
							
														ZFR_delta_xFRz[i] += Q[ii*NVMAX + j] * delta_xFRz[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													delta_xFR[i] += ZFR_delta_xFRz[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* III) DETERMINE delta_yAC */
							 | 
						||
| 
								 | 
							
									if ( nAC > 0 ) /* => ( nFR = nZ + nAC > 0 ) */
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* auxiliary variables */
							 | 
						||
| 
								 | 
							
										real_t delta_yAC_TMP[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
										for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
											delta_yAC_TMP[i] = 0.0;
							 | 
						||
| 
								 | 
							
										real_t delta_yAC_RHS[NVMAX];
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
											delta_yAC_RHS[i] = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( hessianType == HST_IDENTITY )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* delta_yAC = (T')^-1 * ( Yfr*delta_gFR + delta_xFRy ) */
							 | 
						||
| 
								 | 
							
											for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													delta_yAC_TMP[j] += Q[ii*NVMAX + nZ+j] * delta_g[ii];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												delta_yAC_TMP[j] += delta_xFRy[j];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( ( Delta_bC_isZero == BT_TRUE ) && ( Delta_bB_isZero == BT_TRUE ) )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													delta_yAC_RHS[i] = delta_g[ii];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													delta_yAC_RHS[i] = HFR_YFR_delta_xFRy[i] + delta_g[ii];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( nZ > 0 )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
													for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
														delta_yAC_RHS[i] += H[ii*NVMAX + jj] * ZFR_delta_xFRz[j];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( nFX > 0 )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( Delta_bB_isZero == BT_FALSE )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
														delta_yAC_RHS[i] += HMX_delta_xFX[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( i=0; i<nAC; ++i)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
													delta_yAC_TMP[i] += Q[jj*NVMAX + nZ+i] * delta_yAC_RHS[j];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( backsolveT( delta_yAC_TMP,BT_TRUE,delta_yAC ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
											return THROWERROR( RET_STEPDIRECTION_FAILED_TQ );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* IV) DETERMINE delta_yFX */
							 | 
						||
| 
								 | 
							
									if ( nFX > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											delta_yFX[i] = delta_g[ii];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												jj = AC_idx[j];
							 | 
						||
| 
								 | 
							
												delta_yFX[i] -= A[jj*NVMAX + ii] * delta_yAC[j];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( hessianType == HST_IDENTITY )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												delta_yFX[i] += delta_xFX[i];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
													delta_yFX[i] += H[ii*NVMAX + jj] * delta_xFR[j];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( Delta_bB_isZero == BT_FALSE )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													for( j=0; j<nFX; ++j )
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														jj = FX_idx[j];
							 | 
						||
| 
								 | 
							
														delta_yFX[i] += H[ii*NVMAX + jj] * delta_xFX[j];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	h o t s t a r t _ d e t e r m i n e S t e p L e n g t h
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::hotstart_determineStepLength(	const int* const FR_idx, const int* const FX_idx, const int* const AC_idx, const int* const IAC_idx,
							 | 
						||
| 
								 | 
							
																					const real_t* const delta_lbA, const real_t* const delta_ubA,
							 | 
						||
| 
								 | 
							
																					const real_t* const delta_lb, const real_t* const delta_ub,
							 | 
						||
| 
								 | 
							
																					const real_t* const delta_xFX, const real_t* const delta_xFR,
							 | 
						||
| 
								 | 
							
																					const real_t* const delta_yAC, const real_t* const delta_yFX,
							 | 
						||
| 
								 | 
							
																					real_t* const delta_Ax, int& BC_idx, SubjectToStatus& BC_status, BooleanType& BC_isBound
							 | 
						||
| 
								 | 
							
																					)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii, jj;
							 | 
						||
| 
								 | 
							
									int nV  = getNV( );
							 | 
						||
| 
								 | 
							
									int nC  = getNC( );
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nFX = getNFX( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nIAC = getNIAC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* initialise maximum steplength array */
							 | 
						||
| 
								 | 
							
									real_t maxStepLength[2*(NVMAX+NCMAX_ALLOC)];
							 | 
						||
| 
								 | 
							
									for ( i=0; i<2*(nV+nC); ++i )
							 | 
						||
| 
								 | 
							
										maxStepLength[i] = 1.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) DETERMINE MAXIMUM DUAL STEPLENGTH: */
							 | 
						||
| 
								 | 
							
									/* 1) Ensure that active dual constraints' bounds remain valid
							 | 
						||
| 
								 | 
							
									 *    (ignoring inequality constraints).  */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( constraints.getType( ii ) != ST_EQUALITY )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( constraints.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* active lower constraints' bounds */
							 | 
						||
| 
								 | 
							
												if ( delta_yAC[i] < -ZERO )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( y[nV+ii] > 0.0 )
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+ii] = y[nV+ii] / ( -delta_yAC[i] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* active upper constraints' bounds */
							 | 
						||
| 
								 | 
							
												if ( delta_yAC[i] > ZERO )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( y[nV+ii] < 0.0 )
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+ii] = y[nV+ii] / ( -delta_yAC[i] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Ensure that active dual bounds remain valid
							 | 
						||
| 
								 | 
							
									 *    (ignoring implicitly fixed variables). */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( bounds.getType( ii ) != ST_EQUALITY )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if ( bounds.getStatus( ii ) == ST_LOWER )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* active lower bounds */
							 | 
						||
| 
								 | 
							
												if ( delta_yFX[i] < -ZERO )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( y[ii] > 0.0 )
							 | 
						||
| 
								 | 
							
														maxStepLength[ii] = y[ii] / ( -delta_yFX[i] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												/* active upper bounds */
							 | 
						||
| 
								 | 
							
												if ( delta_yFX[i] > ZERO )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( y[ii] < 0.0 )
							 | 
						||
| 
								 | 
							
														maxStepLength[ii] = y[ii] / ( -delta_yFX[i] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) DETERMINE MAXIMUM PRIMAL STEPLENGTH */
							 | 
						||
| 
								 | 
							
									/* 1) Ensure that inactive constraints' bounds remain valid
							 | 
						||
| 
								 | 
							
									 *    (ignoring unbounded constraints). */
							 | 
						||
| 
								 | 
							
									real_t delta_x[NVMAX];
							 | 
						||
| 
								 | 
							
									for( j=0; j<nFR; ++j )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										jj = FR_idx[j];
							 | 
						||
| 
								 | 
							
										delta_x[jj] = delta_xFR[j];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for( j=0; j<nFX; ++j )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										jj = FX_idx[j];
							 | 
						||
| 
								 | 
							
										delta_x[jj] = delta_xFX[j];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for( i=0; i<nIAC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ii = IAC_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( constraints.getType( ii ) != ST_UNBOUNDED )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											delta_Ax[ii] = 0.0;
							 | 
						||
| 
								 | 
							
											for( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
												delta_Ax[ii] += A[ii*NVMAX + j] * delta_x[j]; // POSSIBLE SPEEDUP!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* inactive lower constraints' bounds */
							 | 
						||
| 
								 | 
							
											if ( constraints.isNoLower( ) == BT_FALSE )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( delta_lbA[ii] > delta_Ax[ii] )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( Ax[ii] > lbA[ii] )
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+ii] = ( Ax[ii] - lbA[ii] ) / ( delta_lbA[ii] - delta_Ax[ii] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											/* inactive upper constraints' bounds */
							 | 
						||
| 
								 | 
							
											if ( constraints.isNoUpper( ) == BT_FALSE )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if ( delta_ubA[ii] < delta_Ax[ii] )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( Ax[ii] < ubA[ii] )
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+nC+nV+ii] = ( Ax[ii] - ubA[ii] ) / ( delta_ubA[ii] - delta_Ax[ii] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+nC+nV+ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Ensure that inactive bounds remain valid
							 | 
						||
| 
								 | 
							
									 *    (ignoring unbounded variables). */
							 | 
						||
| 
								 | 
							
									/* inactive lower bounds */
							 | 
						||
| 
								 | 
							
									if ( bounds.isNoLower( ) == BT_FALSE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
											if ( bounds.getType( ii ) != ST_UNBOUNDED )
							 | 
						||
| 
								 | 
							
												if ( delta_lb[ii] > delta_xFR[i] )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( x[ii] > lb[ii] )
							 | 
						||
| 
								 | 
							
														maxStepLength[ii] = ( x[ii] - lb[ii] ) / ( delta_lb[ii] - delta_xFR[i] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* inactive upper bounds */
							 | 
						||
| 
								 | 
							
									if ( bounds.isNoUpper( ) == BT_FALSE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
											if ( bounds.getType( ii ) != ST_UNBOUNDED )
							 | 
						||
| 
								 | 
							
												if ( delta_ub[ii] < delta_xFR[i] )
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if ( x[ii] < ub[ii] )
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+nC+ii] = ( x[ii] - ub[ii] ) / ( delta_ub[ii] - delta_xFR[i] );
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
														maxStepLength[nV+nC+ii] = 0.0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* III) DETERMINE MAXIMUM HOMOTOPY STEPLENGTH */
							 | 
						||
| 
								 | 
							
									real_t tau_new = 1.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BC_idx = 0;
							 | 
						||
| 
								 | 
							
									BC_status = ST_UNDEFINED;
							 | 
						||
| 
								 | 
							
									BC_isBound = BT_FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for ( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* 1) Consider lower/dual blocking bounds. */
							 | 
						||
| 
								 | 
							
										if ( maxStepLength[i] < tau_new )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											tau_new = maxStepLength[i];
							 | 
						||
| 
								 | 
							
											BC_idx = i;
							 | 
						||
| 
								 | 
							
											BC_isBound = BT_TRUE;
							 | 
						||
| 
								 | 
							
											if ( bounds.getStatus( i ) == ST_INACTIVE ) /* inactive? */
							 | 
						||
| 
								 | 
							
												BC_status = ST_LOWER;
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												BC_status = ST_INACTIVE;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 2) Consider upper blocking bounds. */
							 | 
						||
| 
								 | 
							
										if ( maxStepLength[nV+nC+i] < tau_new )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											tau_new = maxStepLength[nV+nC+i];
							 | 
						||
| 
								 | 
							
											BC_idx = i;
							 | 
						||
| 
								 | 
							
											BC_isBound = BT_TRUE;
							 | 
						||
| 
								 | 
							
											BC_status = ST_UPPER;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for ( i=nV; i<nV+nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* 3) Consider lower/dual blocking constraints. */
							 | 
						||
| 
								 | 
							
										if ( maxStepLength[i] < tau_new )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											tau_new = maxStepLength[i];
							 | 
						||
| 
								 | 
							
											BC_idx = i-nV;
							 | 
						||
| 
								 | 
							
											BC_isBound = BT_FALSE;
							 | 
						||
| 
								 | 
							
											if ( constraints.getStatus( i-nV ) == ST_INACTIVE ) /* inactive? */
							 | 
						||
| 
								 | 
							
												BC_status = ST_LOWER;
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												BC_status = ST_INACTIVE;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 4) Consider upper blocking constraints. */
							 | 
						||
| 
								 | 
							
										if ( maxStepLength[nV+nC+i] < tau_new )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											tau_new = maxStepLength[nV+nC+i];
							 | 
						||
| 
								 | 
							
											BC_idx = i-nV;
							 | 
						||
| 
								 | 
							
											BC_isBound = BT_FALSE;
							 | 
						||
| 
								 | 
							
											BC_status = ST_UPPER;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* IV) CLEAR CYCLING DATA
							 | 
						||
| 
								 | 
							
									 *     if a positive step can be taken */
							 | 
						||
| 
								 | 
							
									if ( tau_new > EPS )
							 | 
						||
| 
								 | 
							
										cyclingManager.clearCyclingData( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* V) SET MAXIMUM HOMOTOPY STEPLENGTH */
							 | 
						||
| 
								 | 
							
									tau = tau_new;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
									if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									 	char messageString[80];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( BC_status == ST_UNDEFINED )
							 | 
						||
| 
								 | 
							
											sprintf( messageString,"Stepsize is %.6e!",tau );
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											sprintf( messageString,"Stepsize is %.6e! (BC_idx = %d, BC_isBound = %d, BC_status = %d)",tau,BC_idx,BC_isBound,BC_status );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										getGlobalMessageHandler( )->throwInfo( RET_STEPSIZE_NONPOSITIVE,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	h o t s t a r t _ p e r f o r m S t e p
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::hotstart_performStep(	const int* const FR_idx, const int* const FX_idx, const int* const AC_idx, const int* const IAC_idx,
							 | 
						||
| 
								 | 
							
																			const real_t* const delta_g, const real_t* const delta_lbA, const real_t* const delta_ubA,
							 | 
						||
| 
								 | 
							
																			const real_t* const delta_lb, const real_t* const delta_ub,
							 | 
						||
| 
								 | 
							
																			const real_t* const delta_xFX, const real_t* const delta_xFR,
							 | 
						||
| 
								 | 
							
																			const real_t* const delta_yAC, const real_t* const delta_yFX,
							 | 
						||
| 
								 | 
							
																			const real_t* const delta_Ax, int BC_idx, SubjectToStatus BC_status, BooleanType BC_isBound
							 | 
						||
| 
								 | 
							
																			)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j, ii;
							 | 
						||
| 
								 | 
							
									int nV  = getNV( );
							 | 
						||
| 
								 | 
							
									int nC  = getNC( );
							 | 
						||
| 
								 | 
							
									int nFR = getNFR( );
							 | 
						||
| 
								 | 
							
									int nFX = getNFX( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
									int nIAC = getNIAC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* I) CHECK (CONSTRAINTS') BOUNDS' CONSISTENCY */
							 | 
						||
| 
								 | 
							
									if ( areBoundsConsistent( delta_lb,delta_ub,delta_lbA,delta_ubA ) == BT_FALSE )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										infeasible = BT_TRUE;
							 | 
						||
| 
								 | 
							
										tau = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_QP_INFEASIBLE );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* II) GO TO ACTIVE SET CHANGE */
							 | 
						||
| 
								 | 
							
									if ( tau > ZERO )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* 1) Perform step in primal und dual space... */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFR; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FR_idx[i];
							 | 
						||
| 
								 | 
							
											x[ii] += tau*delta_xFR[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<nFX; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = FX_idx[i];
							 | 
						||
| 
								 | 
							
											x[ii] += tau*delta_xFX[i];
							 | 
						||
| 
								 | 
							
											y[ii] += tau*delta_yFX[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
											y[nV+ii] += tau*delta_yAC[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* ... also for Ax. */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nIAC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = IAC_idx[i];
							 | 
						||
| 
								 | 
							
											if ( constraints.getType( ii ) != ST_UNBOUNDED )
							 | 
						||
| 
								 | 
							
												Ax[ii] += tau*delta_Ax[ii];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for( i=0; i<nAC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ii = AC_idx[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											Ax[ii] = 0.0;
							 | 
						||
| 
								 | 
							
											for( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
												Ax[ii] += A[ii*NVMAX + j] * x[j];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 2) Shift QP data. */
							 | 
						||
| 
								 | 
							
										for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											g[i]  += tau*delta_g[i];
							 | 
						||
| 
								 | 
							
											lb[i] += tau*delta_lb[i];
							 | 
						||
| 
								 | 
							
											ub[i] += tau*delta_ub[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											lbA[i] += tau*delta_lbA[i];
							 | 
						||
| 
								 | 
							
											ubA[i] += tau*delta_ubA[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* print a stepsize warning if stepsize is zero */
							 | 
						||
| 
								 | 
							
										#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
										char messageString[80];
							 | 
						||
| 
								 | 
							
										sprintf( messageString,"Stepsize is %.6e",tau );
							 | 
						||
| 
								 | 
							
										getGlobalMessageHandler( )->throwWarning( RET_STEPSIZE,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
							 | 
						||
| 
								 | 
							
										#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* setup output preferences */
							 | 
						||
| 
								 | 
							
									#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
									char messageString[80];
							 | 
						||
| 
								 | 
							
									VisibilityStatus visibilityStatus;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( printlevel == PL_HIGH )
							 | 
						||
| 
								 | 
							
										visibilityStatus = VS_VISIBLE;
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										visibilityStatus = VS_HIDDEN;
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/* III) UPDATE ACTIVE SET */
							 | 
						||
| 
								 | 
							
									switch ( BC_status )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										/* Optimal solution found as no working set change detected. */
							 | 
						||
| 
								 | 
							
										case ST_UNDEFINED:
							 | 
						||
| 
								 | 
							
											return RET_OPTIMAL_SOLUTION_FOUND;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Remove one variable from active set. */
							 | 
						||
| 
								 | 
							
										case ST_INACTIVE:
							 | 
						||
| 
								 | 
							
											if ( BC_isBound == BT_TRUE )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
												sprintf( messageString,"bound no. %d.", BC_idx );
							 | 
						||
| 
								 | 
							
												getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
												#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( removeBound( BC_idx,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												y[BC_idx] = 0.0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
												sprintf( messageString,"constraint no. %d.", BC_idx );
							 | 
						||
| 
								 | 
							
												getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
												#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( removeConstraint( BC_idx,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												y[nV+BC_idx] = 0.0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Add one variable to active set. */
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											if ( BC_isBound == BT_TRUE )
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
												if ( BC_status == ST_LOWER )
							 | 
						||
| 
								 | 
							
													sprintf( messageString,"lower bound no. %d.", BC_idx );
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
													sprintf( messageString,"upper bound no. %d.", BC_idx );
							 | 
						||
| 
								 | 
							
												getGlobalMessageHandler( )->throwInfo( RET_ADD_TO_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
												#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( addBound( BC_idx,BC_status,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_ADD_TO_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												#ifdef PC_DEBUG
							 | 
						||
| 
								 | 
							
												if ( BC_status == ST_LOWER )
							 | 
						||
| 
								 | 
							
													sprintf( messageString,"lower constraint's bound no. %d.", BC_idx );
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
													sprintf( messageString,"upper constraint's bound no. %d.", BC_idx );
							 | 
						||
| 
								 | 
							
												getGlobalMessageHandler( )->throwInfo( RET_ADD_TO_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
							 | 
						||
| 
								 | 
							
												#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( addConstraint( BC_idx,BC_status,BT_TRUE ) != SUCCESSFUL_RETURN )
							 | 
						||
| 
								 | 
							
													return THROWERROR( RET_ADD_TO_ACTIVESET_FAILED );
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	a r e B o u n d s C o n s i s t e n t
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								BooleanType QProblem::areBoundsConsistent(	const real_t* const delta_lb, const real_t* const delta_ub,
							 | 
						||
| 
								 | 
							
																			const real_t* const delta_lbA, const real_t* const delta_ubA
							 | 
						||
| 
								 | 
							
																			) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Check bounds' consistency. */
							 | 
						||
| 
								 | 
							
									if ( QProblemB::areBoundsConsistent( delta_lb,delta_ub ) == BT_FALSE )
							 | 
						||
| 
								 | 
							
										return BT_FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Check constraints' consistency, i.e.
							 | 
						||
| 
								 | 
							
									 *    check if delta_lb[i] is greater than delta_ub[i]
							 | 
						||
| 
								 | 
							
									 *    for a component i whose bounds are already (numerically) equal. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<getNC( ); ++i )
							 | 
						||
| 
								 | 
							
										if ( ( lbA[i] > ubA[i] - BOUNDTOL ) && ( delta_lbA[i] > delta_ubA[i] + EPS ) )
							 | 
						||
| 
								 | 
							
											return BT_FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return BT_TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	s e t u p Q P d a t a
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::setupQPdata(	const real_t* const _H, const real_t* const _R, const real_t* const _g, const real_t* const _A,
							 | 
						||
| 
								 | 
							
																	const real_t* const _lb, const real_t* const _ub,
							 | 
						||
| 
								 | 
							
																	const real_t* const _lbA, const real_t* const _ubA
							 | 
						||
| 
								 | 
							
																	)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i, j;
							 | 
						||
| 
								 | 
							
									int nV = getNV( );
							 | 
						||
| 
								 | 
							
									int nC = getNC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Load Hessian matrix as well as lower and upper bounds vectors. */
							 | 
						||
| 
								 | 
							
									if (QProblemB::setupQPdata(_H, _R, _g, _lb, _ub) != SUCCESSFUL_RETURN)
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Load constraint matrix. */
							 | 
						||
| 
								 | 
							
									if ( ( nC > 0 ) && ( _A == 0 ) )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( nC > 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
											for( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
												A[i*NVMAX + j] = _A[i*nV + j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 3) Setup lower constraints' bounds vector. */
							 | 
						||
| 
								 | 
							
										if ( _lbA != 0 )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
												lbA[i] = _lbA[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* if no lower constraints' bounds are specified, set them to -infinity */
							 | 
						||
| 
								 | 
							
											for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
												lbA[i] = -INFTY;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* 4) Setup upper constraints' bounds vector. */
							 | 
						||
| 
								 | 
							
										if ( _ubA != 0 )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
												ubA[i] = _ubA[i];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											/* if no upper constraints' bounds are specified, set them to infinity */
							 | 
						||
| 
								 | 
							
											for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
												ubA[i] = INFTY;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 	printmatrix2( "A",A,10,20 );
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								// 	printmatrix2( "lbA",lbA,1,nC );
							 | 
						||
| 
								 | 
							
								// 	printmatrix2( "ubA",ubA,1,nC );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PC_DEBUG  /* Define print functions only for debugging! */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	p r i n t I t e r a t i o n
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::printIteration( 	int iteration,
							 | 
						||
| 
								 | 
							
																		int BC_idx,	SubjectToStatus BC_status, BooleanType BC_isBound
							 | 
						||
| 
								 | 
							
										  								)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									char myPrintfString[160];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* consistency check */
							 | 
						||
| 
								 | 
							
									if ( iteration < 0 )
							 | 
						||
| 
								 | 
							
										return THROWERROR( RET_INVALID_ARGUMENTS );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* nothing to do */
							 | 
						||
| 
								 | 
							
									if ( printlevel != PL_MEDIUM )
							 | 
						||
| 
								 | 
							
										return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) Print header at first iteration. */
							 | 
						||
| 
								 | 
							
								 	if ( iteration == 0 )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										sprintf( myPrintfString,"\n##############  qpOASES  --  QP NO.%4.1d  ###############\n", count );
							 | 
						||
| 
								 | 
							
										myPrintf( myPrintfString );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										sprintf( myPrintfString,"  Iter  |  StepLength   |     Info      |  nFX  |  nAC  \n" );
							 | 
						||
| 
								 | 
							
										myPrintf( myPrintfString );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Print iteration line. */
							 | 
						||
| 
								 | 
							
									if ( BC_status == ST_UNDEFINED )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										sprintf( myPrintfString,"  %4.1d  |  %1.5e  |   QP SOLVED   | %4.1d  | %4.1d  \n", iteration,tau,getNFX( ),getNAC( ) );
							 | 
						||
| 
								 | 
							
										myPrintf( myPrintfString );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										char info[8];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( BC_status == ST_INACTIVE )
							 | 
						||
| 
								 | 
							
											sprintf( info,"REM " );
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											sprintf( info,"ADD " );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( BC_isBound == BT_TRUE )
							 | 
						||
| 
								 | 
							
											sprintf( &(info[4]),"BND" );
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											sprintf( &(info[4]),"CON" );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										sprintf( myPrintfString,"  %4.1d  |  %1.5e  |  %s%4.1d  | %4.1d  | %4.1d  \n", iteration,tau,info,BC_idx,getNFX( ),getNAC( ) );
							 | 
						||
| 
								 | 
							
										myPrintf( myPrintfString );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	p r i n t I t e r a t i o n
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::printIteration( 	int iteration,
							 | 
						||
| 
								 | 
							
																		int BC_idx,	SubjectToStatus BC_status
							 | 
						||
| 
								 | 
							
										  								)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return printIteration( iteration,BC_idx,BC_status,BT_TRUE );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif  /* PC_DEBUG */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	c h e c k K K T c o n d i t i o n s
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								returnValue QProblem::checkKKTconditions( )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									#ifdef __PERFORM_KKT_TEST__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int i, j, jj;
							 | 
						||
| 
								 | 
							
									int nV  = getNV( );
							 | 
						||
| 
								 | 
							
									int nC  = getNC( );
							 | 
						||
| 
								 | 
							
									int nAC = getNAC( );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									real_t tmp;
							 | 
						||
| 
								 | 
							
									real_t maxKKTviolation = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int AC_idx[NCMAX_ALLOC];
							 | 
						||
| 
								 | 
							
									constraints.getActive( )->getNumberArray( AC_idx );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 1) check for Hx + g - [yFX yAC]*[Id A]' = 0. */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										tmp = g[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for( j=0; j<nV; ++j )
							 | 
						||
| 
								 | 
							
											tmp += H[i*NVMAX + j] * x[j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										tmp -= y[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Only sum over active constraints as y is zero for all inactive ones. */
							 | 
						||
| 
								 | 
							
										for( j=0; j<nAC; ++j )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											jj = AC_idx[j];
							 | 
						||
| 
								 | 
							
											tmp -= A[jj*NVMAX + i] * y[nV+jj];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( getAbs( tmp ) > maxKKTviolation )
							 | 
						||
| 
								 | 
							
											maxKKTviolation = getAbs( tmp );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 2) Check for [lb lbA] <= [Id A]*x <= [ub ubA]. */
							 | 
						||
| 
								 | 
							
									/* lbA <= Ax <= ubA */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( lbA[i] - Ax[i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
											maxKKTviolation = lbA[i] - Ax[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( Ax[i] - ubA[i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
											maxKKTviolation = Ax[i] - ubA[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* lb <= x <= ub */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ( lb[i] - x[i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
											maxKKTviolation = lb[i] - x[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( x[i] - ub[i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
											maxKKTviolation = x[i] - ub[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* 3) Check for correct sign of y and for complementary slackness. */
							 | 
						||
| 
								 | 
							
									/* bounds */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nV; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										switch ( bounds.getStatus( i ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											case ST_LOWER:
							 | 
						||
| 
								 | 
							
												if ( -y[i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = -y[i];
							 | 
						||
| 
								 | 
							
												if ( getAbs( x[i] - lb[i] ) > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = getAbs( x[i] - lb[i] );
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case ST_UPPER:
							 | 
						||
| 
								 | 
							
												if ( y[i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = y[i];
							 | 
						||
| 
								 | 
							
												if ( getAbs( ub[i] - x[i] ) > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = getAbs( ub[i] - x[i] );
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											default: /* inactive */
							 | 
						||
| 
								 | 
							
											if ( getAbs( y[i] ) > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = getAbs( y[i] );
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* constraints */
							 | 
						||
| 
								 | 
							
									for( i=0; i<nC; ++i )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										switch ( constraints.getStatus( i ) )
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											case ST_LOWER:
							 | 
						||
| 
								 | 
							
												if ( -y[nV+i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = -y[nV+i];
							 | 
						||
| 
								 | 
							
												if ( getAbs( Ax[i] - lbA[i] ) > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = getAbs( Ax[i] - lbA[i] );
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case ST_UPPER:
							 | 
						||
| 
								 | 
							
												if ( y[nV+i] > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = y[nV+i];
							 | 
						||
| 
								 | 
							
												if ( getAbs( ubA[i] - Ax[i] ) > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = getAbs( ubA[i] - Ax[i] );
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											default: /* inactive */
							 | 
						||
| 
								 | 
							
											if ( getAbs( y[nV+i] ) > maxKKTviolation )
							 | 
						||
| 
								 | 
							
													maxKKTviolation = getAbs( y[nV+i] );
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( maxKKTviolation > CRITICALACCURACY )
							 | 
						||
| 
								 | 
							
										return RET_NO_SOLUTION;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( maxKKTviolation > DESIREDACCURACY )
							 | 
						||
| 
								 | 
							
										return RET_INACCURATE_SOLUTION;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#endif /* __PERFORM_KKT_TEST__ */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return SUCCESSFUL_RETURN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 *	end of file
							 | 
						||
| 
								 | 
							
								 */
							 |