version  0.0.1
Defines the C++ API for MsPASS
Loading...
Searching...
No Matches
VectorStatistics.h
1#ifndef _VECTORSTATISTICS_H_
2#define _VECTORSTATISTICS_H_
3#include "mspass/utility/MsPASSError.h"
4#include <algorithm>
5#include <vector>
6namespace mspass {
7namespace utility {
8
16template <class T> class VectorStatistics {
17public:
23 VectorStatistics(std::vector<T> din);
25 VectorStatistics(T *din, int n);
27 T median();
29 T mean();
31 T q1_4();
33 T q3_4();
35 T interquartile();
37 T mad(T center);
39 T ssq();
41 T upper_bound();
43 T lower_bound();
45 T range();
48 T quantile(size_t n);
49
50private:
51 std::vector<T> d;
52};
53
54template <class T> VectorStatistics<T>::VectorStatistics(std::vector<T> din) {
55 if (din.size() <= 1)
57 std::string("VectorStatistics constructor: ") +
58 "input vector has insufficient data to compute statistics",
59 mspass::utility::ErrorSeverity::Invalid);
60 d = din;
61 std::sort(d.begin(), d.end());
62}
63template <class T> VectorStatistics<T>::VectorStatistics(T *din, int n) {
64 if (n <= 1)
66 std::string("VectorStatistics constructor: ") +
67 "input vector has insufficient data to compute statistics",
68 mspass::utility::ErrorSeverity::Invalid);
69 d.reserve(n);
70 for (int i = 0; i < n; ++i)
71 d.push_back(din[i]);
72 std::sort(d.begin(), d.end());
73}
74template <class T> T VectorStatistics<T>::median() {
75 int count = d.size();
76 int medposition = count / 2;
77 if (count % 2)
78 return (d[medposition]);
79 else
80 return ((d[medposition] + d[medposition - 1]) / 2);
81}
82template <class T> T VectorStatistics<T>::mean() {
83 T result;
84 result = 0;
85 for (int i = 0; i < d.size(); ++i) {
86 result += d[i];
87 }
88 return (result / d.size());
89}
90template <class T> T VectorStatistics<T>::q1_4() {
91 int n = d.size();
92 double result;
93 if (n < 4)
94 return (d[0]);
95 else {
96 int nover4 = (n - 1) / 4;
97 switch (n % 4) {
98 case (0):
99 result = static_cast<double>(d[nover4]);
100 break;
101 case (1):
102 result = 0.75 * static_cast<double>(d[nover4]) +
103 0.25 * static_cast<double>(d[nover4 + 1]);
104 break;
105 case (2):
106 result =
107 static_cast<double>(d[nover4]) + static_cast<double>(d[nover4 + 1]);
108 result /= 2.0;
109 break;
110 case (3):
111 result = 0.25 * static_cast<double>(d[nover4]) +
112 0.75 * static_cast<double>(d[nover4 + 1]);
113 }
114 }
115 return (static_cast<T>(result));
116}
117template <class T> T VectorStatistics<T>::q3_4() {
118 int n = d.size();
119 double result;
120 if (n < 4)
121 return (d[n - 1]);
122 else {
123 int n3_4 = 3 * (n - 1) / 4;
124 switch (n % 4) {
125 case (0):
126 result = static_cast<double>(d[n3_4]);
127 break;
128 case (1):
129 result = 0.75 * static_cast<double>(d[n3_4]) +
130 0.25 * static_cast<double>(d[n3_4 + 1]);
131 break;
132 case (2):
133 result = static_cast<double>(d[n3_4]) + static_cast<double>(d[n3_4 + 1]);
134 result /= 2.0;
135 break;
136 case (3):
137 result = 0.25 * static_cast<double>(d[n3_4]) +
138 0.75 * static_cast<double>(d[n3_4 + 1]);
139 }
140 }
141 return (static_cast<T>(result));
142}
144 T result;
145 T d1_4, d3_4;
146 d1_4 = this->q1_4();
147 d3_4 = this->q3_4();
148 return (d3_4 - d1_4);
149}
150template <class T> T VectorStatistics<T>::mad(T center) {
151 std::vector<T> absdiff;
152 int n = d.size();
153 int i;
154 for (i = 0; i < n; ++i) {
155 T diff;
156 diff = d[i] - center;
157 if (diff < 0)
158 diff = -diff;
159 absdiff.push_back(diff);
160 }
161 VectorStatistics<T> result(absdiff);
162 return (result.median());
163}
164template <class T> T VectorStatistics<T>::ssq() {
165 T result;
166 int i;
167 for (i = 0; i < d.size(); ++i)
168 result = d[i] * d[i];
169 return (result);
170}
171template <class T> T VectorStatistics<T>::upper_bound() {
172 return (d[d.size() - 1]);
173}
174template <class T> T VectorStatistics<T>::lower_bound() { return (d[0]); }
175template <class T> T VectorStatistics<T>::range() {
176 T result;
177 result = this->upper_bound();
178 result -= this->lower_bound();
179 return (result);
180}
181template <class T> T VectorStatistics<T>::quantile(size_t n) {
182 if (n >= d.size()) {
183 std::stringstream ss;
184 ss << "VectorStatistics::quantile method: asked for 1-quantile number "
185 << n << " but data vecotor length is only " << d.size() << std::endl;
186 throw mspass::utility::MsPASSError(ss.str(),
187 mspass::utility::ErrorSeverity::Invalid);
188 }
189}
190} // namespace utility
191} // namespace mspass
192#endif
Base class for error object thrown by MsPASS library routines.
Definition MsPASSError.h:38
Generic object to compute common robust statistics from a vector container of data.
Definition VectorStatistics.h:16
T median()
Definition VectorStatistics.h:74
T q3_4()
Definition VectorStatistics.h:117
T ssq()
Definition VectorStatistics.h:164
T q1_4()
Definition VectorStatistics.h:90
T quantile(size_t n)
Definition VectorStatistics.h:181
T mad(T center)
Definition VectorStatistics.h:150
T interquartile()
Definition VectorStatistics.h:143
T range()
Definition VectorStatistics.h:175
T upper_bound()
Definition VectorStatistics.h:171
T lower_bound()
Definition VectorStatistics.h:174
VectorStatistics(std::vector< T > din)
Definition VectorStatistics.h:54
T mean()
Definition VectorStatistics.h:82