File indexing completed on 2024-04-28 03:42:27
0001 /* 0002 SPDX-FileCopyrightText: 2022 Sophie Taylor <sophie@spacekitteh.moe> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <memory> 0010 #include <gsl/gsl_vector.h> 0011 #include <gsl/gsl_sort.h> 0012 #include <gsl/gsl_statistics.h> 0013 0014 // gslhelpers is used to provide utility routines to access GNU Science Library (GSL) routines 0015 // iterators to access strided arrays are supported and these routines help to access the correct 0016 // GSL rotines (C based) for the datatype of the input data. 0017 // 0018 // gslheklpers is currently used by robuststatistics.h/cpp to access GSL robust statistics routines but 0019 // could be extended in future to access other GSL functions. 0020 0021 namespace Mathematics 0022 { 0023 0024 namespace GSLHelpers 0025 { 0026 0027 // int64 code is currently deactiovated by GSLHELPERS_INT64. It doesn't compile on Mac becuase it 0028 // won't cast a long long * to a long * even though they are both 64bit pointers. 0029 // On 32bit systems this would be an issue because they are not the same. 0030 // If the int64 versions are required in future then this "problem" will need to 0031 // be resolved. 0032 #undef GSLHELPERS_INT64 0033 0034 /** 0035 * @short creates a new shared pointer to a GSL vector which gets automatically freed. 0036 * The vector is initialised to 0. 0037 * 0038 * @param n the size of the vector. 0039 */ 0040 std::shared_ptr<gsl_vector> NewGSLVector(size_t n); 0041 0042 template<class Iter_T> 0043 class stride_iter 0044 { 0045 public: 0046 // public typedefs 0047 typedef typename std::iterator_traits<Iter_T>::value_type value_type; 0048 typedef typename std::iterator_traits<Iter_T>::reference reference; 0049 typedef typename std::iterator_traits<Iter_T>::difference_type 0050 difference_type; 0051 typedef typename std::iterator_traits<Iter_T>::pointer pointer; 0052 typedef std::random_access_iterator_tag iterator_category; 0053 typedef stride_iter self; 0054 0055 // constructors 0056 constexpr stride_iter( ) : iter(nullptr), step(0) { } 0057 constexpr stride_iter(const self &x) : iter(x.iter), step(x.step) { } 0058 constexpr stride_iter(Iter_T x, difference_type n) : iter(x), step(n) { } 0059 0060 // operators 0061 constexpr self &operator++( ) 0062 { 0063 iter += step; 0064 return *this; 0065 } 0066 constexpr self operator++(int) 0067 { 0068 self tmp = *this; 0069 iter += step; 0070 return tmp; 0071 } 0072 constexpr self &operator+=(difference_type x) 0073 { 0074 iter += x * step; 0075 return *this; 0076 } 0077 constexpr self &operator--( ) 0078 { 0079 iter -= step; 0080 return *this; 0081 } 0082 constexpr self operator--(int) 0083 { 0084 self tmp = *this; 0085 iter -= step; 0086 return tmp; 0087 } 0088 constexpr self &operator-=(difference_type x) 0089 { 0090 iter -= x * step; 0091 return *this; 0092 } 0093 constexpr reference operator[](difference_type n) 0094 { 0095 return iter[n * step]; 0096 } 0097 reference operator*( ) const 0098 { 0099 return *iter; 0100 } 0101 0102 // friend operators 0103 constexpr friend bool operator==(const self &x, const self &y) 0104 { 0105 assert(x.step == y.step); 0106 return x.iter == y.iter; 0107 } 0108 constexpr friend bool operator!=(const self &x, const self &y) 0109 { 0110 assert(x.step == y.step); 0111 return x.iter != y.iter; 0112 } 0113 constexpr friend bool operator<(const self &x, const self &y) 0114 { 0115 assert(x.step == y.step); 0116 return x.iter < y.iter; 0117 } 0118 constexpr friend difference_type operator-(const self &x, const self &y) 0119 { 0120 assert(x.step == y.step); 0121 return (x.iter - y.iter) / x.step; 0122 } 0123 constexpr friend self operator+(const self &x, difference_type y) 0124 { 0125 assert(x.step == y.step); 0126 return x += y * x.step; 0127 } 0128 constexpr friend self operator+(difference_type x, const self &y) 0129 { 0130 assert(x.step == y.step); 0131 return y += x * x.step; 0132 } 0133 private: 0134 Iter_T iter; 0135 difference_type step; 0136 }; 0137 0138 template< class Iter_T > 0139 constexpr static stride_iter<Iter_T> make_strided_iter(Iter_T i, typename stride_iter<Iter_T>::difference_type stride) 0140 { 0141 return stride_iter<Iter_T>(i, stride); 0142 } 0143 0144 0145 0146 0147 inline void gslSort(uint8_t data[], const size_t stride, const size_t n) 0148 { 0149 gsl_sort_uchar(data, stride, n); 0150 } 0151 inline void gslSort(double data[], const size_t stride, const size_t n) 0152 { 0153 gsl_sort(data, stride, n); 0154 } 0155 inline void gslSort(float data[], const size_t stride, const size_t n) 0156 { 0157 gsl_sort_float(data, stride, n); 0158 } 0159 inline void gslSort(uint16_t data[], const size_t stride, const size_t n) 0160 { 0161 gsl_sort_ushort(data, stride, n); 0162 } 0163 inline void gslSort(int16_t data[], const size_t stride, const size_t n) 0164 { 0165 gsl_sort_short(data, stride, n); 0166 } 0167 inline void gslSort(uint32_t data[], const size_t stride, const size_t n) 0168 { 0169 gsl_sort_uint(data, stride, n); 0170 } 0171 inline void gslSort(int32_t data[], const size_t stride, const size_t n) 0172 { 0173 gsl_sort_int(data, stride, n); 0174 } 0175 #ifdef GSLHELPERS_INT64 0176 inline void gslSort(int64_t data[], const size_t stride, const size_t n) 0177 { 0178 gsl_sort_long(data, stride, n); 0179 } 0180 #endif 0181 0182 0183 0184 0185 0186 0187 0188 inline double gslMean(const uint8_t data[], const size_t stride, const size_t n) 0189 { 0190 return gsl_stats_uchar_mean(data, stride, n); 0191 } 0192 inline double gslMean(const double data[], const size_t stride, const size_t n) 0193 { 0194 return gsl_stats_mean(data, stride, n); 0195 } 0196 inline double gslMean(const float data[], const size_t stride, const size_t n) 0197 { 0198 return gsl_stats_float_mean(data, stride, n); 0199 } 0200 inline double gslMean(const uint16_t data[], const size_t stride, const size_t n) 0201 { 0202 return gsl_stats_ushort_mean(data, stride, n); 0203 } 0204 inline double gslMean(const int16_t data[], const size_t stride, const size_t n) 0205 { 0206 return gsl_stats_short_mean(data, stride, n); 0207 } 0208 inline double gslMean(const uint32_t data[], const size_t stride, const size_t n) 0209 { 0210 return gsl_stats_uint_mean(data, stride, n); 0211 } 0212 inline double gslMean(const int32_t data[], const size_t stride, const size_t n) 0213 { 0214 return gsl_stats_int_mean(data, stride, n); 0215 } 0216 #ifdef GSLHELPERS_INT64 0217 inline double gslMean(const int64_t data[], const size_t stride, const size_t n) 0218 { 0219 return gsl_stats_long_mean(data, stride, n); 0220 } 0221 #endif 0222 0223 0224 inline double gslGastwirthMeanFromSortedData(const uint8_t data[], const size_t stride, const size_t n) 0225 { 0226 return gsl_stats_uchar_gastwirth_from_sorted_data(data, stride, n); 0227 } 0228 inline double gslGastwirthMeanFromSortedData(const double data[], const size_t stride, const size_t n) 0229 { 0230 return gsl_stats_gastwirth_from_sorted_data(data, stride, n); 0231 } 0232 inline double gslGastwirthMeanFromSortedData(const float data[], const size_t stride, const size_t n) 0233 { 0234 return gsl_stats_float_gastwirth_from_sorted_data(data, stride, n); 0235 } 0236 inline double gslGastwirthMeanFromSortedData(const uint16_t data[], const size_t stride, const size_t n) 0237 { 0238 return gsl_stats_ushort_gastwirth_from_sorted_data(data, stride, n); 0239 } 0240 inline double gslGastwirthMeanFromSortedData(const int16_t data[], const size_t stride, const size_t n) 0241 { 0242 return gsl_stats_short_gastwirth_from_sorted_data(data, stride, n); 0243 } 0244 inline double gslGastwirthMeanFromSortedData(const uint32_t data[], const size_t stride, const size_t n) 0245 { 0246 return gsl_stats_uint_gastwirth_from_sorted_data(data, stride, n); 0247 } 0248 inline double gslGastwirthMeanFromSortedData(const int32_t data[], const size_t stride, const size_t n) 0249 { 0250 return gsl_stats_int_gastwirth_from_sorted_data(data, stride, n); 0251 } 0252 #ifdef GSLHELPERS_INT64 0253 inline double gslGastwirthMeanFromSortedData(const int64_t data[], const size_t stride, const size_t n) 0254 { 0255 return gsl_stats_long_gastwirth_from_sorted_data(data, stride, n); 0256 } 0257 #endif 0258 0259 0260 inline double gslTrimmedMeanFromSortedData(const double trim, const uint8_t data[], const size_t stride, const size_t n) 0261 { 0262 return gsl_stats_uchar_trmean_from_sorted_data(trim, data, stride, n); 0263 } 0264 inline double gslTrimmedMeanFromSortedData(const double trim, const double data[], const size_t stride, const size_t n) 0265 { 0266 return gsl_stats_trmean_from_sorted_data(trim, data, stride, n); 0267 } 0268 inline double gslTrimmedMeanFromSortedData(const double trim, const float data[], const size_t stride, const size_t n) 0269 { 0270 return gsl_stats_float_trmean_from_sorted_data(trim, data, stride, n); 0271 } 0272 inline double gslTrimmedMeanFromSortedData(const double trim, const uint16_t data[], const size_t stride, 0273 const size_t n) 0274 { 0275 return gsl_stats_ushort_trmean_from_sorted_data(trim, data, stride, n); 0276 } 0277 inline double gslTrimmedMeanFromSortedData(const double trim, const int16_t data[], const size_t stride, const size_t n) 0278 { 0279 return gsl_stats_short_trmean_from_sorted_data(trim, data, stride, n); 0280 } 0281 inline double gslTrimmedMeanFromSortedData(const double trim, const uint32_t data[], const size_t stride, 0282 const size_t n) 0283 { 0284 return gsl_stats_uint_trmean_from_sorted_data(trim, data, stride, n); 0285 } 0286 inline double gslTrimmedMeanFromSortedData(const double trim, const int32_t data[], const size_t stride, const size_t n) 0287 { 0288 return gsl_stats_int_trmean_from_sorted_data(trim, data, stride, n); 0289 } 0290 #ifdef GSLHELPERS_INT64 0291 inline double gslTrimmedMeanFromSortedData(const double trim, const int64_t data[], const size_t stride, const size_t n) 0292 { 0293 return gsl_stats_long_trmean_from_sorted_data(trim, data, stride, n); 0294 } 0295 #endif 0296 0297 0298 0299 0300 inline double gslMedianFromSortedData(const uint8_t data[], const size_t stride, const size_t n) 0301 { 0302 return gsl_stats_uchar_median_from_sorted_data(data, stride, n); 0303 } 0304 inline double gslMedianFromSortedData(const double data[], const size_t stride, const size_t n) 0305 { 0306 return gsl_stats_median_from_sorted_data(data, stride, n); 0307 } 0308 inline double gslMedianFromSortedData(const float data[], const size_t stride, const size_t n) 0309 { 0310 return gsl_stats_float_median_from_sorted_data(data, stride, n); 0311 } 0312 inline double gslMedianFromSortedData(const uint16_t data[], const size_t stride, const size_t n) 0313 { 0314 return gsl_stats_ushort_median_from_sorted_data(data, stride, n); 0315 } 0316 inline double gslMedianFromSortedData(const int16_t data[], const size_t stride, const size_t n) 0317 { 0318 return gsl_stats_short_median_from_sorted_data(data, stride, n); 0319 } 0320 inline double gslMedianFromSortedData(const uint32_t data[], const size_t stride, const size_t n) 0321 { 0322 return gsl_stats_uint_median_from_sorted_data(data, stride, n); 0323 } 0324 inline double gslMedianFromSortedData(const int32_t data[], const size_t stride, const size_t n) 0325 { 0326 return gsl_stats_int_median_from_sorted_data(data, stride, n); 0327 } 0328 #ifdef GSLHELPERS_INT64 0329 inline double gslMedianFromSortedData(const int64_t data[], const size_t stride, const size_t n) 0330 { 0331 return gsl_stats_long_median_from_sorted_data(data, stride, n); 0332 } 0333 #endif 0334 0335 0336 inline double gslVariance(const uint8_t data[], const size_t stride, const size_t n) 0337 { 0338 return gsl_stats_uchar_variance(data, stride, n); 0339 } 0340 inline double gslVariance(const double data[], const size_t stride, const size_t n) 0341 { 0342 return gsl_stats_variance(data, stride, n); 0343 } 0344 inline double gslVariance(const float data[], const size_t stride, const size_t n) 0345 { 0346 return gsl_stats_float_variance(data, stride, n); 0347 } 0348 inline double gslVariance(const uint16_t data[], const size_t stride, const size_t n) 0349 { 0350 return gsl_stats_ushort_variance(data, stride, n); 0351 } 0352 inline double gslVariance(const int16_t data[], const size_t stride, const size_t n) 0353 { 0354 return gsl_stats_short_variance(data, stride, n); 0355 } 0356 inline double gslVariance(const uint32_t data[], const size_t stride, const size_t n) 0357 { 0358 return gsl_stats_uint_variance(data, stride, n); 0359 } 0360 inline double gslVariance(const int32_t data[], const size_t stride, const size_t n) 0361 { 0362 return gsl_stats_int_variance(data, stride, n); 0363 } 0364 #ifdef GSLHELPERS_INT64 0365 inline double gslVariance(const int64_t data[], const size_t stride, const size_t n) 0366 { 0367 return gsl_stats_long_variance(data, stride, n); 0368 } 0369 #endif 0370 0371 0372 0373 inline double gslStandardDeviation(const uint8_t data[], const size_t stride, const size_t n) 0374 { 0375 return gsl_stats_uchar_sd(data, stride, n); 0376 } 0377 inline double gslStandardDeviation(const double data[], const size_t stride, const size_t n) 0378 { 0379 return gsl_stats_sd(data, stride, n); 0380 } 0381 inline double gslStandardDeviation(const float data[], const size_t stride, const size_t n) 0382 { 0383 return gsl_stats_float_sd(data, stride, n); 0384 } 0385 inline double gslStandardDeviation(const uint16_t data[], const size_t stride, const size_t n) 0386 { 0387 return gsl_stats_ushort_sd(data, stride, n); 0388 } 0389 inline double gslStandardDeviation(const int16_t data[], const size_t stride, const size_t n) 0390 { 0391 return gsl_stats_short_sd(data, stride, n); 0392 } 0393 inline double gslStandardDeviation(const uint32_t data[], const size_t stride, const size_t n) 0394 { 0395 return gsl_stats_uint_sd(data, stride, n); 0396 } 0397 inline double gslStandardDeviation(const int32_t data[], const size_t stride, const size_t n) 0398 { 0399 return gsl_stats_int_sd(data, stride, n); 0400 } 0401 #ifdef GSLHELPERS_INT64 0402 inline double gslStandardDeviation(const int64_t data[], const size_t stride, const size_t n) 0403 { 0404 return gsl_stats_long_sd(data, stride, n); 0405 } 0406 #endif 0407 0408 0409 0410 inline double gslMAD(const uint8_t data[], const size_t stride, const size_t n, double work[]) 0411 { 0412 return gsl_stats_uchar_mad(data, stride, n, work); 0413 } 0414 inline double gslMAD(const double data[], const size_t stride, const size_t n, double work[]) 0415 { 0416 return gsl_stats_mad(data, stride, n, work); 0417 } 0418 inline double gslMAD(const float data[], const size_t stride, const size_t n, double work[]) 0419 { 0420 return gsl_stats_float_mad(data, stride, n, work); 0421 } 0422 inline double gslMAD(const uint16_t data[], const size_t stride, const size_t n, double work[]) 0423 { 0424 return gsl_stats_ushort_mad(data, stride, n, work); 0425 } 0426 inline double gslMAD(const int16_t data[], const size_t stride, const size_t n, double work[]) 0427 { 0428 return gsl_stats_short_mad(data, stride, n, work); 0429 } 0430 inline double gslMAD(const uint32_t data[], const size_t stride, const size_t n, double work[]) 0431 { 0432 return gsl_stats_uint_mad(data, stride, n, work); 0433 } 0434 inline double gslMAD(const int32_t data[], const size_t stride, const size_t n, double work[]) 0435 { 0436 return gsl_stats_int_mad(data, stride, n, work); 0437 } 0438 #ifdef GSLHELPERS_INT64 0439 inline double gslMAD(const int64_t data[], const size_t stride, const size_t n, double work[]) 0440 { 0441 return gsl_stats_long_mad(data, stride, n, work); 0442 } 0443 #endif 0444 0445 0446 inline double gslSnFromSortedData(const uint8_t data[], const size_t stride, const size_t n, uint8_t work[]) 0447 { 0448 return gsl_stats_uchar_Sn_from_sorted_data(data, stride, n, work); 0449 } 0450 inline double gslSnFromSortedData(const double data[], const size_t stride, const size_t n, double work[]) 0451 { 0452 return gsl_stats_Sn_from_sorted_data(data, stride, n, work); 0453 } 0454 inline double gslSnFromSortedData(const float data[], const size_t stride, const size_t n, float work[]) 0455 { 0456 return gsl_stats_float_Sn_from_sorted_data(data, stride, n, work); 0457 } 0458 inline double gslSnFromSortedData(const uint16_t data[], const size_t stride, const size_t n, uint16_t work[]) 0459 { 0460 return gsl_stats_ushort_Sn_from_sorted_data(data, stride, n, work); 0461 } 0462 inline double gslSnFromSortedData(const int16_t data[], const size_t stride, const size_t n, int16_t work[]) 0463 { 0464 return gsl_stats_short_Sn_from_sorted_data(data, stride, n, work); 0465 } 0466 inline double gslSnFromSortedData(const uint32_t data[], const size_t stride, const size_t n, uint32_t work[]) 0467 { 0468 return gsl_stats_uint_Sn_from_sorted_data(data, stride, n, work); 0469 } 0470 inline double gslSnFromSortedData(const int32_t data[], const size_t stride, const size_t n, int32_t work[]) 0471 { 0472 return gsl_stats_int_Sn_from_sorted_data(data, stride, n, work); 0473 } 0474 #ifdef GSLHELPERS_INT64 0475 inline double gslSnFromSortedData(const int64_t data[], const size_t stride, const size_t n, int64_t work[]) 0476 { 0477 return gsl_stats_long_Sn_from_sorted_data(data, stride, n, work); 0478 } 0479 #endif 0480 0481 inline double gslQnFromSortedData(const uint8_t data[], const size_t stride, const size_t n, uint8_t work[], 0482 int work_int[]) 0483 { 0484 return gsl_stats_uchar_Qn_from_sorted_data(data, stride, n, work, work_int); 0485 } 0486 inline double gslQnFromSortedData(const double data[], const size_t stride, const size_t n, double work[], 0487 int work_int[]) 0488 { 0489 return gsl_stats_Qn_from_sorted_data(data, stride, n, work, work_int); 0490 } 0491 inline double gslQnFromSortedData(const float data[], const size_t stride, const size_t n, float work[], int work_int[]) 0492 { 0493 return gsl_stats_float_Qn_from_sorted_data(data, stride, n, work, work_int); 0494 } 0495 inline double gslQnFromSortedData(const uint16_t data[], const size_t stride, const size_t n, uint16_t work[], 0496 int work_int[]) 0497 { 0498 return gsl_stats_ushort_Qn_from_sorted_data(data, stride, n, work, work_int); 0499 } 0500 inline double gslQnFromSortedData(const int16_t data[], const size_t stride, const size_t n, int16_t work[], 0501 int work_int[]) 0502 { 0503 return gsl_stats_short_Qn_from_sorted_data(data, stride, n, work, work_int); 0504 } 0505 inline double gslQnFromSortedData(const uint32_t data[], const size_t stride, const size_t n, uint32_t work[], 0506 int work_int[]) 0507 { 0508 return gsl_stats_uint_Qn_from_sorted_data(data, stride, n, work, work_int); 0509 } 0510 inline double gslQnFromSortedData(const int32_t data[], const size_t stride, const size_t n, int32_t work[], 0511 int work_int[]) 0512 { 0513 return gsl_stats_int_Qn_from_sorted_data(data, stride, n, work, work_int); 0514 } 0515 #ifdef GSLHELPERS_INT64 0516 inline double gslQnFromSortedData(const int64_t data[], const size_t stride, const size_t n, int64_t work[], 0517 int work_int[]) 0518 { 0519 return gsl_stats_long_Qn_from_sorted_data(data, stride, n, work, work_int); 0520 } 0521 #endif 0522 0523 } 0524 } // namespace Mathematics