/** Example for qpOASES main function using the QProblem class. */
int main( )
{
	USING_NAMESPACE_QPOASES

	/* Setup data of first QP. */
	real_t H[4*4] = { 1.0, 0.0, 0.0, 0.5, 
	                  0.0, 1.0, 0.0, 0.0,
	                  0.0, 0.0, 1.0, 0.0,
	                  0.5, 0.0, 0.0, 1.0 };
	real_t A[3*4] = { 1.0, 1.0, 0.0, 0.0,
	                  1.0, 1.0, 1.0, 0.0,
	                  1.0, 1.0, 1.0, 1.0 };
	real_t g[4] = { 1.5, 1.0, -1.0, -1.0 };
	real_t lb[4] = { 0.5, -2.0, 0.0, 0.0 };
	real_t ub[4] = { 1.0, 2.0, 1.0, 0.5 };
	real_t lbA[3] = { -1.0, -1.0, -1.0 };
	real_t ubA[3] = { 0.0, 0.25, 1.0 };

	

	/* Setting up QProblem object. */
	QProblem example( 4,3 );

	Options options;
	example.setOptions( options );

	/* Solve first QP. */
	int nWSR = 10;
	example.init( H,g,A,lb,ub,lbA,ubA, nWSR );

	/* Get and print solution of second QP. */
	real_t xOpt[4];
	real_t yOpt[4+3];
	example.getPrimalSolution( xOpt );
	example.getDualSolution( yOpt );
	print( xOpt,4,"xOpt" );
	print( yOpt,4+3,"yOpt" );
	printf( "objVal = %e\n\n", example.getObjVal() );
	
	/* Compute KKT tolerances */
	real_t stat, feas, cmpl;

	getKKTResidual(	4,3,
					H,g,A,lb,ub,lbA,ubA,
					xOpt,yOpt,
					stat,feas,cmpl
					);
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl );

	QPOASES_TEST_FOR_TRUE( stat <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( feas <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( cmpl <= 1e-15 );


	/* Solve first QP again (with optimal guess for working set). */
	Bounds prevBounds;
	Constraints prevConstraints;
	
	example.getBounds( prevBounds );
	example.getConstraints( prevConstraints );

	nWSR = 10;
	example.hotstart( g,lb,ub,lbA,ubA, nWSR,0,&prevBounds,&prevConstraints );

	/* Get and print solution of second QP. */
	example.getPrimalSolution( xOpt );
	example.getDualSolution( yOpt );
	print( xOpt,4,"xOpt" );
	print( yOpt,4+3,"yOpt" );
	printf( "objVal = %e\n\n", example.getObjVal() );
	
	/* Compute KKT tolerances */
	getKKTResidual(	4,3,
					H,g,A,lb,ub,lbA,ubA,
					xOpt,yOpt,
					stat,feas,cmpl
					);
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl );

	QPOASES_TEST_FOR_TRUE( stat <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( feas <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( cmpl <= 1e-15 );


	/* Solve first QP again (with inaccurate guess for working set). */
	prevBounds.print();
	prevBounds.rotate(1);
	//prevBounds.moveFixedToFree(0);
	prevBounds.print();

	prevConstraints.print();
	//prevConstraints.moveInactiveToActive(0,ST_LOWER);
	prevConstraints.moveActiveToInactive(1);
	prevConstraints.print();

	nWSR = 10;
	example.hotstart( g,lb,ub,lbA,ubA, nWSR,0,&prevBounds,&prevConstraints );

	/* Get and print solution of second QP. */
	example.getPrimalSolution( xOpt );
	example.getDualSolution( yOpt );
	print( xOpt,4,"xOpt" );
	print( yOpt,4+3,"yOpt" );
	printf( "objVal = %e\n\n", example.getObjVal() );
	
	/* Compute KKT tolerances */
	getKKTResidual(	4,3,
					H,g,A,lb,ub,lbA,ubA,
					xOpt,yOpt,
					stat,feas,cmpl
					);
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl );

	QPOASES_TEST_FOR_TRUE( stat <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( feas <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( cmpl <= 1e-15 );

	return TEST_PASSED;
}
/** Run benchmark examples. */
int main( int argc, char *argv[] )
{
	USING_NAMESPACE_QPOASES
	#ifdef __USE_SINGLE_PRECISION__
	const real_t TOL = 5e-2;
	#else
	const real_t TOL = 1e-5;
	#endif

	/* 1) Define benchmark arguments. */
	BooleanType isSparse = BT_FALSE;
	//BooleanType isSparse = BT_TRUE;
	Options options;
 	options.setToDefault();
	//options.setToMPC();
	//options.setToReliable();
	options.printLevel = PL_LOW;
	//options.printLevel = PL_MEDIUM;
	//options.printLevel = PL_TABULAR;
	//options.enableFarBounds = BT_FALSE;

// 	options.initialStatusBounds = ST_LOWER;
	//options.numRegularisationSteps = 1;
	//options.epsRegularisation = 1.0e3 * EPS;
 	
	//options.enableFlippingBounds = BT_FALSE;
	//options.enableFlippingBounds = BT_FALSE;
	//options.enableRamping = BT_TRUE;
	//options.enableFarBounds = BT_FALSE;
	//options.enableNZCTests = BT_FALSE;
	//options.epsNZCTests = 1.0e4 * EPS;
	//options.epsFlipping = 1.0e5 * EPS;
	//options.enableFullLITests = BT_TRUE;
 	//options.enableDriftCorrection = 1;
 	//options.enableEqualities = BT_TRUE;
	//options.enableEqualities = BT_FALSE;
 	//options.epsNum = -1.0e3 * EPS;
 	//options.epsDen =  1.0e3 * EPS;


	int_t nWSR;
	real_t maxCPUtime; /* seconds */
	real_t maxStationarity = 0.0, maxFeasibility = 0.0, maxComplementarity = 0.0;
	real_t avgStationarity = 0.0, avgFeasibility = 0.0, avgComplementarity = 0.0;

	int_t scannedDir = 0;
	int_t nfail = 0, npass = 0;
	int_t nproblems, i;
	struct dirent **namelist;
	char resstr[MAX_STRING_LENGTH], oqpProblem[MAX_STRING_LENGTH];
	char *problem;
	returnValue returnvalue;

	int_t expectedNumSolvedProblems = 44;
	real_t expectedAvgStationarity    = TOL;
	real_t expectedAvgFeasibility     = TOL;
	real_t expectedAvgComplementarity = TOL;

	
	if ( argv[argc-1][0] == 'O' )
	{
		if ( strlen(argv[argc-1]) != 3 )
		{
			fprintf( stdout,"ERROR (testbench): Invalid options passed!\n" );
			return TEST_DATA_NOT_FOUND;
		}
		
		fprintf( stdout,"Analysing passed options:  " );
		switch ( argv[argc-1][1] )
		{
			case 'd':
				fprintf( stdout,"default options, " );
				options.setToDefault();
				if ( argv[argc-1][2] == 's' )
				{
					expectedNumSolvedProblems  = 44;
					expectedAvgStationarity    = 1e-9;
					expectedAvgFeasibility     = 1e-9;
					expectedAvgComplementarity = 5e-7;
				}
				else
				{
					expectedNumSolvedProblems  = 44;
					expectedAvgStationarity    = 5e-10;
					expectedAvgFeasibility     = 5e-10;
					expectedAvgComplementarity = 5e-8;
				}
				break;
				
			case 'r':
				fprintf( stdout,"reliable options, " );
				options.setToReliable();
				if ( argv[argc-1][2] == 's' )
				{
					expectedNumSolvedProblems  = 44;
					expectedAvgStationarity    = 2e-9;
					expectedAvgFeasibility     = 2e-11;
					expectedAvgComplementarity = 3e-9;
				}
				else
				{
					expectedNumSolvedProblems  = 44;
					expectedAvgStationarity    = 2e-9;
					expectedAvgFeasibility     = 2e-9;
					expectedAvgComplementarity = 3e-7;
				}
				break;
				
			case 'm':
				fprintf( stdout,"MPC options, " );
				options.setToMPC();
				if ( argv[argc-1][2] == 's' )
				{
					expectedNumSolvedProblems  = 42;
					expectedAvgStationarity    = 2e-8;
					expectedAvgFeasibility     = 1e-8;
					expectedAvgComplementarity = 2e-7;
				}
				else
				{
					expectedNumSolvedProblems  = 42;
					expectedAvgStationarity    = 3e-8;
					expectedAvgFeasibility     = 1e-8;
					expectedAvgComplementarity = 5e-8;
				}
				break;
				
			default:
				fprintf( stdout,"ERROR (testbench): Invalid options passed!\n" );
				return TEST_DATA_NOT_FOUND;
		}
		
		switch ( argv[argc-1][2] )
		{
			case 's':
				fprintf( stdout,"sparse QP data\n" );
				isSparse = BT_TRUE;
				break;
				
			case 'd':
				fprintf( stdout,"dense QP data\n" );
				isSparse = BT_FALSE;
				break;
				
			default:
				fprintf( stdout,"ERROR (testbench): Invalid options passed!\n" );
				return TEST_DATA_NOT_FOUND;
		}
		options.printLevel = PL_NONE;
		//options.enableFlippingBounds = BT_FALSE;
		
		nproblems = argc-2;
	}
	else
	{
		nproblems = argc-1;
	}

	
	if (nproblems == 0)
	{
		/* 2a) Scan problem directory */
		nproblems = scandir("../testing/cpp/data/problems", &namelist, NULL, alphasort);
		if (nproblems <= 0)
		{
			myPrintf( "No test problems found!\n" );
			return TEST_DATA_NOT_FOUND;
		}
		scannedDir = 1;
	}
	else
	{
		/* 2b) Use problem list given by arguments */
		scannedDir = 0;
	}

	/* 3) Run benchmark. */
	printf("%10s %9s %9s %9s %6s  %-12s\n", "problem", "stat",
			"feas", "compl", "nWSR", "result");
	for (i = 0; i < nproblems; i++)
	{
		if (scannedDir)
		{
			/* skip special directories and zip file cuter.*bz2 */
			if (namelist[i]->d_name[0] == '.' || namelist[i]->d_name[0] == 'c')
			{
				free(namelist[i]);
				continue;
			}
			problem = namelist[i]->d_name;
		}
		else
		{
			problem = argv[i+1];
		}

		fprintf(stdFile, "%-10s ", problem);
		fflush(stdFile);

		snprintf(oqpProblem, MAX_STRING_LENGTH, "../testing/cpp/data/problems/%s/", problem);
		maxCPUtime = 300.0;
		nWSR = 2500;

		returnvalue = runOqpBenchmark(	oqpProblem, isSparse, options,
										nWSR, maxCPUtime, maxStationarity, maxFeasibility, maxComplementarity 
										);
		if (returnvalue	== SUCCESSFUL_RETURN
				&& maxStationarity < TOL
				&& maxFeasibility < TOL
				&& maxComplementarity < TOL)
		{
			npass++;
			
			avgStationarity    += maxStationarity;
			avgFeasibility     += maxFeasibility;
			avgComplementarity += maxComplementarity;

			strncpy(resstr, "pass", MAX_STRING_LENGTH);
		}
		else
		{
			if ( returnvalue == RET_BENCHMARK_ABORTED )
				return TEST_DATA_NOT_FOUND;

			nfail++;
			snprintf (resstr, MAX_STRING_LENGTH, "fail (%d)",(int)returnvalue);
		}
		fprintf(stdFile, "%9.2e %9.2e %9.2e %6d  %-12s\n", maxStationarity,
				maxFeasibility, maxComplementarity, (int)nWSR, resstr);

		if (scannedDir) free(namelist[i]);
	}
	if (scannedDir) free(namelist);

	avgStationarity    /= (real_t)npass;
	avgFeasibility     /= (real_t)npass;
	avgComplementarity /= (real_t)npass;


	/* 4) Print results. */
	printf( "\n\n" );
	printf( "Testbench results:\n" );
	printf( "======================\n\n" );
	printf( "Pass:  %3d\n",(int)npass );
	printf( "Fail:  %3d\n",(int)nfail );
	printf( "Ratio: %5.1f%%\n", 100.0 * (real_t)npass / (real_t)(npass+nfail) );
	printf( "\n" );

	QPOASES_TEST_FOR_TRUE( npass >= expectedNumSolvedProblems );


	printf( "avg. stat:  %e\n", avgStationarity    );
	printf( "avg. feas:  %e\n", avgFeasibility     );
	printf( "avg. cmpl:  %e\n", avgComplementarity );

	QPOASES_TEST_FOR_TOL( avgStationarity,    expectedAvgStationarity    );
	QPOASES_TEST_FOR_TOL( avgFeasibility,     expectedAvgFeasibility     );
	QPOASES_TEST_FOR_TOL( avgComplementarity, expectedAvgComplementarity );


	return 0;
}
/** Example for qpOASES main function using the QProblem class. */
int main( )
{
	USING_NAMESPACE_QPOASES

	/* Setup data of first QP. */
	real_t H[5*5] = {	1.224642131370767e+01, 2.908638763113702e+00, 0.0, 0.0, 0.0,
						2.908638763113702e+00, 2.497106275003180e+00, 0.0, 0.0, 0.0,
						0.0, 0.0, 1.0, 0.0, 0.0,
						0.0, 0.0, 0.0, 5.158460640334052e-02, 4.723556059962540e-02,
						0.0, 0.0, 0.0, 4.723556059962540e-02, 4.325317843302175e-02 };
	real_t A[2*5] = { 	-1.404358970692652e+00, -2.556613491156063e+00, 3.202524559238066e+00, -1.0, 0.0,
						6.587910295430314e-01, -5.349454475937998e-01, 4.391976356955536e-01, 0.0, -1.0 };
	real_t g[5] = { 	2.474135331302147e+01,
						5.857286430296258e+00,
						2.359382646348721e-01,
						1.721047069188781e-01,
						1.575947337774199e-01 };
	real_t lb[5] = { -10.0, -10.0, -10.0, -10.0, -10.0 };
	real_t ub[5] = {  10.0,  10.0,  10.0,  10.0,  10.0 };
	real_t lbA[2] = { 1.643135416077167e+00, 1.056813028189597e+00 };
	real_t ubA[2] = { 1.643135416077167e+00, 1.056813028189597e+00 };

	/* Setting up QProblem object. */
	QProblem example( 5,2 );

	Options options;
 	//options.enableFlippingBounds = BT_FALSE;
	//options.enableEqualities = BT_TRUE;
	//options.initialStatusBounds = ST_INACTIVE;
	example.setOptions( options );
	example.setPrintLevel( PL_NONE );
	
	/* Solve first QP. */
	returnValue retVal;
	int_t simpleStatus = -1;

	int_t nWSR = 10;
	retVal = example.init( H,g,A,lb,ub,lbA,ubA, nWSR,0 );
	simpleStatus = getSimpleStatus( retVal,BT_TRUE );

	QPOASES_TEST_FOR_TRUE( simpleStatus == 0 );


	/* Get and print solution of second QP. */
	real_t xOpt[5];
	real_t yOpt[5+2];
	
	example.getPrimalSolution( xOpt );
	example.getDualSolution( yOpt );
	printf( "\nxOpt = [ %e, %e, ... ];  objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() );
	
	/* Compute KKT tolerances */
	real_t stat, feas, cmpl;
	SolutionAnalysis analyzer;

	analyzer.getKktViolation( &example, &stat,&feas,&cmpl );
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl );

	QPOASES_TEST_FOR_TOL( stat,1e-14 );
	QPOASES_TEST_FOR_TOL( feas,1e-14 );
	QPOASES_TEST_FOR_TOL( cmpl,1e-15 );

	return TEST_PASSED;
}
/** Example for qpOASES main function using the OQP interface. */
int main( )
{
	USING_NAMESPACE_QPOASES

	/* 1) Define benchmark arguments. */
	BooleanType isSparse = BT_FALSE;
	BooleanType useHotstarts;

	Options options;
	options.setToMPC();
	options.printLevel = PL_LOW;

	int_t maxAllowedNWSR;
	real_t maxNWSR, avgNWSR, maxCPUtime, avgCPUtime;
	real_t maxStationarity, maxFeasibility, maxComplementarity;

	const int_t numBenchmarks = 4; //5
	const char *benchmarkPath[numBenchmarks];
	benchmarkPath[0] = "../testing/cpp/data/oqp/chain80/";
	benchmarkPath[1] = "../testing/cpp/data/oqp/chain80w/";
	benchmarkPath[2] = "../testing/cpp/data/oqp/diesel/";
	benchmarkPath[3] = "../testing/cpp/data/oqp/crane/";
	//benchmarkPath[4] = "../testing/cpp/data/oqp/CDU/";


	/* 2) Run all benchmarks in a loop */
	for ( int_t ii=0; ii<2*numBenchmarks; ++ii )
	{
		if ( ii%2 == 0 )
			useHotstarts = BT_FALSE;
		else
			useHotstarts = BT_TRUE;
		
		maxAllowedNWSR = 1000;
		maxNWSR = 0.0;
		avgNWSR = 0.0;
		maxCPUtime = 1000.0; /* seconds */
		avgCPUtime =    0.0; /* seconds */
		maxStationarity    = 0.0;
		maxFeasibility     = 0.0;
		maxComplementarity = 0.0;

		if ( runOqpBenchmark(	benchmarkPath[ii/2],
								isSparse,useHotstarts,
								options,maxAllowedNWSR,
								maxNWSR,avgNWSR,maxCPUtime,avgCPUtime,
								maxStationarity,maxFeasibility,maxComplementarity
								) != SUCCESSFUL_RETURN )
		{
			myPrintf( "Something went wrong when running benchmark!\n" );
			return TEST_DATA_NOT_FOUND;
		}

		/* 3) Print results. */
		printf( "\n\n" );
		if ( useHotstarts == BT_FALSE )
			printf( "OQP Benchmark Results for %s (cold-starts):\n", benchmarkPath[ii/2] );
		else
			printf( "OQP Benchmark Results for %s (hot-starts):\n", benchmarkPath[ii/2] );

		printf( "===========================================================================\n\n" );
		printf( "maximum CPU time:             %.2f milliseconds\n",1000.0*maxCPUtime );
		printf( "average CPU time:             %.2f milliseconds\n",1000.0*avgCPUtime );
		printf( "\n" );
		printf( "maximum iterations:    %.1f\n",maxNWSR );
		printf( "average iterations:    %.1f\n",avgNWSR );
		printf( "\n" );
		printf( "maximum violation stationarity:     %.3e\n",maxStationarity );
		printf( "maximum violation feasibility:      %.3e\n",maxFeasibility );
		printf( "maximum violation complementarity:  %.3e\n",maxComplementarity );
		printf( "\n" );

		QPOASES_TEST_FOR_TOL( maxStationarity,    1e-9  );
		QPOASES_TEST_FOR_TOL( maxFeasibility,     2e-11 );
		QPOASES_TEST_FOR_TOL( maxComplementarity, 2e-10 );
		
		switch( ii )
		{
			case 0:
				/* chain80 (cold) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 62.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <=  7.5 );
				break;

			case 1:
				/* chain80 (hot) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 19.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <=  2.4 );
				break;

			case 2:
				/* chain80w (cold) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 84.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <= 10.1 );
				break;

			case 3:
				/* chain80w (hot) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 16.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <=  2.7 );
				break;

			case 4:
				/* diesel (cold) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 26.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <=  0.5 );
				break;

			case 5:
				/* diesel (hot) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 22.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <=  0.3 );
				break;

			case 6:
				/* crane (cold) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 64.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <= 44.0 );
				break;

			case 7:
				/* crane (hot) */
				QPOASES_TEST_FOR_TRUE( maxNWSR <= 42.5 );
				QPOASES_TEST_FOR_TRUE( avgNWSR <=  0.4 );
				break;
		}
	}
	
	return TEST_PASSED;
}
예제 #5
0
int main( )
{
	USING_NAMESPACE_QPOASES

	long i;
	int nWSR;
	real_t tic, toc;
	real_t errP=0.0, errD=0.0;
	real_t *x1 = new real_t[180];
	real_t *y1 = new real_t[271];
	real_t *x2 = new real_t[180];
	real_t *y2 = new real_t[271];

	/* create sparse matrices */
	SymSparseMat *H = new SymSparseMat(180, 180, H_ir, H_jc, H_val);
	SparseMatrix *A = new SparseMatrix(91, 180, A_ir, A_jc, A_val);

	H->createDiagInfo();

	real_t* H_full = H->full();
	real_t* A_full = A->full();

	SymDenseMat *Hd = new SymDenseMat(180,180,180,H_full);
	DenseMatrix *Ad = new DenseMatrix(91,180,180,A_full);

	/* solve with dense matrices */
	nWSR = 1000;
	QProblem qrecipeD(180, 91);
	tic = getCPUtime();
	qrecipeD.init(Hd, g, Ad, lb, ub, lbA, ubA, nWSR, 0);
	toc = getCPUtime();
	qrecipeD.getPrimalSolution(x1);
	qrecipeD.getDualSolution(y1);

	fprintf(stdFile, "Solved dense problem in %d iterations, %.3f seconds.\n", nWSR, toc-tic);

	/* Compute KKT tolerances */
	real_t stat, feas, cmpl;

	getKKTResidual(	180,91,
					H_full,g,A_full,lb,ub,lbA,ubA,
					x1,y1,
					stat,feas,cmpl
					);
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n\n", stat,feas,cmpl );


	/* solve with sparse matrices */
	nWSR = 1000;
	QProblem qrecipeS(180, 91);
	tic = getCPUtime();
	qrecipeS.init(H, g, A, lb, ub, lbA, ubA, nWSR, 0);
	toc = getCPUtime();
	qrecipeS.getPrimalSolution(x2);
	qrecipeS.getDualSolution(y2);

	fprintf(stdFile, "Solved sparse problem in %d iterations, %.3f seconds.\n", nWSR, toc-tic);
	
	/* Compute KKT tolerances */
	real_t stat2, feas2, cmpl2;
	getKKTResidual(	180,91,
					H_full,g,A_full,lb,ub,lbA,ubA,
					x2,y2,
					stat2,feas2,cmpl2
					);
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n\n", stat2,feas2,cmpl2 );

	/* check distance of solutions */
	for (i = 0; i < 180; i++)
		if (getAbs(x1[i] - x2[i]) > errP)
			errP = getAbs(x1[i] - x2[i]);
	fprintf(stdFile, "Primal error: %9.2e\n", errP);

	for (i = 0; i < 271; i++)
		if (getAbs(y1[i] - y2[i]) > errD)
			errD = getAbs(y1[i] - y2[i]);
	fprintf(stdFile, "Dual error: %9.2e (might not be unique)\n", errD);

	delete H;
	delete A;
	delete[] H_full;
	delete[] A_full;
	delete Hd;
	delete Ad;

	delete[] y2;
	delete[] x2;
	delete[] y1;
	delete[] x1;

	QPOASES_TEST_FOR_TRUE( stat <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( feas <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( cmpl <= 1e-15 );
	
	QPOASES_TEST_FOR_TRUE( stat2 <= 1e-14 );
	QPOASES_TEST_FOR_TRUE( feas2 <= 1e-14 );
	QPOASES_TEST_FOR_TRUE( cmpl2 <= 1e-13 );

	QPOASES_TEST_FOR_TRUE( errP <= 1e-13 );

	return TEST_PASSED;
}
/** Example for qpOASES main function using the QProblemB class. */
int main( )
{
	USING_NAMESPACE_QPOASES

	/* Setup data of first QP. */
	real_t H[2*2] = { 1.0, 0.0, 0.0, 0.5 };
	real_t g[2] = { 1.5, 1.0 };
	real_t lb[2] = { 0.5, -2.0 };
	real_t ub[2] = { 5.0, 2.0 };

	/* Setup data of second QP. */
	real_t g_new[2] = { 1.0, 1.5 };
	real_t lb_new[2] = { 0.0, -1.0 };
	real_t ub_new[2] = { 5.0, -0.5 };


	/* Setting up QProblemB object. */
	QProblemB example( 2 );

	Options options;
	//options.enableFlippingBounds = BT_FALSE;
	options.initialStatusBounds = ST_INACTIVE;
	options.numRefinementSteps = 1;
	options.enableCholeskyRefactorisation = 1;
	example.setOptions( options );

	/* Solve first QP. */
	int nWSR = 10;
	example.init( H,g,lb,ub, nWSR,0 );
// 	printf( "\nnWSR = %d\n\n", nWSR );

	real_t xOpt[2];
	real_t yOpt[2];
	example.getPrimalSolution( xOpt );
	example.getDualSolution( yOpt );

	/* Compute KKT tolerances */
	real_t stat, feas, cmpl;

	getKKTResidual(	2,
					H,g,lb,ub,
					xOpt,yOpt,
					stat,feas,cmpl
					);
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl );

	QPOASES_TEST_FOR_TRUE( stat <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( feas <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( cmpl <= 1e-15 );

	
	/* Solve second QP. */
	nWSR = 10;
	example.hotstart( g_new,lb_new,ub_new, nWSR,0 );
// 	printf( "\nnWSR = %d\n\n", nWSR );

	/* Get and print solution of second QP. */
	example.getPrimalSolution( xOpt );
	example.getDualSolution( yOpt );
	printf( "\nxOpt = [ %e, %e ];  objVal = %e\n\n", xOpt[0],xOpt[1],example.getObjVal() );

	/* Compute KKT tolerances */
	getKKTResidual(	2,
					H,g_new,lb_new,ub_new,
					xOpt,yOpt,
					stat,feas,cmpl
					);
	printf( "stat = %e\nfeas = %e\ncmpl = %e\n", stat,feas,cmpl );

	QPOASES_TEST_FOR_TRUE( stat <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( feas <= 1e-15 );
	QPOASES_TEST_FOR_TRUE( cmpl <= 1e-15 );

	return TEST_PASSED;
}