thepeg
is hosted by
Hepforge
,
IPPP Durham
ThePEG
2.3.0
Utilities
UnitIO.h
1
// -*- C++ -*-
2
//
3
// UnitIO.h is a part of ThePEG - Toolkit for HEP Event Generation
4
// Copyright (C) 1999-2019 Leif Lonnblad
5
//
6
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
8
//
9
#ifndef ThePEG_UnitIO_H
10
#define ThePEG_UnitIO_H
11
// This is the declaration of the IUnit and OUnit classes and
12
// associated templated functions.
13
14
#include <complex>
15
#include <iomanip>
16
#include <sstream>
17
#include <cstdlib>
18
#include <cmath>
19
20
namespace
ThePEG
{
21
35
template
<
typename
T,
typename
UT>
36
struct
OUnit
{
37
40
OUnit
(
const
T & t,
const
UT & u):
theX
(t),
theUnit
(u) {}
41
43
OUnit
(
const
OUnit<T,UT>
& iu):
theX
(iu.
theX
),
theUnit
(iu.
theUnit
) {}
44
46
const
T &
theX
;
47
49
const
UT &
theUnit
;
50
};
51
63
template
<
typename
T,
typename
UT>
64
struct
IUnit
{
65
68
IUnit
(T & t,
const
UT & u):
theX
(t),
theUnit
(u) {}
69
71
IUnit
(
const
IUnit<T,UT>
& iu):
theX
(iu.
theX
),
theUnit
(iu.
theUnit
) {}
72
74
T &
theX
;
75
77
const
UT &
theUnit
;
78
79
};
80
83
template
<
typename
T,
typename
UT>
84
inline
OUnit<T,UT>
ounit
(
const
T & t,
const
UT & ut) {
85
return
OUnit<T,UT>
(t, ut);
86
}
87
90
template
<
typename
T,
typename
UT>
91
inline
IUnit<T,UT>
iunit
(T & t,
const
UT & ut) {
92
return
IUnit<T,UT>
(t, ut);
93
}
94
97
template
<
typename
OStream,
typename
T,
typename
UT>
98
void
ounitstream
(OStream & os,
const
T & t, UT & u) {
99
os << t/u;
100
}
101
104
template
<
typename
IStream,
typename
T,
typename
UT>
105
void
iunitstream
(IStream & is, T & t, UT & u) {
106
double
d;
107
is >> d;
108
t = d*u;;
109
}
110
113
template
<
typename
IStream,
typename
T,
typename
UT>
114
void
iunitstream
(IStream & is, std::complex<T> & t, UT & u) {
115
std::complex<double> d;
116
is >> d;
117
t = d*u;;
118
}
119
121
template
<
typename
OStream,
typename
T,
typename
UT>
122
OStream &
operator<<
(OStream & os,
const
OUnit<T,UT>
& u) {
123
ounitstream
(os, u.theX, u.theUnit);
124
return
os;
125
}
126
128
template
<
typename
IStream,
typename
T,
typename
UT>
129
IStream &
operator>>
(IStream & is,
const
IUnit<T,UT>
& u) {
130
iunitstream
(is, u.theX, u.theUnit);
131
return
is;
132
}
133
145
template
<
typename
T,
typename
UT>
146
struct
OUnitErr
{
147
150
OUnitErr
(
const
T & t,
const
T & dt,
const
UT & u):
x
(t/u),
dx
(dt/u) {}
151
153
double
x
;
154
156
double
dx
;
157
158
};
159
161
template
<
typename
T,
typename
UT>
162
inline
OUnitErr<T,UT>
ouniterr
(
const
T & t,
const
T & dt,
const
UT & ut) {
163
return
OUnitErr<T,UT>
(t, dt, ut);
164
}
165
167
inline
OUnitErr<double,double>
ouniterr
(
double
t,
double
dt) {
168
return
OUnitErr<double,double>
(t, dt, 1.0);
169
}
170
172
template
<
typename
OStream,
typename
T,
typename
UT>
173
OStream &
operator<<
(OStream & os,
const
OUnitErr<T,UT>
& u) {
174
if
( ! isfinite(u.x) )
return
os << u.x;
175
if
( ! isfinite(u.dx) ) {
176
ostringstream out;
177
out << u.x <<
'('
<< u.dx <<
')'
;
178
return
os << out.str();
179
}
180
double
dx = min(u.dx, abs(u.x));
181
if
( dx <= 0.0 )
return
os << u.x;
182
double
x = abs(u.x);
183
ostringstream osse;
184
osse << std::scientific << setprecision(0) << dx;
185
string
sse = osse.str();
186
string::size_type ee = sse.find(
'e'
);
187
long
m =
static_cast<
long
>
(round(abs(x)/std::pow(10.0,std::atoi(sse.substr(ee + 1).c_str()))));
188
int
powx = m <= 0? os.precision(): int(log10(
double
(m)));
189
if
( m <= 0 || powx > os.precision() ) sse[0]=
'0'
;
190
ostringstream oss;
191
oss << std::scientific << setprecision(powx) << x;
192
string
ss = oss.str();
193
string::size_type e = ss.find(
'e'
);
194
ostringstream out;
195
int
pp = std::atoi(ss.substr(e + 1).c_str());
196
if
( pp%3 == 0 )
197
out << ss.substr(0, e) <<
"("
<< sse[0] <<
")"
<< ss.substr(e);
198
else
if
( (pp - 1)%3 == 0 ) {
199
ostringstream oss;
200
oss << std::scientific << setprecision(powx) << x/10.0;
201
string
ss = oss.str();
202
string::size_type e = ss.find(
'e'
);
203
if
( powx == 0 )
204
out << ss.substr(0, e) <<
"0("
<< sse[0] <<
"0)"
<< ss.substr(e);
205
else
if
( powx == 1 )
206
out << ss.substr(0, ss.find(
'.'
))
207
<< ss.substr(ss.find(
'.'
) + 1, e - ss.find(
'.'
) - 1)
208
<<
"("
<< sse[0] <<
")"
<< ss.substr(e);
209
else
{
210
swap(ss[ss.find(
'.'
)], ss[ss.find(
'.'
) + 1]);
211
out << ss.substr(0, e) <<
"("
<< sse[0] <<
")"
<< ss.substr(e);
212
}
213
}
214
else
{
215
ostringstream oss;
216
oss << std::scientific << setprecision(powx) << x*10.0;
217
string
ss = oss.str();
218
string::size_type e = ss.find(
'e'
);
219
if
( powx == 0 )
220
out <<
"0."
<< ss.substr(0, e) <<
"("
<< sse[0] <<
")"
<< ss.substr(e);
221
else
{
222
swap(ss[ss.find(
'.'
)], ss[ss.find(
'.'
) - 1]);
223
out << ss.substr(0, ss.find(
'.'
)) <<
"0"
<< ss.substr(ss.find(
'.'
), e)
224
<<
"("
<< sse[0] <<
")"
<< ss.substr(e);
225
}
226
}
227
string
res = out.str();
228
if
( u.x < 0.0 )
229
res =
"-"
+ res;
230
return
os << res;
231
}
232
238
template
<
typename
T,
typename
UT>
239
struct
IUnitErr
{
240
243
IUnitErr
(T & t, T & dt,
const
UT & u):
x
(t),
dx
(dt),
ut
(u) {}
244
246
T &
x
;
247
249
T &
dx
;
250
252
UT
ut
;
253
254
};
255
257
template
<
typename
T,
typename
UT>
258
inline
IUnitErr<T,UT>
iuniterr
(T & t, T & dt,
const
UT & ut) {
259
return
IUnitErr<T,UT>
(t, dt, ut);
260
}
261
263
inline
IUnitErr<double,double>
iuniterr
(
double
& t,
double
& dt) {
264
return
IUnitErr<double,double>
(t, dt, 1.0);
265
}
266
268
template
<
typename
IStream,
typename
T,
typename
UT>
269
IStream &
operator>>
(IStream & is,
const
IUnitErr<T,UT>
& u) {
270
string
s;
271
double
x = 0.0;
272
double
dx = 0.0;
273
double
ex = 1.0;
274
is >> s;
275
string::size_type open = s.find(
'('
);
276
string::size_type close = s.find(
')'
);
277
string
se =
"0"
;
278
string
sp =
"1"
;
279
double
pe = 1.0;
280
if
( open != string::npos && close != string::npos ) {
281
se = s.substr(open + 1);
282
sp += s.substr(close + 1);
283
string::size_type dot = s.find(
'.'
);
284
if
( dot != string::npos && dot < open ) pe = std::pow(10.0, 1.0 - (open - dot));
285
}
286
287
istringstream(s) >> x;
288
istringstream(se) >> dx;
289
istringstream(sp) >> ex;
290
291
u.x = x*ex*u.ut;
292
u.dx = dx*ex*pe*u.ut;
293
294
return
is;
295
}
296
297
}
298
299
#endif
/* ThePEG_UnitIO_H */
ThePEG
This is the main namespace within which all identifiers in ThePEG are declared.
Definition:
FactoryBase.h:28
ThePEG::iunit
IUnit< T, UT > iunit(T &t, const UT &ut)
Helper function creating a IUnit object given an object and a unit.
Definition:
UnitIO.h:91
ThePEG::operator>>
vector< T > & operator>>(vector< T > &tv, U &u)
Overload the right shift operator for vector to pop objects from a vector.
Definition:
Containers.h:192
ThePEG::iunitstream
void iunitstream(IStream &is, vector< T, Alloc > &v, UT &u)
Input a vector of objects with the specified unit.
Definition:
Containers.h:289
ThePEG::operator<<
vector< T > & operator<<(vector< T > &tv, const U &u)
Overload the left shift operator for vector to push_back objects to a vector.
Definition:
Containers.h:179
ThePEG::iuniterr
IUnitErr< T, UT > iuniterr(T &t, T &dt, const UT &ut)
Helper function creating a IUnitErr object.
Definition:
UnitIO.h:258
ThePEG::ounitstream
void ounitstream(OStream &os, const vector< T, Alloc > &v, UT &u)
Ouput a vector of objects with the specified unit.
Definition:
Containers.h:275
ThePEG::ouniterr
OUnitErr< T, UT > ouniterr(const T &t, const T &dt, const UT &ut)
Helper function creating a OUnitErr object.
Definition:
UnitIO.h:162
ThePEG::ounit
OUnit< T, UT > ounit(const T &t, const UT &ut)
Helper function creating a OUnit object given an object and a unit.
Definition:
UnitIO.h:84
ThePEG::IUnitErr
The IUnitErr class is used to facilitate input of unitful numbers with error estimates written out us...
Definition:
UnitIO.h:239
ThePEG::IUnitErr::IUnitErr
IUnitErr(T &t, T &dt, const UT &u)
Constructor given an object to be read assuming the given unit.
Definition:
UnitIO.h:243
ThePEG::IUnitErr::ut
UT ut
The unit assumed when reading the object.
Definition:
UnitIO.h:252
ThePEG::IUnitErr::x
T & x
Reference to the object to be read.
Definition:
UnitIO.h:246
ThePEG::IUnitErr::dx
T & dx
The estimated error of the number to be read.
Definition:
UnitIO.h:249
ThePEG::IUnit
The IUnit class is used to facilitate input of unitful numbers from and to a persistent stream.
Definition:
UnitIO.h:64
ThePEG::IUnit::theUnit
const UT & theUnit
The unit assumed when reading the object.
Definition:
UnitIO.h:77
ThePEG::IUnit::IUnit
IUnit(T &t, const UT &u)
Constructor given an object to be read assuming the given unit.
Definition:
UnitIO.h:68
ThePEG::IUnit::theX
T & theX
Reference to the object to be read.
Definition:
UnitIO.h:74
ThePEG::IUnit::IUnit
IUnit(const IUnit< T, UT > &iu)
Copy constructor.
Definition:
UnitIO.h:71
ThePEG::OUnitErr
OUnitErr is used to write out unitful numbers with an error estimate on a standard ostream.
Definition:
UnitIO.h:146
ThePEG::OUnitErr::x
double x
The number to be written.
Definition:
UnitIO.h:153
ThePEG::OUnitErr::dx
double dx
The estimated error of the number to be written.
Definition:
UnitIO.h:156
ThePEG::OUnitErr::OUnitErr
OUnitErr(const T &t, const T &dt, const UT &u)
Constructor given an object to be written assuming the given unit.
Definition:
UnitIO.h:150
ThePEG::OUnit
The OUnit< class is used to facilitate output of unitful numbers to a persistent stream.
Definition:
UnitIO.h:36
ThePEG::OUnit::theUnit
const UT & theUnit
The unit assumed when writing the object.
Definition:
UnitIO.h:49
ThePEG::OUnit::OUnit
OUnit(const T &t, const UT &u)
Constructor given an object to be written assuming the given unit.
Definition:
UnitIO.h:40
ThePEG::OUnit::OUnit
OUnit(const OUnit< T, UT > &iu)
Copy constructor.
Definition:
UnitIO.h:43
ThePEG::OUnit::theX
const T & theX
Reference to the object to be written.
Definition:
UnitIO.h:46
Generated on Thu Jun 20 2024 14:47:02 for ThePEG by
1.9.6