Example #1
0
String operator==(	const ExportIndex& _arg1,
					const ExportIndex& _arg2
					)
{
	String ret;
	ret << _arg1.get() << " = " << _arg2.get() << ";\n";

	return ret;
}
ExportArgument ExportArgumentInternal::getAddress(	const ExportIndex& rowIdx,
													const ExportIndex& colIdx
													) const
{
	if ( rowIdx.isGiven( ) )
	{
		ASSERT( rowIdx.getGivenValue() < (int)getNumRows() );
	}
	if( colIdx.isGiven() )
	{
		ASSERT( colIdx.getGivenValue() < (int)getNumCols() );
	}

	ExportIndex ind = getTotalIdx(rowIdx, colIdx);

	ExportArgument tmp(name, data, type, dataStruct, BT_FALSE, ind, prefix);

	return tmp;
}
returnValue MemoryAllocator::add(const ExportIndex& _obj)
{
	if (indices.add( _obj ) == false)
	{
		LOG( LVL_WARNING ) << "Object '" << _obj.getFullName().getName() << "' already exists in an object pool" << endl;
		return ACADOERROR( RET_INVALID_ARGUMENTS );
	}

	return SUCCESSFUL_RETURN;
}
returnValue MemoryAllocator::release(const ExportIndex& _obj)
{
	if (indices.release( _obj ) == false)
	{
		LOG( LVL_ERROR ) << "Object '" << _obj.getFullName().getName() << "' is not found in an object pool" << endl;
		return ACADOERROR( RET_INVALID_ARGUMENTS );
	}

	return SUCCESSFUL_RETURN;
}
Example #5
0
ExportIndex operator%(	const ExportIndex& _arg1,
						const ExportIndex& _arg2
						)
{
	ExportIndex tmp;

	if (_arg1.isGiven() == BT_TRUE && _arg2.isGiven() == BT_TRUE)
	{
		tmp.assignNode(new ExportIndexNode(_arg1.getGivenValue() % _arg2.getGivenValue()));

		return tmp;
	}

	tmp.assignNode(new ExportIndexNode(ESO_MODULO, _arg1, _arg2));

	return tmp;
}
returnValue ExportNLPSolver::setupSimulation( void )
{
	// \todo Implement free parameters and support for DAEs

	//
	// By default, here will be defined model simulation suitable for sparse QP solver.
	// Condensing based QP solvers should redefine/extend model simulation
	//

	// \todo Move to something like: setupInitialization
	ExportVariable retInit("ret", 1, 1, INT, ACADO_LOCAL);
	retInit.setDoc("=0: OK, otherwise an error code of a QP solver.");
	initialize.setup( "initializeSolver" );
	initialize.doc( "Solver initialization. Must be called once before any other function call." );
	initialize.setReturnValue(retInit);
	initialize << retInit.getFullName() << String(" = 0;\n");

	initialize.addComment( "This is a function which must be called once before any other function call!" );
	initialize.addLinebreak( 2 );

	modelSimulation.setup( "modelSimulation" );
	ExportIndex run;
	modelSimulation.acquire( run );
	ExportForLoop loop(run, 0, getN());

	int useOMP;
	get(CG_USE_OPENMP, useOMP);

	x.setup("x", (getN() + 1), getNX(), REAL, ACADO_VARIABLES);
	x.setDoc( (String)"Matrix containing " << (getN() + 1) << " differential variable vectors." );
	z.setup("z", getN(), getNXA(), REAL, ACADO_VARIABLES);
	z.setDoc( (String)"Matrix containing " << N << " algebraic variable vectors." );
	u.setup("u", getN(), getNU(), REAL, ACADO_VARIABLES);
	u.setDoc( (String)"Matrix containing " << N << " control variable vectors." );
	p.setup("p", 1, getNP(), REAL, ACADO_VARIABLES);
	p.setDoc( (String)"Vector of parameters." );

	if (performsSingleShooting() == BT_FALSE)
	{
		d.setup("d", getN() * getNX(), 1, REAL, ACADO_WORKSPACE);
	}

	evGx.setup("evGx", N * NX, NX, REAL, ACADO_WORKSPACE);
	evGu.setup("evGu", N * NX, NU, REAL, ACADO_WORKSPACE);

	ExportStruct dataStructWspace;
	dataStructWspace = (useOMP && performsSingleShooting() == BT_FALSE) ? ACADO_LOCAL : ACADO_WORKSPACE;
	state.setup("state", 1, (getNX() + getNXA()) * (getNX() + getNU() + 1) + getNU() + getNP(), REAL, dataStructWspace);

	unsigned indexZ   = NX + NXA;
	unsigned indexGxx = indexZ + NX * NX;
	unsigned indexGzx = indexGxx + NXA * NX;
	unsigned indexGxu = indexGzx + NX * NU;
	unsigned indexGzu = indexGxu + NXA * NU;
	unsigned indexU   = indexGzu + NU;
	unsigned indexP   = indexU + NP;

	////////////////////////////////////////////////////////////////////////////
	//
	// Code for model simulation
	//
	////////////////////////////////////////////////////////////////////////////
	if (performsSingleShooting() == BT_TRUE)
	{
		modelSimulation.addStatement( state.getCols(0, NX)				== x.getRow( 0 ) );
		modelSimulation.addStatement( state.getCols(NX, NX + NXA)		== z.getRow( 0 ) );
		modelSimulation.addStatement( state.getCols(indexGzu, indexU)	== u.getRow( 0 ) );
		modelSimulation.addStatement( state.getCols(indexU, indexP)		== p );
		modelSimulation.addLinebreak( );
	}

	if ( useOMP )
	{
		stringstream s;
		s << "#pragma omp parallel for private(" << run.getName().getName() << ", " << state.getFullName().getName()
				<< ") shared("
				<< evGx.getDataStructString().getName() << ", "
				<< x.getDataStructString().getName()
				<< ")" << endl;

		modelSimulation.addStatement( s.str().c_str() );
	}

	if (performsSingleShooting() == BT_FALSE)
	{
		loop.addStatement( state.getCols(0, NX)			== x.getRow( run ) );
		loop.addStatement( state.getCols(NX, NX + NXA)	== z.getRow( run ) );
	}
	loop.addLinebreak( );

	// Fill in the input vector
	loop.addStatement( state.getCols(indexGzu, indexU)	== u.getRow( run ) );
	loop.addStatement( state.getCols(indexU, indexP)	== p );
	loop.addLinebreak( );

	// Integrate the model
	// TODO make that function calls can accept constant defined scalars
	if ( integrator->equidistantControlGrid() )
	{
		if (performsSingleShooting() == BT_FALSE)
			loop.addStatement( (String)"integrate"
					<< "(" << state.getFullName() << ", 1);\n"  );
		else
			loop.addStatement( (String)"integrate"
					<< "(" << state.getFullName() << ", "
					<< run.getFullName() << " == 0"
					<< ");\n"  );
	}
	else
	{
		if (performsSingleShooting() == BT_FALSE)
			loop.addStatement( (String)"integrate"
					<< "(" << state.getFullName() << ", 1, " << run.getFullName() << ");\n" );
		else
			loop.addStatement( (String)"integrate"
					<< "(" << state.getFullName() << ", "
					<< run.getFullName() << " == 0"
					<< ", " << run.getFullName() << ");\n" );
	}
	loop.addLinebreak( );

	if ( performsSingleShooting() == BT_TRUE )
	{
		// Single shooting case: prepare for the next iteration
		loop.addStatement( x.getRow(run + 1) == state.getCols(0, NX) );
		loop.addLinebreak( );
	}
	else
	{
		// Multiple shootin', compute residuum
		loop.addStatement( d.getTranspose().getCols(run * NX, (run  + 1) * NX) == state.getCols( 0,getNX() ) - x.getRow( run+1 ) );
		loop.addLinebreak( );
	}

	loop.addStatement( z.getRow( run ) == state.getCols(NX, NX + NXA) );

	// Stack sensitivities
	// \todo Upgrade this code later to stack Z sens
	loop.addStatement(
			evGx.makeRowVector().getCols(run * NX * NX, (run + 1) * NX * NX) == state.getCols(indexZ, indexGxx)
	);
	loop.addLinebreak();

	loop.addStatement(
			evGu.makeRowVector().getCols(run * NX * NU, (run + 1) * NX * NU) == state.getCols(indexGzx, indexGxu)
	);

	modelSimulation.addStatement( loop );

	// XXX This should be revisited at some point
//	modelSimulation.release( run );

	return SUCCESSFUL_RETURN;
}
returnValue ExportArithmeticStatement::exportCodeAddSubtract(	std::ostream& stream,
																const std::string& _sign,
																const std::string& _realString,
																const std::string& _intString
																) const
{
	if ( ( rhs1->getNumRows() != rhs2->getNumRows() ) || ( rhs1->getNumCols() != rhs2->getNumCols() ) )
		return ACADOERROR( RET_VECTOR_DIMENSION_MISMATCH );
	
	if (rhs1->getNumRows() != lhs->getNumRows() || rhs1->getNumCols() != lhs->getNumCols())
	{
		LOG( LVL_DEBUG )
			<< "lhs name is " << lhs.getName() << ", size: " << lhs.getNumRows() << " x " << lhs.getNumCols() << endl
			<< "rhs1 name is " << rhs1.getName() << ", size: " << rhs1.getNumRows() << " x " << rhs1.getNumCols() << endl;

		return ACADOERROR( RET_VECTOR_DIMENSION_MISMATCH );
	}
	
	//
	// Rough approximation of flops needed for matrix multiplication
	//
	unsigned numberOfFlops = lhs->getNumRows() * lhs->getNumCols();

	//
	// Optimization can be performed only if both matrices are not given.
	// Currently, optimizations cannot be performed on hard-coded matrices.
	//
	bool optimizationsAllowed = ( rhs1->isGiven() == false ) && ( rhs2->isGiven() == false );

	if (numberOfFlops < 4096 || optimizationsAllowed == false)
	{
		for( uint i=0; i<getNumRows( ); ++i )
			for( uint j=0; j<getNumCols( ); ++j )
			{
				if ( ( op0 != ESO_ASSIGN ) &&
						( rhs1->isGiven(i,j) == true ) && ( rhs2->isGiven(i,j) == true ) )
				{
					// check for zero value in case of "+=" or "-="
					if ( ( op1 == ESO_ADD ) && ( acadoIsZero(rhs1(i, j) + rhs2(i, j)) == true ) )
						continue;

					if ( ( op1 == ESO_SUBTRACT ) && ( acadoIsZero( rhs1(i, j) - rhs2(i, j)) == true ) )
						continue;
				}

				stream << lhs.get(i, j) << " " << getAssignString();

				if ( rhs1->isZero(i, j) == false )
				{
					stream  << " " << rhs1->get(i, j);
					if ( rhs2->isZero(i,j) == false )
						stream  << " " << _sign << " " << rhs2->get(i, j) << ";\n";
					else
						stream << ";" << endl;
				}
				else
				{
					if (rhs2->isZero(i, j) == false)
						stream  << " " << _sign << " " << rhs2->get(i, j) << ";\n";
					else
						stream << " 0.0;\n";
				}
			}
	}
	else if ( numberOfFlops < 32768 )
	{
		ExportIndex ii;
		memAllocator->acquire( ii );

		stream << "for (" << ii.getName() << " = 0; ";
		stream << ii.getName() << " < " << getNumRows() << "; ";
		stream << "++" << ii.getName() << ")\n{\n";

		for(unsigned j = 0; j < getNumCols( ); ++j)
		{
			stream << lhs->get(ii, j) << " " << getAssignString();
			stream  << " " << _sign << " " << rhs2->get(ii, j) << ";\n";
		}

		stream << "\n{\n";

		memAllocator->release( ii );
	}
	else
	{
		ExportIndex ii, jj;
		memAllocator->acquire( ii );
		memAllocator->acquire( jj );

		stream	<< "for (" << ii.getName() << " = 0; "
				<< ii.getName() << " < " << getNumRows() <<"; "
				<< "++" << ii.getName() << ")\n{\n";

		stream	<< "for (" << jj.getName() << " = 0; "
				<< jj.getName() << " < " << getNumCols() <<"; "
				<< "++" << jj.getName() << ")\n{\n";

		stream	<< lhs->get(ii, jj) << " " <<  getAssignString()
				<< _sign << " " << rhs2->get(ii, jj) << ";\n";

		stream	<< "\n}\n"
				<< "\n}\n";

		memAllocator->release( ii );
		memAllocator->release( jj );
	}

	return SUCCESSFUL_RETURN;
}
returnValue ExportArithmeticStatement::exportCodeAddSubtract(	FILE* file,
																const String& _sign,
																const String& _realString,
																const String& _intString,
																int _precision
																) const
{
//	if ( ( rhs1.isNull() ) || ( rhs2.isNull() ) || ( !rhs3.isNull() ) )
//		return ACADOERROR( RET_UNABLE_TO_EXPORT_STATEMENT );

	if (rhs1.getDim() == 0)
		return SUCCESSFUL_RETURN;

	if ( ( rhs1->getNumRows() != rhs2->getNumRows() ) || 
		 ( rhs1->getNumCols() != rhs2->getNumCols() ) )
		return ACADOERROR( RET_VECTOR_DIMENSION_MISMATCH );
	
	if ( !lhs.isNull() )
	{
		if ( ( rhs1->getNumRows() != lhs->getNumRows() ) || 
		     ( rhs1->getNumCols() != lhs->getNumCols() ) )
		{
			cout << "lhs name is " << lhs.getName().getName() <<
					", size: " << lhs.getNumRows() << " x " << lhs.getNumCols() << endl;
			cout << "rhs1 name is " << rhs1.getName().getName() <<
					", size: " << rhs1.getNumRows() << " x " << rhs1.getNumCols() << endl;

			return ACADOERROR( RET_VECTOR_DIMENSION_MISMATCH );
		}
	}
	
	String assignString;
	if ( getAssignString( assignString ) != SUCCESSFUL_RETURN )
		return ACADOERROR( RET_UNABLE_TO_EXPORT_STATEMENT );
	
	//
	// Rough approximation of flops needed for matrix multiplication
	//
	unsigned numberOfFlops = lhs->getNumRows() * lhs->getNumCols();

	//
	// Optimization can be performed only if both matrices are not given.
	// Currently, optimizations cannot be performed on hard-coded matrices.
	//
	int optimizationsAllowed =
			( rhs1->isGiven() == BT_FALSE ) && ( rhs2->isGiven() == BT_FALSE );

	if ((numberOfFlops < 4096) || (optimizationsAllowed == 0))
	{
		for( uint i=0; i<getNumRows( ); ++i )
			for( uint j=0; j<getNumCols( ); ++j )
			{
				if ( ( op0 != ESO_ASSIGN ) &&
						( rhs1->isGiven(i,j) == BT_TRUE ) && ( rhs2->isGiven(i,j) == BT_TRUE ) )
				{
					// check for zero value in case of "+=" or "-="
					if ( ( op1 == ESO_ADD ) && ( acadoIsZero(rhs1(i, j) + rhs2(i, j)) == BT_TRUE ) )
						continue;

					if ( ( op1 == ESO_SUBTRACT ) && ( acadoIsZero( rhs1(i, j) - rhs2(i, j)) == BT_TRUE ) )
						continue;
				}

				if ( !lhs.isNull() )
					acadoFPrintf( file,"%s %s ", lhs.get(i,j).getName(),assignString.getName() );

				if ( rhs1->isZero(i, j) == BT_FALSE )
				{
					acadoFPrintf( file,"%s", rhs1->get(i,j).getName() );
					if ( rhs2->isZero(i,j) == BT_FALSE )
						acadoFPrintf( file," %s %s;\n", _sign.getName(),rhs2->get(i,j).getName() );
					else
						acadoFPrintf( file,";\n" );
				}
				else
				{
					if ( rhs2->isZero(i,j) == BT_FALSE )
						acadoFPrintf( file,"%s %s;\n", _sign.getName(),rhs2->get(i,j).getName() );
					else
						acadoFPrintf( file,"0.0;\n" );
				}
			}
	}
	else if ( numberOfFlops < 32768 )
	{
		ExportIndex ii;
		memAllocator->acquire( ii );

		acadoFPrintf(file, "for (%s = 0; ", ii.getName().getName());
		acadoFPrintf(file, "%s < %d; ", ii.getName().getName(), getNumRows());
		acadoFPrintf(file, "++%s)\n{\n", ii.getName().getName());

		for(unsigned j = 0; j < getNumCols( ); ++j)
		{
			acadoFPrintf( file,"%s %s ", lhs->get(ii, j).getName(), assignString.getName() );
			acadoFPrintf( file,"%s %s;\n", _sign.getName(), rhs2->get(ii,j).getName() );
		}

		acadoFPrintf(file, "\n{\n");

		memAllocator->release( ii );
	}
	else
	{
		ExportIndex ii, jj;
		memAllocator->acquire( ii );
		memAllocator->acquire( jj );

		acadoFPrintf(file, "for (%s = 0; ", ii.getName().getName());
		acadoFPrintf(file, "%s < %d; ", ii.getName().getName(), getNumRows());
		acadoFPrintf(file, "++%s)\n{\n", ii.getName().getName());

		acadoFPrintf(file, "for (%s = 0; ", jj.getName().getName());
		acadoFPrintf(file, "%s < %d; ", jj.getName().getName(), getNumRows());
		acadoFPrintf(file, "++%s)\n{\n", jj.getName().getName());

		acadoFPrintf( file,"%s %s ", lhs->get(ii, jj).getName(), assignString.getName() );
		acadoFPrintf( file,"%s %s;\n", _sign.getName(), rhs2->get(ii,jj).getName() );

		acadoFPrintf(file, "\n{\n");
		acadoFPrintf(file, "\n{\n");

		memAllocator->release( ii );
		memAllocator->release( jj );
	}

	return SUCCESSFUL_RETURN;
}
Example #9
0
ExportIndex operator+(	const ExportIndex& _arg1,
						const ExportIndex& _arg2
						)
{
	ExportIndex tmp;

	if (_arg1.isGiven() == BT_TRUE && _arg2.isGiven() == BT_TRUE)
	{
		tmp.assignNode(new ExportIndexNode(_arg1.getGivenValue() + _arg2.getGivenValue()));

		return tmp;
	}

	if (_arg1.isVariable() == BT_TRUE && _arg2.isGiven() == BT_TRUE)
	{
		tmp.assignNode(new ExportIndexNode(_arg1.getName(), _arg1.getPrefix(), _arg1->getFactor(), _arg1->getOffset() + _arg2.getGivenValue()));

		return tmp;
	}

	if (_arg1.isGiven() == BT_TRUE && _arg2.isVariable() == BT_TRUE)
	{
		tmp.assignNode(new ExportIndexNode(_arg2.getName(), _arg2.getPrefix(),  _arg2->getFactor(), _arg2->getOffset() + _arg1.getGivenValue()));

		return tmp;
	}

	if(_arg1.isVariable() == BT_TRUE && _arg2.isVariable() == BT_TRUE && _arg1.getFullName() == _arg2.getFullName())
	{
		if ((_arg1->getFactor() + _arg2->getFactor()) == 0)
			tmp.assignNode(new ExportIndexNode(_arg1->getOffset() + _arg2->getOffset()));
		else
			tmp.assignNode(new ExportIndexNode(_arg1.getName(), _arg1.getPrefix(), _arg1->getFactor() + _arg2->getFactor(), _arg1->getOffset() + _arg2->getOffset()));
	}
	else
	{
		tmp.assignNode(new ExportIndexNode(ESO_ADD, _arg1, _arg2));
	}

	return tmp;
}
Example #10
0
ExportIndex operator*(	const ExportIndex& _arg1,
						const ExportIndex& _arg2
						)
{
	ExportIndex tmp;

	if (_arg1.isGiven() == BT_TRUE && _arg2.isGiven() == BT_TRUE)
	{
		tmp.assignNode(new ExportIndexNode(_arg1.getGivenValue() * _arg2.getGivenValue()));

		return tmp;
	}

	if (_arg1.isVariable() == BT_TRUE && _arg2.isGiven() == BT_TRUE)
	{
		tmp.assignNode(new ExportIndexNode(_arg1.getName(), _arg1.getPrefix(), _arg1->getFactor() * _arg2.getGivenValue(), _arg1->getOffset() * _arg2.getGivenValue()));

		return tmp;
	}

	if (_arg1.isGiven() == BT_TRUE && _arg2.isVariable() == BT_TRUE)
	{
		tmp.assignNode(new ExportIndexNode(_arg2.getName(), _arg2.getPrefix(), _arg2->getFactor() * _arg1.getGivenValue(), _arg2->getOffset() * _arg1.getGivenValue()));

		return tmp;
	}

	tmp.assignNode(new ExportIndexNode(ESO_MULTIPLY, _arg1, _arg2));

	return tmp;
}