SST  7.1.0
StructuralSimulationToolkit
unitAlgebra.h
1 // -*- c++ -*-
2 
3 // Copyright 2009-2017 Sandia Corporation. Under the terms
4 // of Contract DE-NA0003525 with Sandia Corporation, the U.S.
5 // Government retains certain rights in this software.
6 //
7 // Copyright (c) 2009-2017, Sandia Corporation
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(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(std::string u);
69  /** Create a new Compount Unit type */
70  static void registerCompoundUnit(std::string u, 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(std::string units, sst_big_num& multiplier);
78  Units() {}
79  virtual ~Units() {}
80 
81  /** Assignment operator */
82  Units& operator= (const Units& v);
83  /** Self-multiplication operator */
84  Units& operator*= (const Units& v);
85  /** Self-division operator */
86  Units& operator/= (const Units& v);
87  /** Equality Operator */
88  bool operator== (const Units &lhs) const;
89  /** Inequality Operator */
90  bool operator!= (const Units &lhs) const {return !(*this == lhs);}
91  /** Perform a reciprocal operation. Numerator and Denominator swap. */
92  Units& invert();
93 
94  /** Return a String representation if this Unit */
95  std::string toString() const;
96 };
97 
98 /**
99  * Performs Unit math in full precision
100  *
101  * Allows operations such as multiplying a frequency by 2.
102  *
103  */
105  public SST::Core::Serialization::serializable_type<UnitAlgebra> {
106 private:
107  Units unit;
108  sst_big_num value;
109 
110  static std::string trim(std::string str);
111  void init(std::string val);
112 
113 public:
114  UnitAlgebra() {}
115  /**
116  Create a new UnitAlgebra instance, and pre-populate with a parsed value.
117 
118  \param val Value to parse. It is of the following format:
119  \code
120  val := NUMBER( )?UNITS
121  NUMBER := (-)?[0-9]+(.[0-9]+)?
122  UNITS := UNITGROUP(/UNITGROUP)
123  UNITGROUP := UNIT(-UNIT)*
124  UNIT := (SIPREFIX)?(BASEUNIT|COMPUNIT)
125  SIPREFIX := {a,f,p,n,u,m,[kKMGTPE]i?}
126  BASEUNIT := {s,B,b,events}
127  COMPUNIT := {Hz,hz,Bps,bps,event}
128  \endcode
129  */
130  UnitAlgebra(std::string val);
131  virtual ~UnitAlgebra();
132 
133  /** Print to an ostream the value */
134  void print(std::ostream& stream);
135  /** Print to an ostream the value
136  * Formats the number using SI-prefixes
137  */
138  void printWithBestSI(std::ostream& stream);
139  /** Return a string representation of this value */
140  std::string toString() const;
141  /** Return a string representation of this value
142  * Formats the number using SI-prefixes
143  */
144  std::string toStringBestSI() const;
145 
146  UnitAlgebra& operator= (const std::string& v);
147 
148  /** Multiply by an argument; */
150  /** Multiply by an argument; */
151  template <typename T>
152  UnitAlgebra& operator*= (const T& v) {
153  value *= v;
154  return *this;
155  }
156 
157  /** Divide by an argument; */
159  /** Divide by an argument; */
160  template <typename T>
161  UnitAlgebra& operator/= (const T& v) {
162  value /= v;
163  return *this;
164  }
165 
166  /** Compare if this object is greater than the argument */
167  bool operator> (const UnitAlgebra& v) const;
168  /** Compare if this object is greater than, or equal to, the argument */
169  bool operator>= (const UnitAlgebra& v) const;
170  /** Compare if this object is less than the argument */
171  bool operator< (const UnitAlgebra& v) const;
172  /** Compare if this object is less than, or equal to, the argument */
173  bool operator<= (const UnitAlgebra& v) const;
174  /** Apply a reciprocal operation to the object */
175  UnitAlgebra& invert();
176 
177  /** Returns true if the units in the parameter string are found
178  * in this object.
179  */
180  bool hasUnits(std::string u) const;
181  /** Return the raw value */
182  sst_big_num getValue() const {return value;}
183  /** Return the rounded value as a 64bit integer */
184  int64_t getRoundedValue() const;
185 
186  void serialize_order(SST::Core::Serialization::serializer &ser) override {
187  // Do the unit
188  ser & unit.numerator;
189  ser & unit.denominator;
190 
191  // For value, need to convert cpp_dec_float to string and
192  // reinit from string
193  switch(ser.mode()) {
194  case SST::Core::Serialization::serializer::SIZER:
195  case SST::Core::Serialization::serializer::PACK: {
196  // std::string s = value.str(40, std::ios_base::fixed);
197  std::string s = value.toString(0);
198  ser & s;
199  break;
200  }
201  case SST::Core::Serialization::serializer::UNPACK: {
202  std::string s;
203  ser & s;
204  value = sst_big_num(s);
205  break;
206  }
207  }
208  }
209  ImplementSerializable(SST::UnitAlgebra)
210 };
211 
212 
213 // template <typename T>
214 // UnitAlgebra operator* (UnitAlgebra lhs, const T& rhs);
215 
216 // template <typename T>
217 // UnitAlgebra operator* (const T& lhs, UnitAlgebra rhs);
218 
219 // UnitAlgebra operator* (UnitAlgebra& lhs, const UnitAlgebra rhs);
220 
221 // template <typename T>
222 // UnitAlgebra operator/ (UnitAlgebra lhs, const T& rhs);
223 
224 // std::ostream& operator<< (std::ostream& os, const UnitAlgebra& r);
225 
226 // std::ostream& operator<< (std::ostream& os, const Units& r);
227 
228 template <typename T>
229 UnitAlgebra operator* (UnitAlgebra lhs, const T& rhs)
230 {
231  lhs *= rhs;
232  return lhs;
233 }
234 
235 template <typename T>
236 UnitAlgebra operator* (const T& lhs, UnitAlgebra rhs)
237 {
238  rhs *= lhs;
239  return rhs;
240 }
241 
242 inline UnitAlgebra operator* (UnitAlgebra& lhs, const UnitAlgebra rhs)
243 {
244  lhs *= rhs;
245  return lhs;
246 }
247 
248 template <typename T>
249 UnitAlgebra operator/ (UnitAlgebra lhs, const T& rhs)
250 {
251  lhs /= rhs;
252  return lhs;
253 }
254 
255 inline std::ostream& operator<< (std::ostream& os, const UnitAlgebra& r)
256 {
257  os << r.toString();
258  return os;
259 }
260 
261 inline std::ostream& operator<< (std::ostream& os, const Units& r)
262 {
263  os << r.toString();
264  return os;
265 }
266 
267 } // namespace SST
268 
269 
270 #endif //SST_CORE_UNITALGEBRA_H
Units & operator*=(const Units &v)
Self-multiplication operator.
Definition: unitAlgebra.cc:257
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
std::string toString(int32_t precision=6) const
Create a string representation of this decimal_fixedpoint.
Definition: decimal_fixedpoint.h:426
std::string toString() const
Return a string representation of this value.
Definition: unitAlgebra.cc:397
Definition: action.cc:17
static void registerBaseUnit(std::string u)
Create a new Base Unit type.
Definition: unitAlgebra.cc:196
static void registerCompoundUnit(std::string u, std::string v)
Create a new Compount Unit type.
Definition: unitAlgebra.cc:207
Units & operator=(const Units &v)
Assignment operator.
Definition: unitAlgebra.cc:250
sst_big_num getValue() const
Return the raw value.
Definition: unitAlgebra.h:182
Definition: serializable.h:109
Units & invert()
Perform a reciprocal operation.
Definition: unitAlgebra.cc:290
bool operator!=(const Units &lhs) const
Inequality Operator.
Definition: unitAlgebra.h:90
bool operator==(const Units &lhs) const
Equality Operator.
Definition: unitAlgebra.cc:276
std::string toString() const
Return a String representation if this Unit.
Definition: unitAlgebra.cc:299
Performs Unit math in full precision.
Definition: unitAlgebra.h:104
Units & operator/=(const Units &v)
Self-division operator.
Definition: unitAlgebra.cc:267
Helper class internal to UnitAlgebra.
Definition: unitAlgebra.h:40
Definition: serializable.h:130