I created a C++ templated "sample" function which uses Boost random number generators to sample from any object that provides a multinomial distribution as an iterable object.
/** Sample a value from a multinomial law with coefficient of modalities provided */
template<typename T>
int sample(const T& proportion)
{
boost::random::uniform_real_distribution<> uni(0.,
1.);
boost::variate_generator<boost::random::mt19937&,
boost::random::uniform_real_distribution<> > generator(rng_,
uni);
Real x = generator();
Real cumProb = 0.; // cumulative probability
int index = 0;
for(typename T::const_iterator it = proportion.begin();
it != proportion.end();
++it)
{
cumProb += *it;
if (x < cumProb)
{
return index;
}
++index;
}
return -1; // to accelerate sampling, no check have been computed on modalities to verify that is it actually a probability distribution
};
When I call this using an Eigen vector for example (on which I have added an iterator), I get the following error in Valgrind:
==4917== Conditional jump or move depends on uninitialised value(s)
==4917== at 0xD7B0A3C: int mixt::MultinomialStatistic::sample<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false> >(Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false> const&) (mixt_MultinomialStatistic.h:76)
==4917== by 0xD7B0538: mixt::ClassSampler::sampleIndividual(int) (mixt_ClassSampler.cpp:63)
==4917== by 0xD7ADBE6: mixt::IMixtureComposerBase::sStep(int) (mixt_IMixtureComposerBase.cpp:94)
==4917== by 0xD7ADAF0: mixt::IMixtureComposerBase::sStep() (mixt_IMixtureComposerBase.cpp:68)
==4917== by 0xD7AC3DE: mixt::SemStrategy::run() (mixt_SEMStrategy.cpp:83)
==4917== by 0xD74F742: mixtCompCluster(Rcpp::Vector<19, Rcpp::PreserveStorage>, Rcpp::Vector<19, Rcpp::PreserveStorage>, int, double) (mixtCompCluster.cpp:123)
==4917== by 0xD749A61: RMixtComp_mixtCompCluster (RcppExports.cpp:18)
==4917== by 0x4F0ADE7: ??? (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F4981A: Rf_eval (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F4B92F: ??? (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F49622: Rf_eval (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F4A93E: Rf_applyClosure (in /usr/lib/R/lib/libR.so)
==4917==
The line mixt_MultinomialStatistic.h:76 corresponds to if (x < cumProb)
. It seems to me that both x and cumProb are defined at this point. How can I debug this ?
EDIT
As suggested by Beta in the comments, I added the following dummy code:
if (x < 1000.)
{}
if (-1000. < cumProb)
{}
if (x < cumProb)
{ ...
And I still get the error reported for the line if (x < cumProb)
.
When lauching valgrind with the option --track-origins=yes
, I get the following indication
==10074== Uninitialised value was created by a stack allocation
pointing to the instruction:
cumProb += *it;
I faced a somewhat similar question when searching my (unit test) code for uninitialized values and found out that Eigen matrices' (and vectors') values don't get initialized in their default constructors. I had such a vector in a struct and eventually got rid of the problem using a statement à la:
struct MyStruct {
Eigen::Vector2f myVector;
};
MyStruct myStruct{}; // Does not initialize myVector's values!
std::cout << "myVec = " << myStruct.myVector << std::endl; // Causes valgrind to warn about uninitialized variables
myStruct.myVector = Eigen::Vector2f(0.0f, 0.0f);
std::cout << "myVecInit = " << myStruct.myVector << std::endl; // No valgrind warning
Note that I had a hard time debugging this because when launching the unit test with gdb the vector would happen to contain zeros though uninitialized.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.