-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathBoostDistributions.i
422 lines (395 loc) · 16.1 KB
/
BoostDistributions.i
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
/**
* @file SWIG interface file for boost::math::distributions
*
*/
%module BoostDistributions
%include std_common.i
%include std_except.i
%{
#include <sstream>
#include <stdexcept>
#include <boost/version.hpp>
#define BOOST_VERSION_LESS_THAN(ver) (BOOST_VERSION < ver)
#include <boost/math/distributions.hpp>
namespace boost { namespace math {
template <int RequiredVersion, bool check_passed = !BOOST_VERSION_LESS_THAN(RequiredVersion)>
struct distribution_shim_t {
#define GEN_FUNC(func_name) \
template <class DistT, class ValueT> \
inline static typename DistT::value_type func_name(const DistT &dist, const ValueT &x){ \
return boost::math::func_name(dist, x); \
}
GEN_FUNC(pdf);
GEN_FUNC(hazard);
GEN_FUNC(chf);
#undef GEN_FUNC
#define GEN_FUNC(func_name) \
template <class DistT, class ValueT> \
inline static typename DistT::value_type func_name( \
const DistT &dist, const ValueT &x, const bool &is_complement = false){ \
return is_complement \
? boost::math::func_name(complement(dist, x)) \
: boost::math::func_name(dist, x); \
}
GEN_FUNC(cdf);
GEN_FUNC(quantile);
#undef GEN_FUNC
#define GEN_FUNC(func_name) \
template <class DistT> \
inline static typename DistT::value_type func_name(const DistT &dist){ \
return boost::math::func_name(dist); \
}
GEN_FUNC(mean);
GEN_FUNC(median);
GEN_FUNC(mode);
GEN_FUNC(standard_deviation);
GEN_FUNC(variance);
GEN_FUNC(skewness);
GEN_FUNC(kurtosis);
GEN_FUNC(kurtosis_excess);
#undef GEN_FUNC
#define GEN_FUNC(func_name) \
template <class DistT> \
inline static std::pair<typename DistT::value_type, typename DistT::value_type> \
func_name(const DistT &dist){ \
return boost::math::func_name(dist); \
}
GEN_FUNC(range);
GEN_FUNC(support);
#undef GEN_FUNC
};
template <int RequiredVersion>
struct distribution_shim_t<RequiredVersion, false> { // dummy
static const std::string err_msg(){
std::stringstream ss;
ss << "BOOST_VERSION(" << BOOST_VERSION
<< ") should be >= " << RequiredVersion;
return ss.str();
}
#define GEN_FUNC(func_name) \
template <class DistT, class ValueT> \
inline static typename DistT::value_type func_name(const DistT &dist, const ValueT &x){ \
throw std::logic_error(err_msg()); \
}
GEN_FUNC(pdf);
GEN_FUNC(hazard);
GEN_FUNC(chf);
#undef GEN_FUNC
#define GEN_FUNC(func_name) \
template <class DistT, class ValueT> \
inline static typename DistT::value_type func_name( \
const DistT &dist, const ValueT &x, const bool &is_complement = false){ \
throw std::logic_error(err_msg()); \
}
GEN_FUNC(cdf);
GEN_FUNC(quantile);
#undef GEN_FUNC
#define GEN_FUNC(func_name) \
template <class DistT> \
inline static typename DistT::value_type func_name(const DistT &dist){ \
throw std::logic_error(err_msg()); \
}
GEN_FUNC(mean);
GEN_FUNC(median);
GEN_FUNC(mode);
GEN_FUNC(standard_deviation);
GEN_FUNC(variance);
GEN_FUNC(skewness);
GEN_FUNC(kurtosis);
GEN_FUNC(kurtosis_excess);
#undef GEN_FUNC
#define GEN_FUNC(func_name) \
template <class DistT> \
inline static std::pair<typename DistT::value_type, typename DistT::value_type> \
func_name(const DistT &dist){ \
throw std::logic_error(err_msg()); \
}
GEN_FUNC(range);
GEN_FUNC(support);
#undef GEN_FUNC
};
template <class RealType, int RequiredVersion>
struct distribution_dummy_t {
typedef RealType value_type;
static const std::string err_msg(){
return distribution_shim_t<RequiredVersion, false>::err_msg();
}
distribution_dummy_t(){throw std::logic_error(err_msg());}
// static/member functions
#define GEN_FUNC_m(ret_type, fun_name) \
ret_type fun_name(...) const {throw std::logic_error(err_msg());}
#define GEN_FUNC_s(ret_type, fun_name) \
static ret_type fun_name(...){throw std::logic_error(err_msg());}
GEN_FUNC_m(RealType, x_max); // arcsine
GEN_FUNC_m(RealType, x_min); // arcsine
GEN_FUNC_m(RealType, success_fraction);
// bernoulli, binomial, geometric, negative_binomial
GEN_FUNC_m(RealType, alpha); // beta, non_central_beta
GEN_FUNC_m(RealType, beta); // beta, non_central_beta
GEN_FUNC_s(RealType, find_alpha); // beta
GEN_FUNC_s(RealType, find_beta); // beta
GEN_FUNC_s(RealType, find_lower_bound_on_p);
// binomial, geometric, negative_binomial
GEN_FUNC_s(RealType, find_maximum_number_of_trials);
// binomial, geometric, negative_binomial
GEN_FUNC_s(RealType, find_minimum_number_of_trials);
// binomial, geometric, negative_binomial
GEN_FUNC_s(RealType, find_upper_bound_on_p);
// binomial, geometric, negative_binomial
GEN_FUNC_m(RealType, trails); // binomial
GEN_FUNC_m(RealType, location);
// cauchy, extreme_value, inverse_gaussian,
// laplace, logistic, lognormal, normal, skew_normal
GEN_FUNC_m(RealType, scale);
// cauchy, extreme_value, gamma, inverse_chi_squared,
// inverse_gamma, inverse_gaussian, laplace, logistic,
// lognormal, normal, pareto, skew_normal, weibull
GEN_FUNC_s(RealType, find_degrees_of_freedom);
// chi_squared, non_central_chi_squared, students_t
GEN_FUNC_m(RealType, degrees_of_freedom);
// chi_squared, inverse_chi_squared, non_central_chi_squared,
// non_central_t, students_t
GEN_FUNC_m(RealType, lambda); // exponential
GEN_FUNC_m(RealType, degrees_of_freedom1); // fisher_f, non_central_f
GEN_FUNC_m(RealType, degrees_of_freedom2); // fisher_f, non_central_f
GEN_FUNC_m(RealType, shape);
// gamma, inverse_gamma, inverse_gaussian, pareto,
// skew_normal, weibull
GEN_FUNC_m(RealType, successes); // geometric, negative_binomial
GEN_FUNC_m(std::vector<RealType>, probabilities); // hyperexponential
GEN_FUNC_m(std::vector<RealType>, rates); // hyperexponential
GEN_FUNC_m(std::size_t, num_phases); // hyperexponential
GEN_FUNC_m(bool, check_params); // hypergeometric
GEN_FUNC_m(bool, check_x); // hypergeometric
GEN_FUNC_m(unsigned, defective); // hypergeometric
GEN_FUNC_m(unsigned, sample_count); // hypergeometric
GEN_FUNC_m(unsigned, total); // hypergeometric
GEN_FUNC_m(RealType, mean); // inverse_gaussian, poisson
GEN_FUNC_m(RealType, number_of_observations); // kolmogorov_smirnov
GEN_FUNC_m(RealType, non_centrality);
// non_central_beta, non_central_chi_squared, non_central_f,
// non_central_t
GEN_FUNC_s(RealType, find_non_centrality);
// non_central_chi_squared
GEN_FUNC_m(RealType, standard_deviation); // normal
GEN_FUNC_m(RealType, sigma); // rayleigh
GEN_FUNC_m(RealType, lower); // triangular, uniform
GEN_FUNC_m(RealType, mode); // triangular
GEN_FUNC_m(RealType, upper); // triangular, uniform
#undef GEN_FUNC_s
#undef GEN_FUNC_m
};
} }
using namespace boost::math;
%}
%include boost/version.hpp
%define INSTANTIATE(dist_name, type, class_name, min_ver)
%{
#if BOOST_VERSION_LESS_THAN(min_ver)
namespace boost{ namespace math{
template <class RealType = double, class Policy = policies::policy<> >
struct dist_name ## _distribution : public distribution_dummy_t<RealType, min_ver> { // dummy
dist_name ## _distribution(...) : distribution_dummy_t<RealType, min_ver>() {}
};
} }
#endif
%}
#if BOOST_VERSION >= min_ver
%include boost/math/distributions/ ## dist_name ## .hpp
#else
namespace boost{ namespace math{
template <class RealType = double, class Policy = policies::policy<> >
struct dist_name ## _distribution { // dummy
typedef RealType value_type;
dist_name ## _distribution();
};
} }
#endif
%typemap(out, fragment=SWIG_Traits_frag(type)) std::pair<type, type> {
%append_output(swig::from($1.first));
%append_output(swig::from($1.second));
}
%extend boost::math::dist_name ## _distribution {
%catches(std::logic_error) dist_name ## _distribution; // for ctor
%catches(std::logic_error, std::runtime_error); // for the following member functions
#define shim_t boost::math::distribution_shim_t<min_ver>
value_type pdf(const value_type &x) const {
return shim_t::pdf(*$self, x);
}
value_type cdf(const value_type &x, const bool &is_complement = false) const {
return shim_t::cdf(*$self, x, is_complement);
}
value_type quantile(const value_type &p, const bool &is_complement = false) const {
return shim_t::quantile(*$self, p, is_complement);
}
value_type hazard(const value_type &x) const {
return shim_t::hazard(*$self, x);
}
value_type chf(const value_type &x) const {
return shim_t::chf(*$self, x);
}
value_type mean() const {return shim_t::mean(*$self);}
value_type median() const {return shim_t::median(*$self);}
value_type mode() const {return shim_t::mode(*$self);}
value_type standard_deviation() const {return shim_t::standard_deviation(*$self);}
value_type variance() const {return shim_t::variance(*$self);}
value_type skewness() const {return shim_t::skewness(*$self);}
value_type kurtosis() const {return shim_t::kurtosis(*$self);}
value_type kurtosis_excess() const {return shim_t::kurtosis_excess(*$self);}
std::pair<value_type, value_type> range() const {return shim_t::range(*$self);}
std::pair<value_type, value_type> support() const {return shim_t::support(*$self);}
#undef shim_t
};
%template(class_name) boost::math:: ## dist_name ## _distribution<type, policies::policy<> >;
%enddef
%extend boost::math::cauchy_distribution {
%ignore mean;
%ignore standard_deviation;
%ignore variance;
%ignore skewness;
%ignore kurtosis;
%ignore kurtosis_excess;
};
%extend boost::math::non_central_beta_distribution {
%ignore skewness;
%ignore kurtosis;
%ignore kurtosis_excess;
};
// workaround for hyperexponential having RealT template parameter instead of RealType
%extend boost::math::hyperexponential_distribution {
%ignore hyperexponential_distribution(std::initializer_list<RealT>, std::initializer_list<RealT>);
%ignore hyperexponential_distribution(std::initializer_list<RealT>);
%typemap(out, fragment=SWIG_Traits_frag(RealT)) std::vector<RealT> {
for(typename $1_type::const_iterator it($1.begin()), it_end($1.end());
it != it_end; ++it){
%append_output(swig::from(*it));
}
}
%typemap(in, fragment=SWIG_Traits_frag(RealT)) const std::vector<RealT> & (std::vector<RealT> temp) {
#if defined(SWIGRUBY)
if(RB_TYPE_P($input, T_ARRAY)){
RealT v;
for(unsigned int i(0), i_end((unsigned int)RARRAY_LEN($input)); i < i_end; ++i){
VALUE val(RARRAY_AREF($input, i));
if(!SWIG_IsOK(swig::asval(val, &v))){break;}
temp.push_back(v);
}
}
#endif
$1 = &temp;
}
#if BOOST_VERSION >= 105700
hyperexponential_distribution(
const std::vector<RealT> &prob, const std::vector<RealT> &range){
return new hyperexponential_distribution(
prob.begin(), prob.end(), range.begin(), range.end());
}
hyperexponential_distribution(
const std::vector<RealT> &range){
return new hyperexponential_distribution(range);
// two argument constructors have an overload problem. It is checked with 1.82.0.
//return new hyperexponential_distribution(range.begin(), range.end());
}
#endif
};
// workaround for swig parse error of hyperexponential::is_iterator (>=1.77.0)
#if BOOST_VERSION >= 107700
namespace boost{ namespace math{
template <typename RealT = double, typename PolicyT = policies::policy<> >
class hyperexponential_distribution { /* extracted from ver 1.81.0 */
public:
typedef RealT value_type;
typedef PolicyT policy_type;
hyperexponential_distribution();
// Four arg constructor: no ambiguity here, the arguments must be two pairs of iterators:
template <typename ProbIterT, typename RateIterT>
hyperexponential_distribution(
ProbIterT prob_first, ProbIterT prob_last,
RateIterT rate_first, RateIterT rate_last);
// Two arg constructor from 2 ranges, we SFINAE this out of existence if
// either argument type is incrementable as in that case the type is
// probably an iterator:
template <
typename ProbRangeT, typename RateRangeT,
typename std::enable_if<!is_iterator<ProbRangeT>::value &&
!is_iterator<RateRangeT>::value, bool>::type = true>
hyperexponential_distribution(
ProbRangeT const& prob_range, RateRangeT const& rate_range);
// Two arg constructor for a pair of iterators: we SFINAE this out of
// existence if neither argument types are incrementable.
// Note that we allow different argument types here to allow for
// construction from an array plus a pointer into that array.
template <
typename RateIterT, typename RateIterT2,
typename std::enable_if<
is_iterator<RateIterT>::value || is_iterator<RateIterT2>::value, bool>::type = true>
hyperexponential_distribution(
RateIterT const& rate_first, RateIterT2 const& rate_last);
// Initializer list constructor: allows for construction from array literals:
hyperexponential_distribution(std::initializer_list<RealT> l1, std::initializer_list<RealT> l2);
hyperexponential_distribution(std::initializer_list<RealT> l1);
// Single argument constructor: argument must be a range.
template <typename RateRangeT>
hyperexponential_distribution(RateRangeT const& rate_range);
std::vector<RealT> probabilities() const;
std::vector<RealT> rates() const;
std::size_t num_phases() const;
};
} }
#define BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL_HPP
#endif
%define CTACH_LOGIC_ERROR(dist_name, func_name)
%extend boost::math::dist_name ## _distribution {
%catches(std::logic_error) func_name;
};
%enddef
%define CTACH_LOGIC_ERROR_FOR_FIND_METHODS(dist_name)
CTACH_LOGIC_ERROR(dist_name, find_lower_bound_on_p);
CTACH_LOGIC_ERROR(dist_name, find_upper_bound_on_p);
CTACH_LOGIC_ERROR(dist_name, find_minimum_number_of_trials);
CTACH_LOGIC_ERROR(dist_name, find_maximum_number_of_trials);
%enddef
CTACH_LOGIC_ERROR_FOR_FIND_METHODS(binomial);
CTACH_LOGIC_ERROR_FOR_FIND_METHODS(geometric);
CTACH_LOGIC_ERROR_FOR_FIND_METHODS(negative_binomial);
#undef CTACH_LOGIC_ERROR_FOR_FIND_METHODS
CTACH_LOGIC_ERROR(chi_squared, find_degrees_of_freedom);
CTACH_LOGIC_ERROR(non_central_chi_squared, find_degrees_of_freedom);
CTACH_LOGIC_ERROR(students_t, find_degrees_of_freedom);
#undef CTACH_LOGIC_ERROR
%feature("autodoc", "1");
INSTANTIATE(arcsine, double, Arcsine, 105800);
INSTANTIATE(bernoulli, double, Bernoulli, 103500);
INSTANTIATE(beta, double, Beta, 103500);
INSTANTIATE(binomial, double, Binomial, 103500);
INSTANTIATE(cauchy, double, Cauchy, 103500);
INSTANTIATE(chi_squared, double, ChiSquared, 103500);
INSTANTIATE(exponential, double, Exponential, 103500);
INSTANTIATE(extreme_value, double, ExtremeValue, 103500);
INSTANTIATE(fisher_f, double, FisherF, 103500);
INSTANTIATE(gamma, double, Gamma, 103500);
INSTANTIATE(geometric, double, Geometric, 104600);
INSTANTIATE(hyperexponential, double, Hyperexponential, 105700);
INSTANTIATE(hypergeometric, double, Hypergeometric, 104000);
INSTANTIATE(inverse_chi_squared, double, InverseChiSquared, 104500);
INSTANTIATE(inverse_gamma, double, InverseGamma, 104500);
INSTANTIATE(inverse_gaussian, double, InverseGaussian, 104600);
INSTANTIATE(kolmogorov_smirnov, double, KolmogorovSmirnov, 107500);
INSTANTIATE(laplace, double, Laplace, 104000);
INSTANTIATE(logistic, double, Logistic, 104000);
INSTANTIATE(lognormal, double, Lognormal, 103500);
INSTANTIATE(negative_binomial, double, NegativeBinomial, 103500);
INSTANTIATE(non_central_beta, double, NonCentralBeta, 103600);
INSTANTIATE(non_central_chi_squared, double, NonCentralChiSquared, 103600);
INSTANTIATE(non_central_f, double, NonCentralF, 103600);
INSTANTIATE(non_central_t, double, NonCentralT, 103600);
INSTANTIATE(normal, double, Normal, 103500);
INSTANTIATE(pareto, double, Pareto, 103500);
INSTANTIATE(poisson, double, Poisson, 103500);
INSTANTIATE(rayleigh, double, Rayleigh, 103500);
INSTANTIATE(skew_normal, double, SkewNormal, 105000);
INSTANTIATE(students_t, double, StudentsT, 103500);
INSTANTIATE(triangular, double, Triangular, 103500);
INSTANTIATE(uniform, double, Uniform, 103500);
INSTANTIATE(weibull, double, Weibull, 103500);
#undef INSTANTIATE