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;
}
You have member variables with the same name in the base (Distribution) and derived (NormalDistribution) classes. Remove the double param1, param2; from NormalDistribution.
Related
class equation
{
public :
int k;
int l;
int t;
float x1_value;
float x2_value;
float b1 = sqrt(l^2 -4*k*t);
float equation1;
equation();
~equation();
};
float void equation::equation1() {
if (b1 == 0)
{
float x1_value = -l/2*k;
cout << " joongen. " <<x1_value <<endl;
}
else if (b1 > 0)
{
float x1_value = ((-l + sqrt(b1) / (2*k));
float x2_value = ((-l - sqrt(b1) / (2*k));
cout << "x is 2"<< x1_value < " x 2 is "<< x2_value <<endl;
}
else
{
cout <<"imagine number ."<<endl;
}
return (0);
};
The code produces this error:
error: two or more data types in declaration of 'equation1'
float void equation::equation1() {
^
I can make out two problems.
First you define equation1 as a member variable with type float. You might want to change that into a function declaration.
// ...
float equation1();
// ...
The second problem is pointed out in the comments. If you implement your function, you should only use one return type. As I can only guess, what return type you would really want, I take float, since it is in your faulty function declaration.
// ...
float equation::equation1() {
// ...
}
// ...
One extra thing, that disturbs me every time I see someone who is new with C++. Please, please, please, don't use using namespace std;. I assume you do so, because of the missing std::. You open up an fastly huge namespace. You may end up defining a function, with the same name and parameters and encounter a very cryptic error, which is nearly impossible to figure out.
A common task in programming is to process data on the fly and, when all data are collected, do some post processing. A simple example for this would be the computation of the average (and other statistics), where you can have a class like this
class Statistic {
public:
Statistic() : nr(0), sum(0.0), avg(0.0) {}
void add(double x) { sum += x; ++nr; }
void process() { avg = sum / nr; }
private:
int nr;
double sum;
double avg;
};
A disadvantage with this approach is, that we always have to remember to call the process() function after adding all the data. Since in C++ we have things like RAII, this seems like a less than ideal solution.
In Ruby, for example, we can write code like this
class Avg
attr_reader :avg
def initialize
#nr = 0
#sum = 0.0
#avg = nil
if block_given?
yield self
process
end
end
def add(x)
#nr += 1
#sum += x.to_f
end
def process
#avg = #sum / #nr
end
end
which we then can call like this
avg = Avg.new do |a|
data.each {|x| a.add(x)}
end
and the process method is automatically called when exiting the block.
Is there an idiom in C++ that can provide something similar?
For clarification: this question is not about computing the average. It is about the following pattern: feeding data to an object and then, when all the data is fed, triggering a processing step. I am interested in context-based ways to automatically trigger the processing step - or reasons why this would not be a good idea in C++.
"Idiomatic average"
I don't know Ruby but you can't translate idioms directly anyhow. I know that calculating the average is just an example, so lets see what we can get from that example...
Idiomatic way to caclulate sum, and average of elements in a container is std::accumulate:
std::vector<double> data;
// ... fill data ...
auto sum = std::accumulate( a.begin(), a.end() , 0.0);
auto avg = sum / a.size();
The building blocks are container, iterator and algorithms.
If you do not have elements to be processed readily available in a container you can still use the same algorithms, because algorithms only care about iterators. Writing your own iterators requires a bit of boilerplate. The following is just a toy example that calcualtes average of results of calling the same function a certain number of times:
#include <numeric>
template <typename F>
struct my_iter {
F f;
size_t count;
my_iter(size_t count, F f) : count(count),f(f) {}
my_iter& operator++() {
--count;
return *this;
}
auto operator*() { return f(); }
bool operator==(const my_iter& other) const { return count == other.count;}
};
int main()
{
auto f = [](){return 1.;};
auto begin = my_iter{5,f};
auto end = my_iter{0,f};
auto sum = std::accumulate( begin, end, 0.0);
auto avg = sum / 5;
std::cout << sum << " " << avg;
}
Output is:
5 1
Suppose you have a vector of paramters for a function to be called, then calling std::accumulate is straight-forward:
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
auto f = [](int x){return x;};
std::vector<int> v = {1,2,5,10};
auto sum = std::accumulate( v.begin(), v.end(), 0.0, [f](int accu,int add) {
return accu + f(add);
});
auto avg = sum / 5;
std::cout << sum << " " << avg;
}
The last argument to std::accumulate specifies how the elements are added up. Instead of adding them up directly I add up the result of calling the function. Output is:
18 3.6
For your actual question
Taking your question more literally and to answer also the RAII part, here is one way you can make use of RAII with your statistic class:
struct StatisticCollector {
private:
Statistic& s;
public:
StatisticCollector(Statistic& s) : s(s) {}
~StatisticCollector() { s.process(); }
};
int main()
{
Statistic stat;
{
StatisticCollector sc{stat};
//for (...)
// stat.add( x );
} // <- destructor is called here
}
PS: Last but not least there is the alternative to just keep it simple. Your class definition is kinda broken, because all results are private. Once you fix that, it is kinda obvious that you need no RAII to make sure process gets called:
class Statistic {
public:
Statistic() : nr(0), sum(0.0), avg(0.0) {}
void add(double x) { sum += x; ++nr; }
double process() { return sum / nr; }
private:
int nr;
double sum;
};
This is the right interface in my opinion. The user cannot forget to call process because to get the result they need to call it. If the only purpose of the class is to accumulate numbers and process the result it should not encapsulate the result. The result is for the user of the class to store.
hello :) so this is my first time writing a c++ program, im currently using code::blocks tho im pretty sure the issue ive got probably isnt related to the program at all but anyway...
i want to write a simple code, where two "boxes" are created and their volume is calculated and printed on the terminal. ive written this code on a single cpp file:
#include<iostream>
using namespace std;
class Box
{
public:
double length;
double breadth;
double height;
Box(double l, double b, double h)
{
l=length;
b=breadth;
h=height;
}
};
int main()
{
double volume = 0.0;
Box BoxA(2.0, 3.2, 6.0);
Box BoxB(2.5, 4.0, 5.0);
volume = BoxA.length * BoxA.breadth * BoxA.height;
cout << "Box a volume = " << volume <<endl;
volume = BoxB.length * BoxB.breadth * BoxB.height;
cout << "Box b volume = " << volume <<endl;
return 0;
}
so i build and run this thing, no errors but the results i get is this:
box a volume = -0
//and sometimes =0
box b volume = 0
but i dont understand what is wrong here. shouldnt the results be a=38.4 and b=50.0? what am i doing wrong here?
Your constructor assigns values to the passed arguments.
Try this instead:
class Box
{
public:
double length;
double breadth;
double height;
Box(double l, double b, double h)
{
length=l;
breadth=b;
height=h;
}
};
As others have mentioned, there are other improvements that can be made regarding initializer lists and the use of using, and the study of programming in general and c++ in particular is an ongoing journey, never a destination, but this is the direct fix for the immediate problem.
The usual way to write constructors is with initializer lists:
Box(double l, double b, double h) : length(l), breadth(b), height(h)
{
}
This prevent exactly the same error that you had, exchanging the argument and member. If you tried to write : l(length), the compiler would have told you straight away that l is not a member of Box.
You don't even need separate names with initializer lists:
Box(double length, double breadth, double height)
: length(length), breadth(breadth), height(height)
{ }
This does initialize Box::height with the argument height.
#include<iostream>
class Box
{
public:
double length;
double breadth;
double height;
Box(double l, double b, double h)
{
length = l; // assign to the member variables, not parameters
breadth = b;
height = h;
}
};
int main(void)
{
double volume = 0.0;
Box BoxA(2.0, 3.2, 6.0);
Box BoxB(2.5, 4.0, 5.0);
volume = BoxA.length * BoxA.breadth * BoxA.height;
std::cout << "Box a volume = " << volume << std::endl;
volume = BoxB.length * BoxB.breadth * BoxB.height;
std::cout << "Box b volume = " << volume << std::endl;
return 0;
}
This is the refined version of your code. Note that you shouldn't use namespace std. That's a bad programming practice.
I'm working on operators in C++ now, but i have one problem. Well I'm trying to overloard int/float operators, I have 2 variables in class
class Zespolona{
public:
float re;
float im;
}
I've done all of my operators but when i do
operator int const(){
this->re = (int)this->re;
this->im = (int)this->im;
return *this;
}
then it gets an infinite loop.
My main
int main(){
Zespolona z1;
z1.re = 1.2;
z1.im = 34.9;
z1 = (int)z1;
cout << z1 << endl;
}
What can i do, to get int of two of those variables?
I am not completely sure what you are trying to achieve. I am guessing one of the following two possibilities:
1) Covert the two floats of your class (re, im) into integers:
This is rather simple. Since the two members are public you can access them directly:
#include <iostream>
int main()
{
Zespolona Z1;
Z1.re = 1.2;
Z1.im = 34.9;
std::cout << "Re: " << (int) Z1.re << std::endl;
std::cout << "Im: " << (int) Z1.im << std::endl;
return 0;
}
The output of this program should be:
Re: 1
Im: 34
Note: When you convert a float to an integer everything after the decimal dot is omitted (at least that is the behavior using g++ under Ubuntu).
If you want the two floats to be private or protected you would have to create methods like int GetRe() and int GetIm().
2) Convert the two floats of your class (re, im) into one integer using the integer conversion operator operator int const(). This operator has to return exactly one int. For the following example I decided to return the absolute value (magnitude) of the complex number (since your members are called re and im I am guessing the class is used for complex numbers):
class Zespolona
{
public:
float re;
float im;
operator int const()
{
return (int) sqrt(re*re + im*im);
}
};
int main()
{
Zespolona Z1;
Z1.re = 1.2;
Z1.im = 34.9;
std::cout << "Z1: " << (int) Z1 << std::endl;
return 0;
}
The output should now be:
Z1: 34
Note: Again the correct (float) result 34.92... is converted into the integer 34.
The code you mentioned in your questions returns a reference to your class Zespolona when you try to convert it into int. Thus, the compiler again tries to convert that reference into an int. But all it gets is again a reference to Zespolona, and so on. Hence, you get an infinite loop.
I have a Base class Point (representing a 2D point in space) that is non-thread-safe for move operations; so I defined an inherited class LockedPoint that overrides 2 methods in the base class: moveTo and moveBy:
void Point::moveTo(float xPos, float yPos) {
x = xPos;
y = yPos;
}
void Point::moveBy(float xOff, float yOff) {
x += xOff;
y += yOff;
}
void LockedPoint::moveTo(float xPos, float yPos) {
MutGuard m(lock);
x = xPos;
y = yPos;
}
void LockedPoint::moveBy(float xOff, float yOff) {
MutGuard m(lock);
x += xOff;
y += yOff;
}
( where x and y = private member variables,
lock = a private mutex, and
MutGuard = typedef lock_guard<mutex> )
To visually see the problem with the "unlocked" Point, I wrote up a test routine:
void sleepForMS(long ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
void messWithPoint(Point& p, int type) {
float n = 1;
if (type) n *= -1;
for (long i = 0; i < 10000; i++) {
p.moveBy(n, n);
sleepForMS(rand() % (type ? 2 : 3));
if (i % 500 == 0)
std::cout << i << ":\t" << p << std::endl;
}
}
int main(int argc, char* argv[]) {
using namespace std;
Point p;
thread t1(messWithPoint, std::ref(p), 0);
sleepForMS(33);
thread t2(messWithPoint, std::ref(p), 1);
cout << "Started\n";
t1.join();
t2.join();
cout << p << endl;
}
With a Point, the resulting p is "corrupted", as expected (it should equal (0,0) by the end, and it doesn't). If I change p to a LockedPoint though, the base version of moveBy is still called (verified by print debugging).
I read up on method "overriding" (apparently more correctly called "method hiding"), and from what I understand, if the overriding method has the same signature as the base method, it hides the base version, and is called instead. Why then is the base method being called despite the 2 having the same signature? The only thing I can think of is because I'm specifying Point in messWithPoint's argument list, it's taking that literally and calling Point's version. If I change the signature to void messWithPoint(LockedPoint& p, int type), the resulting LockedPoint is (0,0), as expected. Shouldn't it "see" that the passed LockedPoint overrides the used method, and use the "least hidden" version?
If that's not how it works, is there a way to specify taking the base class, but having it use any available overridden versions?
The member functions are not virtual, so the functions in the class known at compile time are used.
However, for a simple class such as point, using virtual member functions or providing automatic mutual exclusion goes against the C++ idea of not paying for what you don't use.
Just copy points.