Commit c9426c9b authored by CHAMONT David's avatar CHAMONT David
Browse files

Avant pause...

parent 25996662
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>
//==========
struct Vecteur { const double x, y, z; } ;
Vecteur operator*( const Vecteur& v, const double d )
{ Vecteur res = { v.x * d, v.y * d, v.z * d }; return res; }
Vecteur operator+( const Vecteur& v1, const Vecteur& v2 )
{ Vecteur res = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; return res; }
//==========
class Particule ;
typedef std::vector< const Particule * > Particules ;
class Particule
{
public:
Particule( const Vecteur & position, const Vecteur & vitesse )
: position_( position ), vitesse_( vitesse )
{}
virtual ~Particule() {} ;
virtual const Particule * clone() const = 0;
static const Particule * cloner( const Particule * const p )
{
return p->clone();
}
virtual Particules evolue() const = 0;
protected :
const Vecteur position_, vitesse_;
static const double PAS_DE_TEMPS = 1e-6 ;
};
//==========
class Photon : public Particule
{
public:
Photon( const Vecteur & position, const Vecteur & vitesse )
: Particule( position, vitesse )
{}
virtual const Particule * clone() const
{
return new Photon( position_, vitesse_ );
}
virtual Particules evolue() const
{
return Particules( 1, new Photon( position_ + vitesse_ * PAS_DE_TEMPS,
vitesse_ ) );
}
};
//==========
class Electron : public Particule
{
public:
Electron( const Vecteur & position,
const Vecteur & vitesse,
const bool anti )
: Particule( position, vitesse ), anti_( anti )
{}
virtual const Particule * clone() const
{
return new Electron( position_, vitesse_, anti_ );
}
bool anti() const { return anti_ ; }
virtual Particules evolue() const
{
static const double PROBA_PHOTON_SECONDAIRE = 1e-5 ;
// Impur (mutation res + appel à rand())
Particules res( 1,
new Electron( position_ + vitesse_ * PAS_DE_TEMPS,
vitesse_ ,
anti_ ) );
if ((std::rand() / double(RAND_MAX)) < PROBA_PHOTON_SECONDAIRE)
{
res.push_back( new Photon( position_, vitesse_ ) ) ;
}
return res;
}
private:
const bool anti_ ;
};
//==========
class Collision
{
public :
Collision( const long nb_particules )
: particules_( nb_particules )
{
// Impur (mutation de particules_)
std::generate( particules_.begin(), particules_.end(), generer_particule );
}
Collision( const Collision & c )
: particules_( c.particules_.size() )
{
// Impur (mutation de particules_)
std::transform( c.particules_.begin(),
c.particules_.end(),
particules_.begin(),
Particule::cloner );
}
// Intrinsèquement impur (modification *this), mais requis par le C++98
Collision& operator=( const Collision & c ) {
if (&c == this) { return *this; }
*this = Collision(c);
return *this;
}
~Collision() {
// Impur (mutation de particules_)
std::for_each( particules_.begin(), particules_.end(), detruire_particule );
}
long nb_electrons() const { return nb_particules( filtre_electron ); }
long nb_positrons() const { return nb_particules( filtre_positron ); }
long nb_photons() const { return nb_particules( filtre_photon ); }
Collision evolue( const long nb_evolutions = 1 ) const
{
if ( nb_evolutions == 0 ) { return *this; }
const Collision etape =
Collision( std::for_each( particules_.begin(),
particules_.end(),
CollecteurParticules() ).resultat() );
return etape.evolue( nb_evolutions - 1 );
}
void affiche() const
{
// Impur (entrée-sortie)
std::cout
<< nb_electrons() <<" e-, "
<< nb_positrons() <<" e+, "
<< nb_photons() <<" p"
<< std::endl ;
}
private :
// Impur (données mutables)
Particules particules_;
// Attention, ce constructeur prend possession des particules d'entrée
// Ce concept ne peut pas être exprimé par le code en C++98...
Collision( const Particules & ps )
: particules_( ps )
{}
static const Particule * generer_particule()
{
// Impur (appel à rand())
const Vecteur position = { 0, 0, 0 };
const Vecteur vitesse = { 1, 0, 0 };
const bool anti = ((std::rand() / double(RAND_MAX)) >= 0.5);
return new Electron( position, vitesse, anti );
}
// Impur (manipule la donnée d'entrée)
static void detruire_particule( const Particule * const p )
{
delete p;
}
static bool filtre_electron( const Particule * const p )
{
const Electron * electron_ptr = dynamic_cast< const Electron * >( p ) ;
return ( ( electron_ptr != NULL ) && ( !electron_ptr->anti() ) );
}
static bool filtre_positron( const Particule * const p )
{
const Electron * electron_ptr = dynamic_cast< const Electron * >( p ) ;
return ( ( electron_ptr != NULL ) && ( electron_ptr->anti() ) );
}
static bool filtre_photon( const Particule * const p )
{
return ( dynamic_cast< const Photon * >( p ) != NULL );
}
long nb_particules( bool(* filtre)(const Particule * const) ) const
{
return std::count_if( particules_.begin(), particules_.end(), filtre );
}
class CollecteurParticules
{
public:
// Impur (mutation d'état interne)
void operator()( const Particule * const p ) {
const Particules res_int = p->evolue();
std::copy( res_int.begin(), res_int.end(), std::back_inserter( res_ ) );
}
Particules resultat() const {
return res_;
}
private:
// Impur (données mutables)
Particules res_;
};
};
//==========
int main( const int argc, const char * const argv[] )
{
assert( argc == 3 );
const long nb_particules = std::atol( argv[1] );
const long nb_evolutions = std::atol( argv[2] );
// Impur (entrée-sortie)
const clock_t avant = clock() ;
const Collision collision =
Collision( nb_particules ).evolue( nb_evolutions );
collision.affiche() ;
// Impur (entrée-sortie)
const clock_t apres = clock() ;
// Impur (entrée-sorties)
std::cout << "Duree " << int((apres - avant) / double(CLOCKS_PER_SEC) * 1000) << " ms"
<< std::endl ;
return 0 ;
}
#include <vector>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>
//==========
long nb_vecteurs = 0;
class Vecteur
{
public :
Vecteur( double x = 0, double y = 0, double z = 0 )
{
x_ = x;
y_ = y;
z_ = z;
nb_vecteurs++;
}
Vecteur( const Vecteur & v )
{
x_ = v.x_;
y_ = v.y_;
z_ = v.z_;
nb_vecteurs++;
}
~Vecteur()
{
nb_vecteurs--;
}
void multiplie( double d )
{
x_ *= d;
y_ *= d;
z_ *= d;
}
void ajoute( const Vecteur & v )
{
x_ += v.x_;
y_ += v.y_;
z_ += v.z_;
}
private :
double x_, y_, z_;
} ;
//==========
Vecteur VNULL( 0, 0, 0 );
double PAS_DE_TEMPS = 1e-6;
//==========
class Particule ;
typedef std::vector< Particule * > Particules ;
class Particule
{
public:
Particule( const Vecteur & position, const Vecteur & vitesse )
{
position_ = position;
vitesse_ = vitesse;
}
virtual ~Particule() {}
virtual Particule * clone() const = 0;
virtual void evolue( Particules & secondaires ) = 0;
protected:
Vecteur position_;
Vecteur vitesse_;
} ;
//==========
class Photon : public Particule
{
public:
Photon( const Vecteur & position, const Vecteur & vitesse )
: Particule( position, vitesse )
{}
virtual Particule * clone() const
{
return new Photon( position_, vitesse_ );
}
virtual void evolue( Particules & secondaires )
{
Vecteur deplacement( vitesse_ );
deplacement.multiplie( PAS_DE_TEMPS );
position_.ajoute( deplacement );
}
} ;
//==========
class Electron : public Particule
{
public:
Electron( const Vecteur & position,
const Vecteur & vitesse,
bool anti = false )
: Particule( position, vitesse )
{
anti_ = anti;
}
virtual Particule * clone() const
{
return new Electron( position_, vitesse_, anti_ );
}
bool anti() { return anti_; }
virtual void evolue( Particules & secondaires )
{
Vecteur deplacement( vitesse_ );
deplacement.multiplie( PAS_DE_TEMPS );
position_.ajoute( deplacement );
if ( (std::rand() / double(RAND_MAX)) < 0.00001 ) {
Photon * secondaire = new Photon( position_, vitesse_ );
secondaires.push_back( secondaire );
}
}
private:
bool anti_;
} ;
//==========
class Collision
{
public:
Collision( long nb_particules )
{
for ( long ip = 0; ip < nb_particules; ++ip )
{
Vecteur vitesse( 1, 0, 0 );
if ( ( std::rand() / double(RAND_MAX) ) < 0.5 ) {
particules_.push_back( new Electron( VNULL, vitesse ) );
} else {
particules_.push_back( new Electron( VNULL, vitesse, true ) );
}
}
}
Collision( const Collision & c )
{
Particules::const_iterator pp;
for ( pp = c.particules_.begin(); pp != c.particules_.end(); ++pp ) {
particules_.push_back( (*pp)->clone() );
}
}
Collision& operator=( const Collision & c ) {
if (&c == this) { return *this; }
*this = Collision(c);
return *this;
}
~Collision()
{
Particules::iterator pp;
for ( pp = particules_.begin(); pp != particules_.end(); ++pp ) {
delete (*pp);
}
}
long nb_electrons()
{
long nb = 0;
Particules::iterator pp;
for ( pp = particules_.begin(); pp != particules_.end(); ++pp ) {
Electron * electron = dynamic_cast< Electron * >( *pp );
if ( (electron != 0) && (!electron->anti()) ) { ++nb; }
}
return nb;
}
long nb_positrons()
{
long nb = 0;
Particules::iterator pp;
for ( pp = particules_.begin(); pp != particules_.end(); ++pp ) {
Electron * electron = dynamic_cast< Electron * >( *pp );
if ( (electron != 0) && (electron->anti()) ) { ++nb; }
}
return nb;
}
long nb_photons()
{
long nb = 0 ;
Particules::iterator pp;
for ( pp = particules_.begin(); pp != particules_.end(); ++pp ) {
if ( dynamic_cast< Photon * >( *pp ) != 0 ) { ++nb; }
}
return nb ;
}
void evolue()
{
Particules secondaires;
Particules::iterator pp;
for ( pp = particules_.begin(); pp != particules_.end(); ++pp )
{
(*pp)->evolue(secondaires);
}
for ( pp = secondaires.begin(); pp != secondaires.end(); ++pp )
{
particules_.push_back(*pp);
}
}
void affiche()
{
std::cout
<< nb_electrons() << " e-, "
<< nb_positrons() << " e+, "
<< nb_photons() << " p"
<< std::endl ;
}
private:
Particules particules_;
};
//==========
int main( int argc, char * argv[] )
{
assert(argc==3);
long nb_particules = std::atol( argv[1] );
long nb_evolutions = std::atol( argv[2] );
clock_t avant = clock();
Collision collision( nb_particules );
for ( long pas = 1 ; pas <= nb_evolutions ; ++pas ) {
collision.evolue();
}
collision.affiche();
clock_t apres = clock();
long ms = int((apres - avant) / double(CLOCKS_PER_SEC) * 1000) ;
std::cout
<< nb_vecteurs << " vecteurs\n"
<< "Duree " << ms << " ms" << std::endl;
return 0 ;
}
#include <algorithm>
#include <iostream>
#include <vector>
#include <memory>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>
//==========
struct Vecteur { double const x, y, z; } ;
Vecteur operator*( Vecteur const & v, double const d )
{ return Vecteur{ v.x * d, v.y * d, v.z * d }; }
Vecteur operator+( Vecteur const & v1, Vecteur const & v2 )
{ return Vecteur{ v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; }
//==========
class Particule ;
typedef Particule const * ParticuleCP ;
typedef std::vector<ParticuleCP> Particules ;
class Particule
{
public:
Particule( Vecteur const & position, Vecteur const & vitesse )
: position_(position), vitesse_(vitesse)
{}
virtual ParticuleCP clone() const = 0 ;
virtual ~Particule() {} ;
virtual Particules evolue() const = 0 ;
static ParticuleCP cloner( ParticuleCP const & p )
{ return p->clone() ; }
protected :
Vecteur const position_, vitesse_ ;
static double constexpr PAS_DE_TEMPS = 1e-6 ;
};
//==========
class Photon : public Particule
{
public:
Photon( Vecteur const & position, Vecteur const & vitesse )
: Particule( position, vitesse )
{}
virtual ParticuleCP clone() const
{ return new Photon(position_,vitesse_) ; }
virtual Particules evolue() const
{
Vecteur const nouvelle_position = position_+vitesse_*PAS_DE_TEMPS ;
return Particules( 1, new Photon(nouvelle_position,vitesse_) ) ;
}
} ;
//==========
class Electron : public Particule
{
public:
Electron
( Vecteur const & position, Vecteur const & vitesse, bool const anti )
: Particule( position, vitesse ), anti_( anti )
{}
virtual ParticuleCP clone() const
{ return new Electron(position_,vitesse_,anti_ ) ; }
bool anti() const
{ return anti_ ; }
virtual Particules evolue() const
{
static const double PROBA_PHOTON_SECONDAIRE = 1e-5 ;