Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2001-04-03 08:58:50


on 4/2/01 11:30 AM, nbecker_at_[hidden] wrote:

> Thanks for the ideas on the PN generator. Here is a new version that
> I think is more in the spirit of boost:

What does "PN" stand for?

> #ifndef PNGen_H
> #define PNGen_H
>
> #include <boost/random.hpp>
>
> template<class RNG>

I think all-caps identifiers are discouraged, because they could clash with
macro names.

> class PNGen {

The names should be like the_cpp_standard, and not InterCaps.

> RNG& rng;
> typename RNG::result_type cache;
> int cnt;
> public:
> PNGen (RNG& _rng) :
> rng (_rng),
> cnt (0)
> {}

The constructor could take its parameter explicitly.

> void Refresh() {
> cache = rng();
> cnt = std::numeric_limits<typename RNG::result_type>::digits;
> }
>
> int Next() {
> int bit = cache & 1;
> cache >>= 1;
> cnt--;
> return bit;
> }

Do these implementation details have to be publicly exposed? If you are
returning bits, what's wrong with a "bool" result?

> int Bipolar() {
> return (operator()() == 0) ? -1 : 1;
> }
>
> int Unipolar() {
> return operator()();
> }

Why are these part of the interface? Couldn't the user translate the
results his/herself?

> int operator()() {
> if (cnt == 0)
> Refresh();
> return Next();
> }
>
>
> };
>
> #endif

The interface could be more like the other random number generators:

//=========================================================================
// Warning: NOT compiled
// #include <you_figure_it_out>

namespace boost
{
namespace random
{

template < class RandomNumberGenerator >
class pretty_nice_generator
{
    typedef pretty_nice_generator<RandomNumberGenerator> self_type;

public:
    typedef RandomNumberGenerator base_type;
    typedef bool result_type;

    BOOST_STATIC_CONSTANT( bool, has_fixed_range = true );
    BOOST_STATIC_CONSTANT( result_type, min_value = false );
    BOOST_STATIC_CONSTANT( result_type, max_value = true );

    result_type min() const
        { return min_value; }
    result_type max() const
        { return max_value; }

    explicit self_type( base_type const &rng = base_type() )
        : rng_( rng ), count_()
        { init(); }

    template < typename T >
        explicit self_type( T seed )
            : rng_( seed ), count_()
            { init(); }

    template < typename T >
        void seed( T s )
            { rng_.seed( s ); init(); }

    result_type operator()()
    {
        bool const bit = cache_ & 1;
        cache_ >>= 1;
        if ( --count_ <= 0 )
            init();
        return bit;
    }

    bool validation( result_type x ) const
        { return valid == x; }

    template < typename Ch, class Tr >
        friend std::basic_ostream<Ch, Tr> &
          operator <<(
           std::basic_ostream<Ch, Tr> &os,
           self_type const &png )
    {
        return os << png.rng_ << ' ' << png.cache_ << ' ' << png.count_;
    }

    template < typename Ch, class Tr >
        friend std::basic_istream<Ch, Tr> &
          operator >>(
           std::basic_istream<Ch, Tr> &is,
           self_type &png )
    {
        using std::ws;
        return is >> png.rng_ >> ws >> png.cache_ >> ws >> png.count_ >> ws;
    }

    friend operator ==( self_type const &x, self_type const &y )
    {
        return x.rng_ == y.rng_ && x.cache_ == y.cache_
         && x.count_ == y.count_;
    }
    friend operator !=( self_type const &x, self_type const &y )
        { return !(x == y); }

private:
    typedef typename base_type::result_type cache_type;

    void init()
    {
        cache_ = rng_();
        count_ = std::numeric_limits<cache_type>::digits;
    }

    base_type rng_;
    cache_type cache_;
    int count_;

}; // boost::random::pretty_nice_generator

} // random
} // boost
//=========================================================================

-- 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk