@@ -517,6 +517,10 @@ struct Limits {
517
517
template <typename Iterator> Double_t Mean (Iterator first, Iterator last);
518
518
template <typename Iterator, typename WeightIterator> Double_t Mean (Iterator first, Iterator last, WeightIterator wfirst);
519
519
520
+ template <typename T> T *MovMedian (Long64_t n, T *a, Long64_t k, Double_t *w = nullptr , Long64_t *work = nullptr );
521
+ template <typename T> T *MovMean (Long64_t n, T *a, Long64_t k, Double_t *w = nullptr );
522
+ template <typename T> Double_t Mode (const Long64_t n, T *a);
523
+
520
524
template <typename T> Double_t GeomMean (Long64_t n, const T *a);
521
525
template <typename Iterator> Double_t GeomMean (Iterator first, Iterator last);
522
526
@@ -1083,7 +1087,7 @@ Double_t TMath::Mean(Iterator first, Iterator last, WeightIterator w)
1083
1087
}
1084
1088
1085
1089
// //////////////////////////////////////////////////////////////////////////////
1086
- // / Returns the weighted mean of an array a with length n.
1090
+ // / Returns the weighted mean of an array with a length n.
1087
1091
1088
1092
template <typename T>
1089
1093
Double_t TMath::Mean (Long64_t n, const T *a, const Double_t *w)
@@ -1095,6 +1099,207 @@ Double_t TMath::Mean(Long64_t n, const T *a, const Double_t *w)
1095
1099
}
1096
1100
}
1097
1101
1102
+ // //////////////////////////////////////////////////////////////////////////////
1103
+ // / Returns the moving mean of an array.
1104
+ // /
1105
+ // / \param[in] n number of array elements
1106
+ // / \param[in] *a array
1107
+ // / \param[in] k window size
1108
+ // / \param[in] *w weight of the array values
1109
+ // /
1110
+ // / The mean values will be calculated over the window value
1111
+ // / for each entry a[i] of the array. The function will return
1112
+ // / weighted moving mean if the weight argument is provided.
1113
+
1114
+ template <typename T>
1115
+ class Moving {
1116
+ public:
1117
+ T *a0;
1118
+ Double_t *w0;
1119
+ Long64_t *work0;
1120
+ Long64_t k0;
1121
+ Long64_t n0;
1122
+
1123
+ virtual Double_t GetValue (Long64_t n, T *a, Double_t *w = nullptr , Long64_t *work = nullptr ) = 0;
1124
+ virtual ~Moving () {};
1125
+
1126
+ Moving (Long64_t n, T *a, Long64_t k, Double_t *w = nullptr , Long64_t *work = nullptr )
1127
+ {
1128
+ n0 = n;
1129
+ a0 = a;
1130
+ k0 = k;
1131
+ w0 = w;
1132
+ work0 = work;
1133
+ }
1134
+
1135
+ template <typename U>
1136
+ void SplitArray (U *v, U *v1, Int_t first, Int_t last)
1137
+ {
1138
+ int i = 0 ;
1139
+
1140
+ while (first <= last) {
1141
+ v1[i] = v[first];
1142
+ i++;
1143
+ first++;
1144
+ }
1145
+ }
1146
+
1147
+ Double_t GetMoving (Long64_t n, Int_t first, Int_t last, Moving *sp)
1148
+ {
1149
+ Double_t result;
1150
+ T *a1 = new T[n + 1 ];
1151
+ SplitArray (a0, a1, first, last);
1152
+
1153
+ if (w0 != nullptr ) {
1154
+ Double_t *w1 = new Double_t[n + 1 ];
1155
+ SplitArray (w0, w1, first, last);
1156
+
1157
+ if (work0 != nullptr ) {
1158
+ Long64_t *wrk1 = new Long64_t[n + 1 ];
1159
+ SplitArray (work0, wrk1, first, last);
1160
+ result = sp->GetValue (n, a1, w1, wrk1);
1161
+ delete[] wrk1;
1162
+ } else {
1163
+ result = sp->GetValue (n, a1, w1);
1164
+ }
1165
+ delete[] w1;
1166
+ } else {
1167
+ result = sp->GetValue (n, a1);
1168
+ }
1169
+ delete[] a1;
1170
+ return result;
1171
+ }
1172
+
1173
+ T *GetResult (Moving *sp)
1174
+ {
1175
+ Long64_t kl = k0 / 2 ;
1176
+ Long64_t kr = (k0 % 2 ) ? k0 / 2 : k0 / 2 - 1 ;
1177
+ T *mov = new T[n0 + 1 ];
1178
+
1179
+ for (int i = 0 ; i != n0; i++) {
1180
+ kl = (i < k0 / 2 and i > 0 ) ? i : k0 / 2 ;
1181
+ if (i + kr > n0 - 1 ) {
1182
+ kr--;
1183
+ }
1184
+
1185
+ if (i == 0 ) {
1186
+ if (k0 > 2 ) {
1187
+ mov[i] = sp->GetMoving (kr + 1 , 0 , kr + 1 , sp);
1188
+ } else {
1189
+ mov[i] = sp->GetMoving (1 , 0 , 1 , sp);
1190
+ }
1191
+ } else if (i == n0 - 1 ) {
1192
+ mov[i] = sp->GetMoving (kl + 1 , i - kl, i, sp);
1193
+ } else {
1194
+ mov[i] = sp->GetMoving (kl + kr + 1 , i - kl, i + kr, sp);
1195
+ }
1196
+ }
1197
+ return mov;
1198
+ }
1199
+ };
1200
+
1201
+ template <typename T>
1202
+ class MovingMean : public Moving <T> {
1203
+ public:
1204
+ MovingMean (Long64_t n, T *a, Long64_t k, Double_t *w) : Moving<T>(n, a, k, w) {}
1205
+
1206
+ Double_t GetValue (Long64_t n, T *a, Double_t *w = nullptr , Long64_t *work = nullptr )
1207
+ {
1208
+ (void ) work;
1209
+ Double_t mean = TMath::Mean (n, a, w);
1210
+ return mean;
1211
+ }
1212
+ };
1213
+
1214
+ template <typename T>
1215
+ T *TMath::MovMean (Long64_t n, T *a, Long64_t k, Double_t *w)
1216
+ {
1217
+ if (n <= 2 ) {
1218
+ Fatal (" MovMean" , " the length of the array must be >1" );
1219
+ }
1220
+ if (k > n) {
1221
+ Fatal (" MovMean" , " the window length k is larger than the length of the array" );
1222
+ }
1223
+ if (k == 1 ) {
1224
+ Fatal (" MovMean" , " the window length k must be >1" );
1225
+ }
1226
+
1227
+ MovingMean<T> *movmean = new MovingMean (n, a, k, w);
1228
+ T *result = movmean->GetResult (movmean);
1229
+ delete movmean;
1230
+ return result;
1231
+ }
1232
+
1233
+ // //////////////////////////////////////////////////////////////////////////////
1234
+ // / Returns the moving median of an array.
1235
+ // /
1236
+ // / \param[in] n number of array elements
1237
+ // / \param[in] *a array
1238
+ // / \param[in] k window size
1239
+ // / \param[in] *w weight of the array values
1240
+ // / \param[in] *work work
1241
+ // /
1242
+ // / The median values will be calculated over the window
1243
+ // / value for each entry a[i] of the array. The function will
1244
+ // / return weighted moving median if the weight argument
1245
+ // / is provided.
1246
+
1247
+ template <typename T>
1248
+ class MovingMedian : public Moving <T> {
1249
+ public:
1250
+ MovingMedian (Long64_t n, T *a, Long64_t k, Double_t *w, Long64_t *work) : Moving<T>(n, a, k, w, work) {}
1251
+
1252
+ Double_t GetValue (Long64_t n, T *a, Double_t *w, Long64_t *work)
1253
+ {
1254
+ Double_t median = TMath::Median (n, a, w, work);
1255
+ return median;
1256
+ }
1257
+ };
1258
+
1259
+ template <typename T>
1260
+ T *TMath::MovMedian (Long64_t n, T *a, Long64_t k, Double_t *w, Long64_t *work)
1261
+ {
1262
+ if (n <= 2 ) {
1263
+ Fatal (" MovMedian" , " the length of the array must be >1" );
1264
+ }
1265
+ if (k > n) {
1266
+ Fatal (" MovMedian" , " the window length k is larger than the length of the array" );
1267
+ }
1268
+ if (k == 1 ) {
1269
+ Fatal (" MovMedian" , " the window length k must be >1" );
1270
+ }
1271
+
1272
+ MovingMedian<T> *movmedian = new MovingMedian (n, a, k, w, work);
1273
+ T *result = movmedian->GetResult (movmedian);
1274
+ delete movmedian;
1275
+ return result;
1276
+ }
1277
+
1278
+ // //////////////////////////////////////////////////////////////////////////////
1279
+ // / Returns the mode of an array. If there are an equal amount of
1280
+ // / different values, the smallest value will be returned.
1281
+ // /
1282
+ // / \param[in] n number of array elements
1283
+ // / \param[in] *a array
1284
+
1285
+ template <typename T>
1286
+ Double_t TMath::Mode (const Long64_t n, T *a)
1287
+ {
1288
+ int N1 = 0 ;
1289
+ int N2 = 0 ;
1290
+ Double_t mode = 0 ;
1291
+ std::sort (a, a + n);
1292
+
1293
+ for (Long64_t i = 0 ; i < n; i++) {
1294
+ N2 = std::count (a, a + n, a[i]);
1295
+ if (N2 > N1 && mode != a[i]) {
1296
+ mode = a[i];
1297
+ }
1298
+ N1 = N2;
1299
+ }
1300
+ return mode;
1301
+ }
1302
+
1098
1303
// //////////////////////////////////////////////////////////////////////////////
1099
1304
// / Returns the geometric mean of an array defined by the iterators.
1100
1305
// / \f[ GeomMean = (\prod_{i=0}^{n-1} |a[i]|)^{1/n} \f]
0 commit comments