SST  10.1.0
StructuralSimulationToolkit
unitAlgebra.h
1 // -*- c++ -*-
2 
3 // Copyright 2009-2020 NTESS. Under the terms
4 // of Contract DE-NA0003525 with NTESS, the U.S.
5 // Government retains certain rights in this software.
6 //
7 // Copyright (c) 2009-2020, NTESS
8 // All rights reserved.
9 //
10 // This file is part of the SST software package. For license
11 // information, see the LICENSE file in the top level directory of the
12 // distribution.
13 
14 #ifndef SST_CORE_UNITALGEBRA_H
15 #define SST_CORE_UNITALGEBRA_H
16 
17 #include "sst/core/sst_types.h"
18 #include "sst/core/serialization/serializable.h"
19 #include "sst/core/serialization/serializer.h"
20 
21 #include <string>
22 #include <map>
23 #include <vector>
24 #include <mutex>
25 
26 #include "sst/core/warnmacros.h"
27 #include "sst/core/decimal_fixedpoint.h"
28 
29 
30 namespace SST {
31 
32 // typedef decimal_fixedpoint<3,3> sst_dec_float;
33 typedef decimal_fixedpoint<3,3> sst_big_num;
34 
35 /**
36  * Helper class internal to UnitAlgebra.
37  *
38  * Contains information on valid units
39  */
40 class Units {
41 
42  typedef uint8_t unit_id_t;
43 
44 private:
45  friend class UnitAlgebra;
46 
47  // Static data members and functions
48  static std::recursive_mutex unit_lock;
49  static std::map<std::string,unit_id_t> valid_base_units;
50  static std::map<std::string,std::pair<Units,sst_big_num> > valid_compound_units;
51  static std::map<unit_id_t,std::string> unit_strings;
52  static unit_id_t count;
53  static bool initialized;
54 
55  static bool initialize();
56 
57  // Non-static data members and functions
58  std::vector<unit_id_t> numerator;
59  std::vector<unit_id_t> denominator;
60 
61  void reduce();
62  // Used in constructor to incrementally build up unit from string
63  void addUnit(const std::string&, sst_big_num& multiplier, bool invert);
64 
65 public:
66  // Static data members and functions
67  /** Create a new Base Unit type */
68  static void registerBaseUnit(const std::string& u);
69  /** Create a new Compound Unit type */
70  static void registerCompoundUnit(const std::string& u, const std::string& v);
71 
72  // Non-static data members and functions
73  /** Create a new instantiation of a Units with a base unit string, and multiplier
74  * \param units String representing the new unit
75  * \param multiplier Value by which to multiply to get to this unit
76  */
77  Units(const std::string& units, sst_big_num& multiplier);
78  Units() {}
79  virtual ~Units() {}
80 
81  /** Copy constructor */
82  Units(const Units&) = default;
83 
84  /** Assignment operator */
85  Units& operator= (const Units& v);
86  /** Self-multiplication operator */
87  Units& operator*= (const Units& v);
88  /** Self-division operator */
89  Units& operator/= (const Units& v);
90  /** Equality Operator */
91  bool operator== (const Units &lhs) const;
92  /** Inequality Operator */
93  bool operator!= (const Units &lhs) const {return !(*this == lhs);}
94  /** Perform a reciprocal operation. Numerator and Denominator swap. */
95  Units& invert();
96 
97  /** Return a String representation if this Unit */
98  std::string toString() const;
99 };
100 
101 /**
102  * Performs Unit math in full precision
103  *
104  * Allows operations such as multiplying a frequency by 2.
105  *
106  */
108  public SST::Core::Serialization::serializable_type<UnitAlgebra> {
109 private:
110  Units unit;
111  sst_big_num value;
112 
113  static std::string trim(const std::string& str);
114 
115 public:
116  void init(const std::string& val);
117 
118  UnitAlgebra() {}
119  /**
120  Create a new UnitAlgebra instance, and pre-populate with a parsed value.
121 
122  \param val Value to parse. It is of the following format:
123  \code
124  val := NUMBER( )?UNITS
125  NUMBER := (-)?[0-9]+(.[0-9]+)?
126  UNITS := UNITGROUP(/UNITGROUP)
127  UNITGROUP := UNIT(-UNIT)*
128  UNIT := (SIPREFIX)?(BASEUNIT|COMPUNIT)
129  SIPREFIX := {a,f,p,n,u,m,[kKMGTPE]i?}
130  BASEUNIT := {s,B,b,events}
131  COMPUNIT := {Hz,hz,Bps,bps,event}
132  \endcode
133  */
134  UnitAlgebra(const std::string& val);
135  virtual ~UnitAlgebra();
136 
137  /** Copy constructor */
138  UnitAlgebra(const UnitAlgebra&) = default;
139 
140  /** Print to an ostream the value */
141  void print(std::ostream& stream);
142  /** Print to an ostream the value
143  * Formats the number using SI-prefixes
144  */
145  void printWithBestSI(std::ostream& stream);
146  /** Return a string representation of this value */
147  std::string toString() const;
148  /** Return a string representation of this value
149  * Formats the number using SI-prefixes
150  */
151  std::string toStringBestSI() const;
152 
153  UnitAlgebra& operator= (const std::string& v);
154 
155  /** Multiply by an argument; */
157  /** Multiply by an argument; */
158  template <typename T>
159  UnitAlgebra& operator*= (const T& v) {
160  value *= v;
161  return *this;
162  }
163 
164  /** Divide by an argument; */
166  /** Divide by an argument; */
167  template <typename T>
168  UnitAlgebra& operator/= (const T& v) {
169  value /= v;
170  return *this;
171  }
172 
173  /** Add an argument; */
175  /** Multiply by an argument; */
176  template <typename T>
177  UnitAlgebra& operator+= (const T& v) {
178  value += v;
179  return *this;
180  }
181 
182  /** Subtract an argument; */
184  /** Divide by an argument; */
185  template <typename T>
186  UnitAlgebra& operator-= (const T& v) {
187  value -= v;
188  return *this;
189  }
190 
191  /** Compare if this object is greater than the argument */
192  bool operator> (const UnitAlgebra& v) const;
193  /** Compare if this object is greater than, or equal to, the argument */
194  bool operator>= (const UnitAlgebra& v) const;
195  /** Compare if this object is less than the argument */
196  bool operator< (const UnitAlgebra& v) const;
197  /** Compare if this object is less than, or equal to, the argument */
198  bool operator<= (const UnitAlgebra& v) const;
199  /** Compare if this object is equal to, the argument */
200  bool operator== (const UnitAlgebra& v) const;
201  /** Compare if this object is not equal to, the argument */
202  bool operator!= (const UnitAlgebra& v) const;
203  /** Apply a reciprocal operation to the object */
204  UnitAlgebra& invert();
205 
206  /** Returns true if the units in the parameter string are found
207  * in this object.
208  */
209  bool hasUnits(const std::string& u) const;
210  /** Return the raw value */
211  sst_big_num getValue() const {return value;}
212  /** Return the rounded value as a 64bit integer */
213  int64_t getRoundedValue() const;
214  double getDoubleValue() const;
215  bool isValueZero() const;
216 
217  void serialize_order(SST::Core::Serialization::serializer &ser) override {
218  // Do the unit
219  ser & unit.numerator;
220  ser & unit.denominator;
221 
222  // For value, need to convert cpp_dec_float to string and
223  // reinit from string
224  switch(ser.mode()) {
225  case SST::Core::Serialization::serializer::SIZER:
226  case SST::Core::Serialization::serializer::PACK: {
227  // std::string s = value.str(40, std::ios_base::fixed);
228  std::string s = value.toString(0);
229  ser & s;
230  break;
231  }
232  case SST::Core::Serialization::serializer::UNPACK: {
233  std::string s;
234  ser & s;
235  value = sst_big_num(s);
236  break;
237  }
238  }
239  }
240  ImplementSerializable(SST::UnitAlgebra)
241 };
242 
243 
244 // template <typename T>
245 // UnitAlgebra operator* (UnitAlgebra lhs, const T& rhs);
246 
247 // template <typename T>
248 // UnitAlgebra operator* (const T& lhs, UnitAlgebra rhs);
249 
250 // UnitAlgebra operator* (UnitAlgebra& lhs, const UnitAlgebra rhs);
251 
252 // template <typename T>
253 // UnitAlgebra operator/ (UnitAlgebra lhs, const T& rhs);
254 
255 // std::ostream& operator<< (std::ostream& os, const UnitAlgebra& r);
256 
257 // std::ostream& operator<< (std::ostream& os, const Units& r);
258 
259 template <typename T>
260 UnitAlgebra operator* (UnitAlgebra lhs, const T& rhs)
261 {
262  lhs *= rhs;
263  return lhs;
264 }
265 
266 // template <typename T>
267 // UnitAlgebra operator* (const T& lhs, UnitAlgebra rhs)
268 // {
269 // rhs *= lhs;
270 // return rhs;
271 // }
272 
273 inline UnitAlgebra operator* (UnitAlgebra lhs, const UnitAlgebra& rhs)
274 {
275  lhs *= rhs;
276  return lhs;
277 }
278 
279 template <typename T>
280 UnitAlgebra operator/ (UnitAlgebra lhs, const T& rhs)
281 {
282  lhs /= rhs;
283  return lhs;
284 }
285 
286 inline UnitAlgebra operator/ (UnitAlgebra lhs, const UnitAlgebra& rhs)
287 {
288  lhs /= rhs;
289  return lhs;
290 }
291 
292 template <typename T>
293 UnitAlgebra operator+ (UnitAlgebra lhs, const T& rhs)
294 {
295  lhs += rhs;
296  return lhs;
297 }
298 
299 inline UnitAlgebra operator+ (UnitAlgebra lhs, const UnitAlgebra& rhs)
300 {
301  lhs += rhs;
302  return lhs;
303 }
304 
305 template <typename T>
306 UnitAlgebra operator- (UnitAlgebra lhs, const T& rhs)
307 {
308  lhs -= rhs;
309  return lhs;
310 }
311 
312 inline UnitAlgebra operator- (UnitAlgebra lhs, const UnitAlgebra& rhs)
313 {
314  lhs -= rhs;
315  return lhs;
316 }
317 
318 
319 inline std::ostream& operator<< (std::ostream& os, const UnitAlgebra& r)
320 {
321  os << r.toString();
322  return os;
323 }
324 
325 inline std::ostream& operator<< (std::ostream& os, const Units& r)
326 {
327  os << r.toString();
328  return os;
329 }
330 
331 } // namespace SST
332 
333 
334 #endif //SST_CORE_UNITALGEBRA_H
bool operator>(const UnitAlgebra &v) const
Compare if this object is greater than the argument.
Definition: unitAlgebra.cc:475
Units & operator*=(const Units &v)
Self-multiplication operator.
Definition: unitAlgebra.cc:254
UnitAlgebra & operator/=(const UnitAlgebra &v)
Divide by an argument;.
Definition: unitAlgebra.cc:441
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
void print(std::ostream &stream)
Print to an ostream the value.
Definition: unitAlgebra.cc:383
std::string toString(int32_t precision=6) const
Create a string representation of this decimal_fixedpoint.
Definition: decimal_fixedpoint.h:437
bool operator==(const UnitAlgebra &v) const
Compare if this object is equal to, the argument.
Definition: unitAlgebra.cc:523
bool operator>=(const UnitAlgebra &v) const
Compare if this object is greater than, or equal to, the argument.
Definition: unitAlgebra.cc:487
std::string toString() const
Return a string representation of this value.
Definition: unitAlgebra.cc:394
int64_t getRoundedValue() const
Return the rounded value as a 64bit integer.
Definition: unitAlgebra.cc:559
Units & operator=(const Units &v)
Assignment operator.
Definition: unitAlgebra.cc:247
static void registerBaseUnit(const std::string &u)
Create a new Base Unit type.
Definition: unitAlgebra.cc:193
std::string toStringBestSI() const
Return a string representation of this value Formats the number using SI-prefixes.
Definition: unitAlgebra.cc:403
bool operator==(const Units &lhs) const
Equality Operator.
Definition: unitAlgebra.cc:273
Definition: serializable.h:109
Units & invert()
Perform a reciprocal operation.
Definition: unitAlgebra.cc:287
sst_big_num getValue() const
Return the raw value.
Definition: unitAlgebra.h:211
void printWithBestSI(std::ostream &stream)
Print to an ostream the value Formats the number using SI-prefixes.
Definition: unitAlgebra.cc:388
bool operator!=(const UnitAlgebra &v) const
Compare if this object is not equal to, the argument.
Definition: unitAlgebra.cc:530
UnitAlgebra & invert()
Apply a reciprocal operation to the object.
Definition: unitAlgebra.cc:538
std::string toString() const
Return a String representation if this Unit.
Definition: unitAlgebra.cc:296
UnitAlgebra & operator*=(const UnitAlgebra &v)
Multiply by an argument;.
Definition: unitAlgebra.cc:433
UnitAlgebra & operator+=(const UnitAlgebra &v)
Add an argument;.
Definition: unitAlgebra.cc:449
static void registerCompoundUnit(const std::string &u, const std::string &v)
Create a new Compound Unit type.
Definition: unitAlgebra.cc:204
UnitAlgebra & operator-=(const UnitAlgebra &v)
Subtract an argument;.
Definition: unitAlgebra.cc:462
bool hasUnits(const std::string &u) const
Returns true if the units in the parameter string are found in this object.
Definition: unitAlgebra.cc:547
bool operator<=(const UnitAlgebra &v) const
Compare if this object is less than, or equal to, the argument.
Definition: unitAlgebra.cc:511
bool operator!=(const Units &lhs) const
Inequality Operator.
Definition: unitAlgebra.h:93
Performs Unit math in full precision.
Definition: unitAlgebra.h:107
Units & operator/=(const Units &v)
Self-division operator.
Definition: unitAlgebra.cc:264
Helper class internal to UnitAlgebra.
Definition: unitAlgebra.h:40
bool operator<(const UnitAlgebra &v) const
Compare if this object is less than the argument.
Definition: unitAlgebra.cc:499
Definition: serializable.h:132