simpleton
simpleton

Reputation: 31

C++ Function Polymorphism - Unexpected Behaviour

I'm quite new to C++ and come from a Python background. Basically, I want a collection of "State" objects, each of which should have its own "Distribution" object. Different states can have different types of distribution (uniform, normal, etc.). I want to be able to evaluate the probability of some observation passed to a state without worrying about what that state's distribution is. It occurs to me that's what polymorphism is for. However, if I calculate the PDF for an observation, then change one of the distribution parameters (say, the mean) then I still get the same answer from the PDF function call. Clearly there is some issue of scope, updating, etc. that I'm not understanding; I would be very grateful for an explanation. I've produced a shortened snippet of code which I hope describes my question. While I had a look for similar issues, I couldn't find anything that quite answered my question - nevertheless, sincere apologies if this is a repeat post.

#include <iostream>
#include <math.h>

class Distribution{
/*polymorphic class for probability distributions */
    protected:
        Distribution( double, double );
    public:
        double param1, param2;
        virtual double pdf( double ) = 0;
};

class NormalDistribution: public Distribution {
/*derived class for a normal distribution */

    public:
        NormalDistribution( double, double );
        double param1, param2;
        double pdf( double x ){
            return ( 1.0/sqrt( 2.0*pow( param2, 2.0 )*M_PI ) )*exp( -pow( x - param1 , 2.0 )/( 2.0*pow( param2, 2.0 ) ) );
        }
};

Distribution::Distribution( double x, double y ){
    param1 = x;
    param2 = y;
}

NormalDistribution::NormalDistribution( double x, double y ): Distribution( x, y ) {
    param1 = x;
    param2 = y;
}

class State {
    /*simple class for a state object that houses a state's distribution */
    public:
            Distribution *dist;
        State( Distribution * x){
            dist = x;
        };
};

class myBoringClass{
    public:
        int x;
        int myBoringFunction(int y){
            return x*y;
        }
};

int main(){

    //For polymorphic NormalDistribution class
    NormalDistribution nd2(0.0,1.0);
    NormalDistribution *np = &nd2;
    State myState(np);

    //Set an initial mean, std and evaluate the probability density function (PDF) at x=0.5
    std::cout << "PDF evaluated at x=0.5, which should be 0.352: " << myState.dist -> pdf(0.5) << std::endl; //this gives the right answer, which is 0.352

    //Now change the mean and evaluate the PDF again
    myState.dist -> param1 = 2.0;
    std::cout << "PDF evaluated at x=0.5, which should be 0.1295: "<< myState.dist -> pdf(0.5) << std::endl; //this gives the wrong answer.  Should give 0.1295, but instead gives 0.352.

    //For myBoringClass, which works as I would expect
    myBoringClass boringClass;
    boringClass.x = 4;
    std::cout << "Should be 2*4: " << boringClass.myBoringFunction(2) << std::endl; //prints 8
    boringClass.x = 5;
    std::cout << "Should be 2*5: " << boringClass.myBoringFunction(2) << std::endl; //prints 10

    return 0;
}

Upvotes: 1

Views: 64

Answers (1)

Rudolfs Bundulis
Rudolfs Bundulis

Reputation: 11954

You have member variables with the same name in the base (Distribution) and derived (NormalDistribution) classes. Remove the double param1, param2; from NormalDistribution.

Upvotes: 5

Related Questions