0

I'd like to define my objects of boost-distributions in my class and keep on using them.

For the binomial Distribution this was no problem.

Bdist.hpp

#include "boost/math/distributions/binomial.hpp"

class Bdist {
public:

    Bdist();

    Bdist(unsigned n, double theta);

    virtual ~Bdist(){};

    /**stuff**/

private:
    boost::math::binomial_distribution<> binomialboost;
    double theta; //Every experiment successes with this propability 
    unsigned n; //Amount of trials

};

And in the Bdist.cpp

Bdist::Bdist(unsigned n, double theta) :
n(n), theta(theta) {
    binomialboost= boost::math::binomial_distribution<> (((int)n),theta); 
}

Bdist::Bdist() {
    n = 0;
    theta = 0.0;
    binomialboost = boost::math::binomial_distribution<>(((int)n), theta);
}

Strangely, when I do the same with the geometrical distribution it fails:

Gdist::Gdist() {
    theta = 0;
    geometricboost = boost::math::geometric_distribution<>(theta);
}

Gdist::Gdist(double theta) :
theta(theta) {
    geometricboost = boost::math::geometric_distribution<>(theta);
}

Here's the Gdist.hpp

#include <complex>
#include <boost/math/distributions/geometric.hpp>

class Gdist {
public:
    Gdist();

    Gdist(double theta);

    virtual ~Gdist(){};

/**stuff**/

private:
    boost::math::geometric_distribution <> geometricboost;
    double theta; //Propability
};

For testing purposes, I wrote a small main.cpp to see how it would react with different initialisations:

#include <cstdlib>
#include <boost/math/distributions/geometric.hpp>

int main(int argc, char** argv) {
boost::math::geometric_distribution<> geoboost;    //fails here
geoboost = boost::math::geometric_distribution<double>(0.1);

printf("%f",boost::math::pdf(geoboost, 0.5));

    return 0;
}

Here I get:

main.cpp:18:39: error: no matching function for call to ‘boost::math::geometric_distribution<double>::geometric_distribution()’
 boost::math::geometric_distribution<> geoboost;
                                       ^

By inserting double for the template...

boost::math::geometric_distribution<double> geoboost;      //Error still here
geoboost = boost::math::geometric_distribution<double>(0.1);

The message doesn't get better:

main.cpp:18:45: error: no matching function for call to ‘boost::math::geometric_distribution<double>::geometric_distribution()’
 boost::math::geometric_distribution<double> geoboost;
                                             ^

The definitions of binomial_distribution and geometric_distribution aren't so different at all:

template <class RealType = double, class Policy = policies::policy<> >
    class binomial_distribution
    {
    public:
      typedef RealType value_type;
      typedef Policy policy_type;

      binomial_distribution(RealType n = 1, RealType p = 0.5) : m_n(n), m_p(p)

And

template <class RealType = double, class Policy = policies::policy<> >
    class geometric_distribution
    {
    public:
      typedef RealType value_type;
      typedef Policy policy_type;

      geometric_distribution(RealType p) : m_p(p)

How can this be? Why is one failing and the other one not?

Wandering Fool
  • 2,170
  • 3
  • 18
  • 48
Qohelet
  • 1,459
  • 4
  • 24
  • 41
  • Possible though, but would you mind explaining how I have to define it in my hpp then? And how should I initialize it in my cpp? – Qohelet Aug 09 '15 at 21:52

2 Answers2

3

Initialise the distribution explicitly, rather than default initialising it and then assigning to it, e g.

Gdist::Gdist(double theta) :
  theta(theta), geometricboost(theta) {
}
Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
2

The binomial distribution's parameters are defaulted- that is to say that boost::math::binomial_distribution<> binomialboost; is a legal member on it's own, as it can be default constructed.

The geometric distribution requires a parameter.

The problem is caused by you not properly initializing them and just leaving it to the default constructor, and then overwriting the value immediately. Simply initialize them properly in the initializer list and the problem will go away.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • So how should I define it in my hpp then? And how should I initialize it in my cpp? – Qohelet Aug 09 '15 at 21:49
  • The definition in the header is immaterial. In the source file, simply pass the parameters to the constructor in the initializer list. – Puppy Aug 09 '15 at 21:50
  • Like this: `geometricboost = boost::math::geometric_distribution(theta);` Gives me a `error: missing template arguments before ‘(’ token` and also `no matching function for call to ‘boost::math::geometric_distribution::geometric_distribution()’` – Qohelet Aug 09 '15 at 21:57
  • 1
    @Qohelet You use an initailizer list, see e.g. [this](http://stackoverflow.com/questions/1598967/benefits-of-initialization-lists) – nos Aug 09 '15 at 22:01
  • Got it! Many thanks! – Qohelet Aug 09 '15 at 22:04