double stdev_helper(const VD& data)
{
    double sumsqr = std::inner_product(data.constBegin(), data.constEnd(), data.constBegin(), 0);
    double sum = std::accumulate(data.constBegin(), data.constEnd(), 0);
    const int ct = data.size();
    return sqrt((sumsqr - sum * sum / ct) / (ct - 1));
}
void MLComputeTest::dotProduct_benchmark_inner_product()
{
    VD data;
    data.resize(10000);
    std::iota(data.begin(), data.end(), 1);
    QBENCHMARK
    {
        std::inner_product(data.constBegin(), data.constEnd(), data.constBegin(), 0);
    }
}
void MLComputeTest::mean_benchmark_alternative()
{
    VD data;
    data.resize(10000);
    std::iota(data.begin(), data.end(), 1);
    QBENCHMARK
    {
        (void)(std::accumulate(data.constBegin(), data.constEnd(), 0) / data.size());
    }
}
void MLComputeTest::sum_benchmark_accumulate()
{
    VD data;
    data.resize(10000);
    std::iota(data.begin(), data.end(), 1);
    QBENCHMARK
    {
        std::accumulate(data.constBegin(), data.constEnd(), 0);
    }
}
double correlation_helper(const VD& data1, const VD& data2)
{
    if (data1.size() != data2.size())
        return 0;
    const size_t N = data1.size();
    const double sum1 = std::accumulate(data1.constBegin(), data1.constEnd(), 0);
    const double mean1 = sum1 / N;
    const double sumsqr1 = std::inner_product(data1.constBegin(), data1.constEnd(), data1.constBegin(), 0);
    const double stdev1 = N > 1 ? sqrt((sumsqr1 - sum1 * sum1 / N) / (N - 1)) : 0;

    const double sum2 = std::accumulate(data2.constBegin(), data2.constEnd(), 0);
    const double mean2 = sum2 / N;
    const double sumsqr2 = std::inner_product(data2.constBegin(), data2.constEnd(), data2.constBegin(), 0);
    const double stdev2 = sqrt((sumsqr2 - sum2 * sum2 / N) / (N - 1));
    if (!stdev1 || !stdev2)
        return 0;
    VD Y1;
    Y1.reserve(N);
    std::transform(data1.constBegin(), data1.constEnd(), Y1.begin(), [mean1, stdev1](double val) { return (val - mean1)/stdev1; });
    VD Y2;
    Y2.reserve(N);
    std::transform(data2.constBegin(), data2.constEnd(), Y2.begin(), [mean2, stdev2](double val) { return (val - mean2)/stdev2; });
    return std::inner_product(Y1.constBegin(), Y1.constEnd(), Y2.constBegin(), 0);
}