Quantity.h
Go to the documentation of this file.
1 #ifndef WIRECELL_QUANTITY
2 #define WIRECELL_QUANTITY
3 
4 #include <cmath>
5 #include <ostream>
6 
7 namespace WireCell {
8 
9  // This is heavily cribbed from Boost's units/example/measurement.hpp
10 
11  /** Provide a quantity with a value and an uncertainty and all the
12  * little math operators.
13  *
14  * Beware this assumes all quantities are uncorrelated!
15  */
16  class Quantity {
17  public:
19  : m_mean(0.0), m_sigma(0.0)
20  { }
21  Quantity(const double& mean, const double& sigma)
22  : m_mean(mean), m_sigma(sigma)
23  { }
24  Quantity(const double& mean)
25  : m_mean(mean), m_sigma(0.0)
26  { }
27  Quantity(const int& imean)
28  : m_mean((double)imean), m_sigma(0.0)
29  { }
31  : m_mean(other.m_mean), m_sigma(other.m_sigma)
32  { }
33 
34 
35  ~Quantity() {}
36 
38  {
39  if (this == &other) return *this;
40  m_mean = other.m_mean;
41  m_sigma = other.m_sigma;
42  return *this;
43  }
44 
45  operator double() const { return m_mean; }
46 
47  double mean() const { return m_mean; }
48  double sigma() const { return m_sigma; }
49 
50 
51  Quantity& operator+=(const double& exact)
52  {
53  m_mean += exact;
54  return *this;
55  }
56 
57  Quantity& operator-=(const double& exact)
58  {
59  m_mean -= exact;
60  return *this;
61  }
62 
63  Quantity& operator*=(const double& exact)
64  {
65  m_mean *= exact;
66  m_sigma *= exact;
67  return *this;
68  }
69 
70  Quantity& operator/=(const double& exact)
71  {
72  m_mean /= exact;
73  m_sigma /= exact;
74  return *this;
75  }
76 
77 
79  // relative uncertainties
80  const double mrs = m_sigma/m_mean;
81  const double ors = other.m_sigma/other.m_mean;
82 
83  m_mean *= other.m_mean;
84  m_sigma = m_mean * std::hypot(mrs, ors);
85 
86  return *this;
87  }
88 
90  // relative uncertainties
91  const double mrs = m_sigma/m_mean;
92  const double ors = other.m_sigma/other.m_mean;
93 
94  m_mean /= other.m_mean;
95  m_sigma = m_mean * std::hypot(mrs, ors);
96 
97  return *this;
98  }
99 
101  m_mean -= other.m_mean;
102  m_sigma = std::hypot(m_sigma, other.m_sigma);
103  return *this;
104  }
106  m_mean += other.m_mean;
107  m_sigma = std::hypot(m_sigma, other.m_sigma);
108  return *this;
109  }
110 
111 
112  bool operator<(const Quantity& other) const {
113  return m_mean < other.m_mean;
114  }
115  bool operator>(const Quantity& other) const {
116  return m_mean > other.m_mean;
117  }
118  bool operator==(const Quantity& other) const {
119  return m_mean == other.m_mean;
120  }
121  bool operator!=(const Quantity& other) const {
122  return m_mean != other.m_mean;
123  }
124 
125  private:
126 
127  double m_mean, m_sigma;
128  };
129 
130 
131 inline std::ostream & operator<<(std::ostream &os, const WireCell::Quantity& q)
132 {
133  os << "(" << q.mean() << " +/- " << q.sigma() << ")";
134  return os;
135 }
136 
138 {
139  return WireCell::Quantity(-1*other.mean(), other.sigma());
140 }
141 
143  const WireCell::Quantity& rhs)
144 {
145  WireCell::Quantity res = lhs;
146  res *= rhs;
147  return res;
148 }
150  const WireCell::Quantity& rhs)
151 {
152  WireCell::Quantity res = lhs;
153  res /= rhs;
154  return res;
155 }
157  const WireCell::Quantity& rhs)
158 {
159  WireCell::Quantity res = lhs;
160  res += rhs;
161  return res;
162 }
164  const WireCell::Quantity& rhs)
165 {
166  WireCell::Quantity res = lhs;
167  res -= rhs;
168  return res;
169 }
170 
171 // some comparisons with other, scalar types
172 
173 // fixme: *should* this be true: should exact values be considered equal?
174 inline bool operator==(const WireCell::Quantity& lhs, const double& scalar)
175 { return lhs.mean() == scalar; }
176 
177 inline bool operator!=(const WireCell::Quantity& lhs, const double& scalar)
178 { return lhs.mean() != scalar; }
179 
180 inline bool operator<(const WireCell::Quantity& lhs, const double& scalar)
181 { return lhs.mean() < scalar; }
182 
183 inline bool operator>(const WireCell::Quantity& lhs, const double& scalar)
184 { return lhs.mean() > scalar; }
185 
186 
187 inline bool operator==(const double& scalar, const WireCell::Quantity& rhs)
188 { return scalar == rhs.mean(); }
189 
190 inline bool operator!=(const double& scalar, const WireCell::Quantity& rhs)
191 { return scalar != rhs.mean(); }
192 
193 inline bool operator<(const double& scalar, const WireCell::Quantity& rhs)
194 { return scalar < rhs.mean(); }
195 
196 inline bool operator>(const double& scalar, const WireCell::Quantity& rhs)
197 { return scalar > rhs.mean(); }
198 
199 } //namespace WireCell
200 
201 #endif
bool operator!=(const Quantity &other) const
Definition: Quantity.h:121
D3Vector< T > operator*(const D3Vector< T > a, T s)
Definition: D3Vector.h:160
Quantity & operator/=(const double &exact)
Definition: Quantity.h:70
Quantity & operator+=(const double &exact)
Definition: Quantity.h:51
Quantity & operator-=(const double &exact)
Definition: Quantity.h:57
Quantity & operator*=(const Quantity &other)
Definition: Quantity.h:78
Quantity(const double &mean)
Definition: Quantity.h:24
Quantity & operator=(const Quantity &other)
Definition: Quantity.h:37
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
Definition: hypot.h:60
Quantity(const Quantity &other)
Definition: Quantity.h:30
bool operator<(const Quantity &other) const
Definition: Quantity.h:112
Quantity & operator/=(const Quantity &other)
Definition: Quantity.h:89
double mean() const
Definition: Quantity.h:47
Quantity(const double &mean, const double &sigma)
Definition: Quantity.h:21
Quantity(const int &imean)
Definition: Quantity.h:27
D3Vector< T > operator/(const D3Vector< T > a, T s)
Definition: D3Vector.h:165
Definition: Main.h:22
double sigma() const
Definition: Quantity.h:48
std::ostream & operator<<(std::ostream &os, const WireCell::WirePlaneId &wpid)
Definition: WirePlaneId.cxx:83
Quantity & operator*=(const double &exact)
Definition: Quantity.h:63
bool operator>(const Quantity &other) const
Definition: Quantity.h:115
Quantity & operator-=(const Quantity &other)
Definition: Quantity.h:100
Quantity & operator+=(const Quantity &other)
Definition: Quantity.h:105
bool operator==(const Quantity &other) const
Definition: Quantity.h:118
D3Vector< T > operator-(const D3Vector< T > a, const D3Vector< T > b)
Definition: D3Vector.h:150
D3Vector< T > operator+(const D3Vector< T > a, const D3Vector< T > b)
Definition: D3Vector.h:155