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