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