aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/AggregateFunctions/AggregateFunctionMeanZTest.cpp
blob: 99d0d0063d59f3b1bfef7efddf1284284e1f560d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <AggregateFunctions/AggregateFunctionFactory.h>
#include <AggregateFunctions/AggregateFunctionMeanZTest.h>
#include <AggregateFunctions/FactoryHelpers.h>
#include <AggregateFunctions/Moments.h>


namespace ErrorCodes
{
    extern const int BAD_ARGUMENTS;
    extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
}


namespace DB
{
struct Settings;

namespace
{

struct MeanZTestData : public ZTestMoments<Float64>
{
    static constexpr auto name = "meanZTest";

    std::pair<Float64, Float64> getResult(Float64 pop_var_x, Float64 pop_var_y) const
    {
        Float64 mean_x = getMeanX();
        Float64 mean_y = getMeanY();

        /// z = \frac{\bar{X_{1}} - \bar{X_{2}}}{\sqrt{\frac{\sigma_{1}^{2}}{n_{1}} + \frac{\sigma_{2}^{2}}{n_{2}}}}
        Float64 zstat = (mean_x - mean_y) / getStandardError(pop_var_x, pop_var_y);

        if (unlikely(!std::isfinite(zstat)))
            return {std::numeric_limits<Float64>::quiet_NaN(), std::numeric_limits<Float64>::quiet_NaN()};

        Float64 pvalue = 2.0 * boost::math::cdf(boost::math::normal(0.0, 1.0), -1.0 * std::abs(zstat));

        return {zstat, pvalue};
    }
};

AggregateFunctionPtr createAggregateFunctionMeanZTest(
    const std::string & name, const DataTypes & argument_types, const Array & parameters, const Settings *)
{
    assertBinary(name, argument_types);

    if (parameters.size() != 3)
        throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "Aggregate function {} requires three parameter.", name);

    if (!isNumber(argument_types[0]) || !isNumber(argument_types[1]))
        throw Exception(ErrorCodes::BAD_ARGUMENTS, "Aggregate function {} only supports numerical types", name);

    return std::make_shared<AggregateFunctionMeanZTest<MeanZTestData>>(argument_types, parameters);
}

}

void registerAggregateFunctionMeanZTest(AggregateFunctionFactory & factory)
{
    factory.registerFunction("meanZTest", createAggregateFunctionMeanZTest);
}

}