Loading...
Searching...
No Matches
wdm.hpp
1// Copyright © 2020 Thomas Nagler
2//
3// This file is part of the wdm library and licensed under the terms of
4// the MIT license. For a copy, see the LICENSE file in the root directory
5// or https://github.com/tnagler/wdm/blob/master/LICENSE.
6
7#pragma once
8
9#include "wdm/bbeta.hpp"
10#include "wdm/cxi.hpp"
11#include "wdm/hoeffd.hpp"
12#include "wdm/ktau.hpp"
13#include "wdm/methods.hpp"
14#include "wdm/nan_handling.hpp"
15#include "wdm/prho.hpp"
16#include "wdm/srho.hpp"
17
19namespace wdm {
20
48inline double
49wdm(std::vector<double> x,
50 std::vector<double> y,
51 std::string method,
52 std::vector<double> weights = std::vector<double>(),
53 bool remove_missing = true,
54 std::vector<int> seeds = std::vector<int>())
55{
56 utils::check_sizes(x, y, weights);
57 // na handling
58 if (utils::preproc(x, y, weights, method, remove_missing) == "return_nan")
59 return std::numeric_limits<double>::quiet_NaN();
60
61 if (methods::is_hoeffding(method))
62 return impl::hoeffd(x, y, weights);
63 if (methods::is_kendall(method))
64 return impl::ktau(x, y, weights);
65 if (methods::is_pearson(method))
66 return impl::prho(x, y, weights);
67 if (methods::is_spearman(method))
68 return impl::srho(x, y, weights);
69 if (methods::is_blomqvist(method))
70 return impl::bbeta(x, y, weights);
71 if (methods::is_chatterjee(method)) {
72 auto xi_and_std = impl::cxi(x, y, weights, false, "max", seeds);
73 return std::get<0>(xi_and_std);
74 }
75 throw std::runtime_error("method not implemented.");
76}
77
106{
107public:
108 Indep_test() = delete;
109
131 Indep_test(std::vector<double> x,
132 std::vector<double> y,
133 std::string method,
134 std::vector<double> weights = std::vector<double>(),
135 bool remove_missing = true,
136 std::string alternative = "two-sided",
137 std::vector<int> seeds = std::vector<int>(),
138 bool y_continuous = true)
139 : method_(method)
140 , alternative_(alternative)
141 {
142 utils::check_sizes(x, y, weights);
143 if (utils::preproc(x, y, weights, method, remove_missing) == "return_nan") {
144 n_eff_ = utils::effective_sample_size(x.size(), weights);
145 estimate_ = std::numeric_limits<double>::quiet_NaN();
146 statistic_ = std::numeric_limits<double>::quiet_NaN();
147 p_value_ = std::numeric_limits<double>::quiet_NaN();
148 } else {
149 n_eff_ = utils::effective_sample_size(x.size(), weights);
150 if (methods::is_chatterjee(method)) {
151 auto stats = impl::cxi(x, y, weights, true, "max", seeds, y_continuous);
152 estimate_ = std::get<0>(stats);
153 statistic_ =
154 (std::get<3>(stats) - std::get<2>(stats)) / std::get<1>(stats);
155 } else {
156 estimate_ = wdm(x, y, method, weights, false);
157 statistic_ =
158 compute_test_stat(estimate_, method, n_eff_, x, y, weights);
159 }
160 p_value_ = compute_p_value(statistic_, method, alternative, n_eff_);
161 }
162 }
163
165 std::string method() const { return method_; }
166
168 std::string alternative() const { return alternative_; }
169
171 double n_eff() const { return n_eff_; }
172
174 double estimate() const { return estimate_; }
175
177 double statistic() const { return statistic_; }
178
180 double p_value() const { return p_value_; }
181
182private:
183 inline double compute_test_stat(double estimate,
184 std::string method,
185 double n_eff,
186 const std::vector<double>& x,
187 const std::vector<double>& y,
188 const std::vector<double>& weights)
189 {
190 // prevent overflow in atanh
191 if (estimate >= 1.0)
192 estimate = 1 - 1e-12;
193 if (estimate <= -1.0)
194 estimate = -1 + 1e-12;
195
196 double stat;
197 if (methods::is_hoeffding(method)) {
198 stat = estimate / 30.0 + 1.0 / (36.0 * n_eff);
199 } else if (methods::is_kendall(method)) {
200 stat = estimate * impl::ktau_stat_adjust(x, y, weights);
201 } else if (methods::is_pearson(method)) {
202 stat = std::atanh(estimate) * std::sqrt(n_eff - 3);
203 } else if (methods::is_spearman(method)) {
204 stat = std::atanh(estimate) * std::sqrt((n_eff - 3) / 1.06);
205 } else if (methods::is_blomqvist(method)) {
206 stat = std::atanh(estimate) * std::sqrt(n_eff);
207 } else {
208 throw std::runtime_error("method not implemented.");
209 }
210
211 return stat;
212 }
213
214 inline double compute_p_value(double statistic,
215 std::string method,
216 std::string alternative,
217 double n_eff = 0.0)
218 {
219 double p_value;
220 if (methods::is_hoeffding(method)) {
221 if (n_eff == 0.0)
222 throw std::runtime_error("must provide n_eff for method 'hoeffd'.");
223 if (alternative != "two-sided")
224 throw std::runtime_error(
225 "only two-sided test available for Hoeffding's D.");
226 p_value = impl::phoeffb(statistic, n_eff);
227 } else {
228 if (alternative == "two-sided") {
229 p_value = 2 * utils::normalCDF(-std::abs(statistic));
230 } else if (alternative == "less") {
231 p_value = utils::normalCDF(statistic);
232 } else if (alternative == "greater") {
233 p_value = 1 - utils::normalCDF(statistic);
234 } else {
235 throw std::runtime_error("alternative not implemented.");
236 }
237 }
238
239 return p_value;
240 }
241
242 std::string method_;
243 std::string alternative_;
244 double n_eff_;
245 double estimate_;
246 double statistic_;
247 double p_value_;
248};
249
250}
Definition wdm.hpp:106
double p_value() const
Returns the asymptotic p-value.
Definition wdm.hpp:180
Indep_test(std::vector< double > x, std::vector< double > y, std::string method, std::vector< double > weights=std::vector< double >(), bool remove_missing=true, std::string alternative="two-sided", std::vector< int > seeds=std::vector< int >(), bool y_continuous=true)
Definition wdm.hpp:131
std::string method() const
Returns the requested method name.
Definition wdm.hpp:165
double estimate() const
Returns the estimated dependence measure.
Definition wdm.hpp:174
double statistic() const
Returns the method-specific transformed test statistic.
Definition wdm.hpp:177
double n_eff() const
Returns Kish's effective sample size after missing-value removal.
Definition wdm.hpp:171
std::string alternative() const
Returns the requested alternative hypothesis.
Definition wdm.hpp:168
Weighted dependence measures.
Definition wdm.hpp:19