我目前正在努力使用以下代码,其目的是实现可变参数可变参数模板模板:
template
<
template <typename... HeadArgs> class Head,
template <typename... TailArgs> class...
>
struct join<Head<typename HeadArgs...>, Head<typename TailArgs...>...>
{
typedef Head<typename HeadArgs..., typename TailArgs......> result;
};
Run Code Online (Sandbox Code Playgroud)
理想情况下,我可以使用此模板元函数来实现以下功能:
template <typename...> struct obj1 {};
template <typename...> struct obj2 {};
typedef join
<
obj1<int, int, double>,
obj1<double, char>,
obj1<char*, int, double, const char*>
>::result new_obj1;
typedef join
<
obj2<int, int, double>,
obj2<double, char>,
obj2<char*, int, double, const char*>
>::result new_obj2;
/* This should result in an error, because there are
different encapsulating objects …Run Code Online (Sandbox Code Playgroud) 我有兴趣在直方图中找到大致相似的局部最小值

我想找到109.258的局部最小值,最简单的方法是确定109.258处的计数数是否低于某些区间内的平均计数(包括109.258).它确定了这个间隔对我来说是最困难的部分.
至于这个数据的来源,它是一个100个不均匀宽度的直方图.每个bin都有一个值(显示在x轴上),以及落入该bin的样本计数(显示在y轴上).我想要做的是找到分割直方图的"最佳"位置.分割的每一侧沿二叉树向下传播,作为分类算法的一部分.
我认为我最好的做法是尝试使用Levenberg-Marquardt算法之类的方法拟合这个直方图的曲线,然后比较局部最小值以找到"最佳"."最佳"的适当度量将包括对该分裂的重要性的一些指示,其被测量为左侧区间中的平均计数与右侧区间中的计数的平均值之间的差异,然后可能如果有意义的话,将每个差异与所包括的计数数量相加以得到"最佳"的复合测量值.
无论哪种方式,算法的计算复杂性都不是一个大问题,100个箱子大约是我期望遇到的最大数量.然而,这种计算将对于每个样品进行一次,因此保持它相对于线性的二进制位的数目将当然是理想的.
顺便说一下,我正在用C++做所有事情,并且使用了boost库和STL,因此在这方面没有任何限制.
任何有关最佳实践的想法或见解将不胜感激!
我正在努力在C++中实现多元Gaussian的概率密度函数,并且我坚持如何最好地处理维> 2的情况.
高斯的pdf可以写成

其中(A)'或''表示通过从x的所有元素中减去均值而创建的'矩阵'的转置.在该等式中,k是我们具有的维数,sigma表示协方差矩阵,其是akxk矩阵.最后,| X | 表示矩阵X的行列式.
在单变量情况下,实施pdf是微不足道的.即使在双变量(k = 2)的情况下,它也是微不足道的.但是,当我们超过两个维度时,实施起来要困难得多.
在双变量情况下,我们有

其中rho是x和y之间的相关性,相关性等于

在这种情况下,我可以使用Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>实现第一个方程,或者只使用第二个方程自己计算所有内容,而不会受益于Eigen的简化线性代数接口.
我尝试多变量情况的想法可能首先将上述方程扩展到多变量情形

同

我的问题是:
boost::multi_array作为n维数组,或者我应该尝试利用Eigen?我正在努力实现直方图,其中一个关键点是直方图箱的快速合并.因为我没有关于直方图近似的数据集的先验知识,所以我需要提出一种方法,在我超过最大数量的箱之后快速合并相邻的箱.
因此,作为一个例子,如果您使用五个直方图箱来近似数据流23,19,10,16,36,2,9,32,30,45,那么您将读入前五个元素,获得:
(23,1),(19,1),(10,1),(16,1),(36,1)
添加bin(2,1)会导致问题,因为我们已经超过了最大的bin数.因此,我们添加(2,1)并合并两个最接近的二进制位 - (16,1)和(19,1) - 以获得一个替换这两个的新bin(17.5,2).
对于剩余的直方图重复此方法,可以得到最终输出:
(2,1),(9.5,2),(19.33,3),(32.67,3),(45,1).
在不考虑复杂性问题的情况下实现这一点是微不足道的.但是,我真的很关心为大数据集优化它,因为我的"琐碎"实现最终需要15秒才能在100,000高斯分布值的流上运行.
我目前的想法是使用boost :: multi_index来跟踪我的HistogramBin结构,定义为:
struct HistogramBin
{
double bin;
unsigned long count;
bool isNull;
HistogramBin(double x, bool n = false)
: bin(x), count(1), isNull(n) {}
bool operator<(const HistogramBin &other) const
{ return (bin < other.bin); }
// Merges other with this histogram bin
// E.g., if you have (2.0,1) and (3.0,2), you'd merge them into (2.67,3)
void merge(const HistogramBin &other)
{
unsigned long old_count = count;
count += other.count;
bin …Run Code Online (Sandbox Code Playgroud) 这个问题稍微延伸了这里回答的问题.我正在努力重新实现本文第2.1节中的直方图近似版本,并且我想在再次开始此过程之前连接所有的鸭子.上次,我用过boost::multi_index,但性能并不是最大的,我想避免插入/发现复杂性的桶数量的对数std::set.由于我正在使用的直方图的数量(随机森林中随机树的每个叶节点每个特征一个),计算复杂度必须尽可能接近常数.
用于实现直方图的标准技术涉及将输入实际值映射到箱号.要做到这一点,一种方法是:
这适用于具有统一箱尺寸的直方图,并且非常有效.然而,上面链接的论文的2.1节提供了没有统一的箱尺寸的直方图算法.
另一个问题是,简单地将输入实际值乘以一个因子,并使用得到的产品作为索引,以负数表示失败.为了解决这个问题,我考虑在数组中的某处识别一个'0'bin.这个箱子将以0.0为中心; 它上面/下面的垃圾箱可以使用刚才解释的相同的乘法和平面方法计算,稍作修改,将地板产品加到两个或根据需要减去两个.
然后,这引出了合并的问题:本文中的算法合并了两个最接近的箱,从中心到中心测量.在实践中,这会产生"锯齿状"直方图近似值,因为某些箱子会有非常大的数量,而其他箱子则不会.当然,这是由于不均匀尺寸的箱,并且不会导致任何精度损失.然而,如果我们试图将非均匀尺寸的箱子标准化以制造均匀,则会发生精度损失.这是因为假设m/2样本落在bin中心的左侧和右侧,其中m = bin计数.我们可以将每个bin建模为高斯,但这仍然会导致精度损失(尽管很小)
这就是我现在被困住的地方,导致了这个主要问题:实现直方图接受流数据并将每个样本存储在统一大小的容器中的最佳方法是什么?