我创建了一个C ++模板化的“样本”函数,该函数使用Boost随机数生成器从任何提供多项分布的对象中作为可迭代对象进行采样。
/** 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
};
当我使用Eigen向量调用它时(我在其上添加了迭代器),我在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==
行mixt_MultinomialStatistic.h:76对应if (x < cumProb)
。在我看来,x和cumProb都是在这一点上定义的。我该怎么调试呢?
修改
正如Beta在评论中所建议的,我添加了以下虚拟代码:
if (x < 1000.)
{}
if (-1000. < cumProb)
{}
if (x < cumProb)
{ ...
我仍然收到行if (x < cumProb)
报告的错误。
当使用选项--track-origins=yes
推送valgrind时,我得到以下指示
==10074== Uninitialised value was created by a stack allocation
指着指示:
cumProb += *it;
答案 0 :(得分:0)
在我的(单元测试)代码中搜索未初始化的值时,我遇到了一个类似的问题,结果发现本征矩阵(和向量)的值未在其默认构造函数中初始化。我在结构中使用了这样的向量,最终使用语句à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
请注意,我很难调试这一点,因为当使用gdb启动单元测试时,向量虽然未初始化,但碰巧会包含零。