ThePEG  1.8.0
PhysicalQty.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // PhysicalQty.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 2006-2011 David Grellscheid, Leif Lonnblad
5 //
6 // ThePEG is licenced under version 2 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef Physical_Qty_H
10 #define Physical_Qty_H
11 #include "TemplateTools.h"
12 #include <sstream>
13 
24 namespace ThePEG {
25 
27 struct ZeroUnit {
29  operator double() const { return 0.0; }
30 };
31 
34 
36 
37 
40 template <int M, int II>
41 struct QtyHelper
42 {
44  static const int I = -999999;
45 };
46 
50 template <int II>
51 struct QtyHelper<0,II>
52 {
54  static const int I = II;
55 };
56 
60 template <int II, int DI, int DI2>
61 struct QtyInt
62 {
64  static const int I = QtyHelper<(DI2*II)%DI,(DI2*II)/DI>::I;
65 };
67 
80 template<int L, int E, int Q, int DL = 1, int DE = 1, int DQ = 1>
81 class Qty
82 {
83 private:
85  Qty(double val) : rawValue_(val) {}
86 
87 public:
88 
90  static std::string className() {
91  std::ostringstream os;
92  os << "Qty<"
93  << L << ','
94  << E << ','
95  << Q << ','
96  << DL << ','
97  << DE << ','
98  << DQ << '>';
99 
100  return os.str();
101  }
102 
103 
105  typedef Qty<2*L,2*E,2*Q,DL,DE,DQ> Squared;
106 
108  static Qty<L,E,Q,DL,DE,DQ> baseunit()
109  {
110  return Qty<L,E,Q,DL,DE,DQ>(1.0);
111  }
112 
114  Qty() : rawValue_(0.0) {}
115 
117  Qty(ZeroUnit) : rawValue_(0.0) {}
118 
120  template <int DL2, int DE2, int DQ2>
121  Qty(const Qty<QtyInt<L,DL,DL2>::I,
122  QtyInt<E,DE,DE2>::I,
123  QtyInt<Q,DQ,DQ2>::I,
124  DL2,DE2,DQ2> & q)
125  : rawValue_(q.rawValue()) {}
126 
128  double rawValue() const { return rawValue_; }
129 
131  Qty<L,E,Q,DL,DE,DQ> & operator*=(double x) { rawValue_ *= x; return *this; }
132 
134  Qty<L,E,Q,DL,DE,DQ> & operator/=(double x) { rawValue_ /= x; return *this; }
135 
137  template <int DL2, int DE2, int DQ2>
138  Qty<L,E,Q,DL,DE,DQ> &
139  operator+=(const Qty<QtyInt<L,DL,DL2>::I,
140  QtyInt<E,DE,DE2>::I,
141  QtyInt<Q,DQ,DQ2>::I,
142  DL2,DE2,DQ2> x)
143  {
144  rawValue_ += x.rawValue();
145  return *this;
146  }
147 
149  template <int DL2, int DE2, int DQ2>
150  Qty<L,E,Q,DL,DE,DQ> &
151  operator-=(const Qty<QtyInt<L,DL,DL2>::I,
152  QtyInt<E,DE,DE2>::I,
153  QtyInt<Q,DQ,DQ2>::I,
154  DL2,DE2,DQ2> x)
155  {
156  rawValue_ -= x.rawValue();
157  return *this;
158  }
159 
160 private:
162  double rawValue_;
163 };
164 
166 template<int DL, int DE, int DQ>
167 class Qty<0,0,0,DL,DE,DQ>
168 {
169 public:
171  typedef Qty<0,0,0,DL,DE,DQ> Squared;
172 
174  static double baseunit() {
175  return 1.0;
176  }
177 
179  Qty(ZeroUnit) : rawValue_(0.0) {}
180 
182  Qty(double x = 0.0) : rawValue_(x) {}
183 
185  template <int DL2, int DE2, int DQ2>
186  Qty(const Qty<0,0,0,DL2,DE2,DQ2> & q) : rawValue_(q.rawValue()) {}
187 
189  double rawValue() const { return rawValue_; }
190 
192  operator double() const { return rawValue_; }
193 
195  Qty<0,0,0,DL,DE,DQ> & operator*=(double x) { rawValue_ *= x; return *this; }
196 
198  Qty<0,0,0,DL,DE,DQ> & operator/=(double x) { rawValue_ /= x; return *this; }
199 
201  template <int DL2, int DE2, int DQ2>
202  Qty<0,0,0,DL,DE,DQ> & operator+=(const Qty<0,0,0,DL2,DE2,DQ2> x) {
203  rawValue_ += x.rawValue();
204  return *this;
205  }
206 
208  template <int DL2, int DE2, int DQ2>
209  Qty<0,0,0,DL,DE,DQ> & operator-=(const Qty<0,0,0,DL2,DE2,DQ2> x) {
210  rawValue_ -= x.rawValue();
211  return *this;
212  }
213 
215  Qty<0,0,0,DL,DE,DQ> & operator+=(double x) {
216  rawValue_ += x;
217  return *this;
218  }
219 
221  Qty<0,0,0,DL,DE,DQ> & operator-=(double x) {
222  rawValue_ -= x;
223  return *this;
224  }
225 
226 private:
228  double rawValue_;
229 };
230 
232 
233 
238 template <typename T, typename U>
239 struct BinaryOpTraits;
240 
243 template<int L1, int L2, int E1, int E2, int Q1, int Q2,
244  int DL1, int DL2, int DE1, int DE2, int DQ1, int DQ2>
245 struct BinaryOpTraits<Qty<L1,E1,Q1,DL1,DE1,DQ1>,
246  Qty<L2,E2,Q2,DL2,DE2,DQ2> > {
249  typedef Qty<L1*DL2+L2*DL1,E1*DE2+E2*DE1,Q1*DQ2+Q2*DQ1,
250  DL1*DL2,DE1*DE2,DQ1*DQ2> MulT;
253  typedef Qty<L1*DL2-L2*DL1,E1*DE2-E2*DE1,Q1*DQ2-Q2*DQ1,
254  DL1*DL2,DE1*DE2,DQ1*DQ2> DivT;
255 };
256 
257 
258 template<int L1, int E1, int Q1, int DL1, int DE1, int DQ1>
259 struct BinaryOpTraits<Qty<L1,E1,Q1,DL1,DE1,DQ1>,
260  Qty<L1,E1,Q1,DL1,DE1,DQ1> > {
263  typedef Qty<2*L1,2*E1,2*Q1,
264  DL1,DE1,DQ1> MulT;
267  typedef double DivT;
268 };
269 
273 template<int L1, int E1, int Q1, int DL1, int DE1, int DQ1>
274 struct BinaryOpTraits<double,
275  Qty<L1,E1,Q1,DL1,DE1,DQ1> > {
278  typedef Qty<L1,E1,Q1,
279  DL1,DE1,DQ1> MulT;
282  typedef Qty<-L1,-E1,-Q1,
283  DL1,DE1,DQ1> DivT;
284 };
285 
289 template<int L1, int E1, int Q1, int DL1, int DE1, int DQ1>
290 struct BinaryOpTraits<Qty<L1,E1,Q1,DL1,DE1,DQ1>,
291  double> {
294  typedef Qty<L1,E1,Q1,
295  DL1,DE1,DQ1> MulT;
298  typedef Qty<L1,E1,Q1,
299  DL1,DE1,DQ1> DivT;
300 };
302 
304 
305 /** Type traits for alternative code generation*/
306 template <int L, int E, int Q, int DL, int DE, int DQ>
307 struct TypeTraits<Qty<L,E,Q,DL,DE,DQ> >
308 {
310  enum { hasDimension = true };
312  typedef DimensionT DimType;
313  static const Qty<L,E,Q,DL,DE,DQ> baseunit;
314 };
315 
317 template <int L, int E, int Q, int DL, int DE, int DQ>
318 const Qty<L,E,Q,DL,DE,DQ>
319 TypeTraits<Qty<L,E,Q,DL,DE,DQ> >::baseunit = Qty<L,E,Q,DL,DE,DQ>::baseunit();
320 
321 
323 template <int DL, int DE, int DQ>
324 struct TypeTraits<Qty<0,0,0,DL,DE,DQ> >
325 {
327  enum { hasDimension = false };
329  typedef StandardT DimType;
330  static const double baseunit;
331 };
332 
334 template <int DL, int DE, int DQ>
335 const double
336 TypeTraits<Qty<0,0,0,DL,DE,DQ> >::baseunit = 1.0;
338 
341 }
342 
343 #endif
Helper class to construct zero unitful quantities.
Definition: PhysicalQty.h:27
Helper classes to extend or shorten fractions.
Definition: PhysicalQty.h:41
Qty(double val)
Constructor from raw values. Breaks consistency.
Definition: PhysicalQty.h:85
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
double rawValue_
The raw value in units of Qty::baseunit().
Definition: PhysicalQty.h:162
static const int I
The new numerator.
Definition: PhysicalQty.h:64
static const int I
The numerator, indicating failure.
Definition: PhysicalQty.h:44
const ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:33
Template to help with fractional powers of dimensions.
Definition: PhysicalQty.h:61
static std::string className()
The name of the class for persistent IO.
Definition: PhysicalQty.h:90
This template class allows the compiler to check calculations with physical quantities for dimensiona...
Definition: PhysicalQty.h:81
Useful template machinery.