Sorry if this is a simple question - but is there a "best practice" for downsampling the evolution of the state variables in odeint?
Below, I've copied a nice example for building an "observer" to log the state variables provided in this article (http://www.codeproject.com/Articles/268589/odeint-v2-Solving-ordinary-differential-equations)
struct streaming_observer
{
std::ostream &m_out;
streaming_observer( std::ostream &out ) : m_out( out ) {}
void operator()( const state_type &x , double t ) const
{
m_out << t;
for( size_t i=0 ; i < x.size() ; ++i )
m_out << "\t" << x[i];
m_out << "\n";
}
};
// ...
integrate_const( runge_kutta4< state_type >() , lorenz , x , 0.0 , 10.0 , dt , streaming_observer( std::cout ) );
How would you alter the observer to only log the state every 10 steps (for example). I'm wondering whether there is a more elegant solution than putting in an if-statement:
struct streaming_observer
{
std::ostream &m_out;
int count;
streaming_observer( std::ostream &out ) : m_out( out ) {count = 10;}
void operator()( const state_type &x , double t ) const
{
if( count == 10 ) {
count = 1;
m_out << t;
for( size_t i=0 ; i < x.size() ; ++i )
m_out << "\t" << x[i];
m_out << "\n";
}
else {
count++;
}
}
};
I had the same issue and solved it exactly like you did. However, you could also consider using a stepper with step-size control and then use integrate_const with a dt such that the observer is called at the required intervals. When you use a stepper with step-size control (even better: dense ouput like dopri5), integrate_const adjusts the step size according to your error tolerance, but then assures that the observer is called at times t0 + n*dt.
Actually I would do it exactly like you did. You can also write a small adapter for doing the striding:
template< typename Obs >
struct striding_observer {
size_t stride , count;
Observer obs;
striding_observer( size_t s , Obs o ) : stride(s) , count(1) , obs(o) { }
template< typename S , typename T >
void operator()( State const& s , Time const& t ) {
if( count == stride ) {
obs( s , t );
count = 1;
} else {
++count;
}
}
};
template< typename Obs >
striding_observer< Obs > make_striding_observer( size_t stride , Obs o ) {
return striding_observer< Obs >( stride , o );
}
Then the striding is optional and composable. You can then write the very first example as
integrate_const( runge_kutta4< state_type >() ,
lorenz , x , 0.0 , 10.0 , dt ,
make_striding_observer( 10 , streaming_observer( std::cout ) ) );
Related
system of equations
Hi. I want to evolve those equations in time from zero to 10^16 and initial condotions x(0)=10^8 and y(0)= 0.5. Because of the dependence of the equations on x in the denominator I think using odeint with runge_kutta_dopri5 is a good choice because of the adaptive step control. The thing is I have little idea how to do this in practice cause i have little experience in c++ and odeint. I searched a lot about using odeint but the examples where not helpful for me. Also i want to stop the calculations when x reaches zero i saw this https://stackoverflow.com/questions/33334073/stop-integration-in-odeint-with-stiff-ode
based on examples i wrote this so far with no luck
#include <iostream>
#include <vector>
#include <cmath>
#include <boost/array.hpp>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace boost::numeric::odeint;
const double b = 43.0e17;
typedef boost::array< double , 2 > state_type;
void binary(const state_type &x , state_type &dxdt , double t )
{
dxdt[0] = -b*(64.0/5)*(1 + (73.0/24)*pow(x[1],2)
+ 37.0/96)*pow(x[1],4) )/pow(x[0],3)*pow(1-pow(x[1],2),7.0/2);
dxdt[1] = -b*(304.0/96)*x[1]*(1 + (121.0/304)*pow(x[1],2))
/pow(x[0],4)*pow((1 - pow(x[1],2)),5.0/2);
}
void write_binary( const state_type &x , const double t )
{
cout << t << '\t' << x[0] << '\t' << x[1] << '\t' << x[2] << endl;
}
//I dont know what this does but the examples used it
struct streaming_observer
{
std::ostream& m_out;
streaming_observer( std::ostream &out ) : m_out( out ) { }
template< class State , class Time >
void operator()( const State &x , Time t ) const
{
m_out << t;
for( size_t i=0 ; i<x.size() ; ++i ) m_out << "\t" << x[i] ;
m_out << "\n";
}
};
//This was a first try with a given stepper but i want to replace it
int main(int argc, char **argv)
{
state_type x = { 20.871e8 , 0.5 }; // initial conditions
integrate( binary , x , 0.0 , 1000.0 , 0.1 , write_binary );
}
When I compiled it a run it I got this error
Internal Program Error - assertion (i < N) failed in const T& boost::array::operator[](boost::array::size_type) const [with T = double; long unsigned int N = 2ul; boost::array::const_reference = const double&; boost::array::size_type = long unsigned int]:
/usr/include/boost/array.hpp(129): out of range
Aborted (core dumped)
How can i get this work?
the write_binary function writes over the array bounds and causes the assertion. x[2] is not valid.
I try to run this example from the ODEINT library to solve ODE. It just runs fine, but instead of cout the results to screen, I want to write them to a file. I add this ofstream to the code under write_cout function but it only writes the last line of result to the file and not all.
Do you have any idea about this? Thanks
#include <iostream>
#include <boost/numeric/odeint.hpp>
#include <fstream>
using namespace std;
using namespace boost::numeric::odeint;
void rhs( const double x , double &dxdt , const double t )
{
dxdt = 3.0/(2.0*t*t) + x/(2.0*t);
}
void write_cout( const double &x , const double t )
{
cout << t << '\t' << x << endl;
cout<<"alo"<<endl;
ofstream buckyFile ("tuna.txt");
buckyFile<<t <<'\t'<<x<<endl;
}
// state_type = double
typedef runge_kutta_dopri5< double > stepper_type;
int main()
{
double x = 0.0;
integrate_adaptive( make_controlled( 1E-12 , 1E-12 , stepper_type() ) ,
rhs , x , 1.0 , 10.0 , 0.1 , write_cout );
}
Or even better
struct stream_writer
{
std::ostream& m_out;
stream_writer( std::ostream& out ) : m_out( out ) {}
void operator()( const double &x , const double t )
{
m_out << t << "\t" << x << "\n";
}
};
int main()
{
double x = 0.0;
ofstream fout( "tuna.txt" );
integrate_adaptive( make_controlled( 1E-12 , 1E-12 , stepper_type() ) ,
rhs , x , 1.0 , 10.0 , 0.1 , stream_writer( fout ) );
}
ofstream buckyFile ("tuna.txt");
opens a new file tuna.txt each time the function is entered, overriding what ever was there before.
A quick fix would be to use a
static ofstream buckyFile ("tuna.txt");
instead.
Hello I am having difficulty with the decision I have made in coding. I am developing a game, and in my game I have treated everything in Object class and object class has two attributes mainly the vital attribute and point attribute. Point attribute somehow need to be in pair of string and int and sometimes float. (I don't use boost:variant I know it could have been much simpler as I have searched on this site) but I don't like to stick to the boost option, I really need to do this without it. So each point attribute object has int and floats on it, for example attack damage which, in my system is of type int, while attack rate is of type float. I came to solution to make a wrapper template class called PointAttribute< T > and this inherits on PABase class so I can make push it on to map without me knowing the type.
Now I am on the big question how do I properly access the second element of map with pair:
pair< string , PABase > ?
Is it even possible?
I did mine using this code
template< typename T >
PointAttribute< T > * Object::getPointAttributes( const string & oname )
{
PointAttribute< T > * attribute = static_cast< PointAttribute<T>* >( &pointAttributes[ oname ] );
cout << "Getting value of : " << oname << " value : " << attribute->getCurrentPoints() << endl;
return attribute;
}
I don't know if I am doing everything right. I know I am doing it wrong and I desperately need help on accessing the information from the second.
Actually my codes works but when I retrieved my desired value it returns a float with the wrong value. I've check the value of my point attribute definition and they seem to be loaded properly in my system it just that when I retrieved it returns a value which is of not the actual value I am expecting.
I invoked the function on this way
float attackRange = Object::getPointAttributes<float>( "attackrange" )->getCurrentPoints();
EDIT:
Here is my code for PABase and PointAttribute< T >:
#ifndef POINTATTRIBUTE_HPP
#define POINTATTRIBUTE_HPP
#include<iostream>
using std::cout;
using std::endl;
using std::cerr;
#include<string>
using std::string;
#include<memory>
using std::unique_ptr;
#include<SFML/Graphics.hpp>
namespace esc
{
class PABase{ public: virtual ~PABase(){} };
template< typename T >
class PointAttribute : public PABase
{
public:
PointAttribute();
virtual ~PointAttribute();
void setAttributePoints( T );
T getAttributePoints() const;
void increaseCurrentPointsBy( T );
void decreaseCurrentPointsBy( T );
void setCurrentPointsTo( T );
T getCurrentPoints() const;
void increaseMaxPointsBy( T );
void decreaseMaxPointsBy( T );
void setMaxPointsTo( T );
T getMaxPoints() const;
void increaseBasePointsBy( T );
void decreaseBasePointsBy( T );
void setBasePointsTo( T );
T getBasePoints() const;
void resetPointAttribute();
private:
void init();
string attributeName;
T attributePoints;
T currentPoints;
T maxPoints;
T basePoints;
};
template< typename T >
PointAttribute< T >::PointAttribute()
:
attributePoints( T() ),
currentPoints( T() ),
maxPoints( T() ),
basePoints( T() )
{
}
template< typename T >
PointAttribute< T >::~PointAttribute()
{
}
template< typename T >
inline void PointAttribute< T >::setAttributePoints( T p )
{
attributePoints = p;
currentPoints = p;
maxPoints = p;
basePoints = T();
cout << "\n\nAttribute set! " << endl;
cout << "Attribute points : " << attributePoints << endl;
cout << "Max points : " << maxPoints << endl;
cout << "Base points : " << basePoints << endl;
}
template< typename T >
inline T PointAttribute< T >::getAttributePoints() const
{
return attributePoints;
}
template< typename T >
inline void PointAttribute< T >::increaseCurrentPointsBy( T amount )
{
currentPoints += amount;
currentPoints = ( currentPoints > maxPoints )? maxPoints : currentPoints;
}
template< typename T >
inline void PointAttribute< T >::decreaseCurrentPointsBy( T amount )
{
currentPoints -= amount;
currentPoints = ( currentPoints < T() )? T() : currentPoints;
}
template< typename T >
inline void PointAttribute< T >::setCurrentPointsTo( T amount )
{
if( amount >= basePoints && amount <= maxPoints )
currentPoints = amount;
}
template< typename T >
inline T PointAttribute< T >::getCurrentPoints() const
{
return currentPoints;
}
template< typename T >
inline void PointAttribute< T >::increaseMaxPointsBy( T amount )
{
int checkVal = ( amount < T() )? T() : amount;
maxPoints += checkVal;
}
template< typename T >
inline void PointAttribute< T >::decreaseMaxPointsBy( T amount )
{
T checkVal = ( amount < T() )? T() : amount;
maxPoints -= checkVal;
}
template< typename T >
inline void PointAttribute< T >::setMaxPointsTo( T amount )
{
T checkVal = ( amount < T() )? T() : amount;
maxPoints = checkVal;
}
template< typename T >
inline T PointAttribute< T >::getMaxPoints() const
{
return maxPoints;
}
template< typename T >
inline void PointAttribute< T >::increaseBasePointsBy( T amount )
{
if( amount > T() && amount <= maxPoints )
basePoints += amount;
}
template< typename T >
inline void PointAttribute< T >::decreaseBasePointsBy( T amount )
{
if( amount > T() && amount <= maxPoints )
basePoints -= amount;
}
template< typename T >
inline void PointAttribute< T >::setBasePointsTo( T amount )
{
if( amount > T() && amount <= maxPoints )
basePoints = amount;
}
template< typename T >
inline T PointAttribute< T >::getBasePoints() const
{
return basePoints;
}
template< typename T >
inline void PointAttribute< T >::resetPointAttribute()
{
maxPoints = attributePoints;
basePoints = T();
}
}
#endif // POINTATTRIBUTE_HPP
Here is how the point attribute is beign filled up before the game begins. The definition is loaded from a simple text file with this given syntax:
[pointattribute]
attackdamage 7
attackrange 150
and here is the part of the home-made reader I have made, what this does is to read a particular identifier as long it is a valid file symbol, in this case [pointattribute]
the reason is I could add more point attribute in the future without doing a lot of codes and I can just change them freely as I balance the game. (I am writing a framework for RTS).
Here is the snippet for that else-if part of the reader
else if( identifier.compare("[pointattribute]") == 0 )
{
string aname;
string s_eval;
s >> aname >> s_eval;
cout << "\n\nLoading point attribute of : " << oname << endl;
cout << "Attribute name : " << aname << " value : ";
if( is< float >( s_eval ) )
{
istringstream s( s_eval );
float fval = 0.0f;
s >> fval;
PointAttribute< float > wrap;
wrap.setAttributePoints( fval );
attrib->pointAttributes[ aname ] = wrap;
cout << fval << endl;
}
else if( is< int >( s_eval ) )
{
istringstream s( s_eval );
int ival = 0;
s >> ival;
PointAttribute< int > wrap;
wrap.setAttributePoints( ival );
attrib->pointAttributes[ aname ] = wrap;
cout << ival << endl;
}
}
The value returned in Object class scope is on around 1.0e something whatever. It just return that kind of real number which is in fact not the value I am expecting. Something is wrong and something I gravely overlooked.
Also I have a young experience in C++ so sorry for my jargons I hope I made myself clear. Thanks for your help.
Can you provide me with a simple example of performing a numeric integration with odeint in C++?
I would like to use the convenient integrate function, documented as:
integrate( system , x0 , t0 , t1 , dt )
Also I'm not sure, how to pass it instead of a function or a functor, a class method, if that's possible.
In C++11 you can use a simple lambda function wrapping the call to your member method
Class c;
auto f = [&c]( const state_type & x , state_type &dxdt , double t ) {
c.system_func( x , dxdt , t ); };
integrate( f , x0 , t0 , t1 , dt );
std::bind might also work, but then you have to take care if values are passed by reference of by value.
In C++03 you need to write a simple wrapper around your class method
struct wrapper
{
Class &c;
wrapper( Class &c_ ) : c( c_ ) { }
template< typename State , typename Time >
void operator()( State const &x , State &dxdt , Time t ) const
{
c.system_func( x , dxdt , t );
}
};
// ...
integrate( wrapper( c ) , x0 , t0 , t1 , dt );
(Boost.Bind will not work correctly with more then two arguments).
You mean examples in addition to the ones provided online?
#include <iostream>
#include <boost/array.hpp>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace boost::numeric::odeint;
const double sigma = 10.0;
const double R = 28.0;
const double b = 8.0 / 3.0;
typedef boost::array< double , 3 > state_type;
void lorenz( const state_type &x , state_type &dxdt , double t )
{
dxdt[0] = sigma * ( x[1] - x[0] );
dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
dxdt[2] = -b * x[2] + x[0] * x[1];
}
void write_lorenz( const state_type &x , const double t )
{
cout << t << '\t' << x[0] << '\t' << x[1] << '\t' << x[2] << endl;
}
int main(int argc, char **argv)
{
state_type x = { 10.0 , 1.0 , 1.0 }; // initial conditions
integrate( lorenz , x , 0.0 , 25.0 , 0.1 , write_lorenz );
}
And regarding the system, you can provide anything where the following expression is valid:
sys( x , dxdt , t ) // returning void
Check the user's guide (and more examples) online.
I would like to see the structure of the memory, allocated to two different variables.
The attention behind this, is to understand how the memory is structured in order of storing different datatypes.
How is it done in C++?
//how to show, whats in memory in &var1 &var2 ?
short var1 = 2;
string var2 = "bla";
If you are using Eclipse, you can use the Memory View in the debug perspective.
Either that, or simply create a pointer to your variables and inspect the contents of those:
short var1 = 2;
string var2 = "bla";
char* pVar1 = (char*)&var1; //point to memory storing var1
char* pVar2 = (char*)&var2; //point to memory storing var2
If you're using MSVS, you can open the Memory tab and write the address you wish to inspect.
You must be in debug - Debug -> Windows -> Memory.
I usually use something like the following:
template< typename T >
class Dump
{
public:
explicit Dump( T const& obj ) ;
void print( std::ostream& dest ) const ;
friend std::ostream& operator<<( std::ostream& dest, Dump const& source )
{
source.print( dest );
return source;
}
private:
unsigned char const*myObj ;
} ;
template< typename T >
inline Dump< T >
dump(
T const& obj )
{
return Dump< T >( obj ) ;
}
template< typename T >
Dump< T >::Dump(
T const& obj )
: myObj( reinterpret_cast< unsigned char const* >( &obj ) )
{
}
template< typename T >
void
Dump< T >::print(
std::ostream& dest ) const
{
IOSave saver( dest ) ;
dest.fill( '0' ) ;
dest.setf( std::ios::hex, std::ios::basefield ) ;
char const* baseStr = "" ;
if ( (dest.flags() & std::ios::showbase) != 0 ) {
baseStr = "0x" ;
dest.unsetf( std::ios::showbase ) ;
}
unsigned char const* const
end = myObj + sizeof( T ) ;
for ( unsigned char const* p = myObj ; p != end ; ++ p ) {
if ( p != myObj ) {
dest << ' ' ;
}
dest << baseStr << std::setw( 2 ) << (unsigned int)( *p ) ;
}
}
IOSave is a simple class which saves the formatting state (flags,
fill and precision) in the constructor, and restores them in the
destructor.