00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _Dynamic_h
00025 #define _Dynamic_h
00026
00027
00028 #include "Quantities/Quantity/Quantity.h"
00029 #include "Quantities/Quantity/QuantityError.h"
00030
00031 namespace quantity {
00032
00034
00035
00036
00038
00040
00046 template<typename ST> class Dynamic
00047 {
00048 private:
00050 ST _value;
00051
00052 public:
00053 const long _rl_n;
00054 const long _rl_d;
00055 const long _rm_n;
00056 const long _rm_d;
00057 const long _rt_n;
00058 const long _rt_d;
00059 const long _re_n;
00060 const long _re_d;
00061 const long _rte_n;
00062 const long _rte_d;
00063 const long _ra_n;
00064 const long _ra_d;
00065 const long _rlu_n;
00066 const long _rlu_d;
00067
00068 private:
00070
00072 Dynamic (void);
00073
00075
00084 Dynamic
00085 (const long rl_n, const long rl_d,
00086 const long rm_n, const long rm_d,
00087 const long rt_n, const long rt_d,
00088 const long re_n, const long re_d,
00089 const long rte_n, const long rte_d,
00090 const long ra_n, const long ra_d,
00091 const long rlu_n, const long rlu_d, const ST value)
00092 : _value (value),
00093 _rl_n (rl_n/BSUtilities::gcd(rl_n, rl_d)),
00094 _rl_d (rl_d/BSUtilities::gcd(rl_n, rl_d)),
00095 _rm_n (rm_n/BSUtilities::gcd(rm_n, rm_d)),
00096 _rm_d (rm_d/BSUtilities::gcd(rm_n, rm_d)),
00097 _rt_n (rt_n/BSUtilities::gcd(rt_n, rt_d)),
00098 _rt_d (rt_d/BSUtilities::gcd(rt_n, rt_d)),
00099 _re_n (re_n/BSUtilities::gcd(re_n, re_d)),
00100 _re_d (re_d/BSUtilities::gcd(re_n, re_d)),
00101 _rte_n (rte_n/BSUtilities::gcd(rte_n, rte_d)),
00102 _rte_d (rte_d/BSUtilities::gcd(rte_n, rte_d)),
00103 _ra_n (ra_n/BSUtilities::gcd(ra_n, ra_d)),
00104 _ra_d (ra_d/BSUtilities::gcd(ra_n, ra_d)),
00105 _rlu_n (rlu_n/BSUtilities::gcd(rlu_n, rlu_d)),
00106 _rlu_d (rlu_d/BSUtilities::gcd(rlu_n, rlu_d)) {}
00107
00108 public:
00110 Dynamic (const Dynamic &dynamic)
00111 : _value (dynamic._value),
00112 _rl_n (dynamic._rl_n), _rl_d (dynamic._rl_d),
00113 _rm_n (dynamic._rm_n), _rm_d (dynamic._rm_d),
00114 _rt_n (dynamic._rt_n), _rt_d (dynamic._rt_d),
00115 _re_n (dynamic._re_n), _re_d (dynamic._re_d),
00116 _rte_n (dynamic._rte_n), _rte_d (dynamic._rte_d),
00117 _ra_n (dynamic._ra_n), _ra_d (dynamic._ra_d),
00118 _rlu_n (dynamic._rlu_n), _rlu_d (dynamic._rlu_d)
00119 {}
00120
00122 void operator= (const Dynamic &dynamic)
00123 {_rl_n = dynamic._rl_n;
00124 _rl_d = dynamic._rl_d;
00125 _rm_n = dynamic._rm_n;
00126 _rm_d = dynamic._rm_d;
00127 _rt_n = dynamic._rt_n;
00128 _rt_d = dynamic._rt_d;
00129 _re_n = dynamic._re_n;
00130 _re_d = dynamic._re_d;
00131 _rte_n = dynamic._rte_n;
00132 _rte_d = dynamic._rte_d;
00133 _ra_n = dynamic._ra_n;
00134 _ra_d = dynamic._ra_d;
00135 _rlu_n = dynamic._rlu_n;
00136 _rlu_d = dynamic._rlu_d;
00137 _value = dynamic._value;
00138 }
00139
00141 ST value (void) const {return _value;}
00142
00144
00146 template<typename FST>
00147 Dynamic operator*= (const FST factor)
00148 {_value *= factor; return *this;}
00149
00151
00154 template<typename FST>
00155 Dynamic operator* (const FST factor) const
00156 {return Dynamic (*this) *= factor;}
00157
00159 template<typename FST>
00160 friend Dynamic operator* (const FST factor, const Dynamic &quantity)
00161 {return Dynamic (quantity * factor);}
00162
00164
00170 template <template<typename, typename> class SM, typename QT, typename RHST,
00171 typename RHSU, typename RHDQT>
00172 Dynamic operator* (const SM<Quantity<QT, RHST>, DerivedQuantity<QT, RHSU, RHDQT> > &factor) const
00173 {
00174 typedef typename QuantityTraits<QT>::Dimension Dim;
00175 return Dynamic (
00176 (_rl_n * Dim::canonicalDenomRL) + (Dim::canonicalNumRL *_rl_d),
00177 _rl_d * Dim::canonicalDenomRL,
00178 (_rm_n * Dim::canonicalDenomRM) + (Dim::canonicalNumRM * _rm_d),
00179 _rm_d * Dim::canonicalDenomRM,
00180 (_rt_n * Dim::canonicalDenomRT) + (Dim::canonicalNumRT * _rt_d),
00181 _rt_d * Dim::canonicalDenomRT,
00182 (_re_n * Dim::canonicalDenomRE) + (Dim::canonicalNumRE * _re_d),
00183 _re_d * Dim::canonicalDenomRE,
00184 (_rte_n * Dim::canonicalDenomRTE) + (Dim::canonicalNumRTE * _rte_d),
00185 _rte_d * Dim::canonicalDenomRTE,
00186 (_ra_n * Dim::canonicalDenomRA) + (Dim::canonicalNumRA * _ra_d),
00187 _ra_d * Dim::canonicalDenomRA,
00188 (_rlu_n * Dim::canonicalDenomRLU) + (Dim::canonicalNumRLU * _rlu_d),
00189 _rlu_d * Dim::canonicalDenomRLU,
00190 _value * unit::Standard<RHSU>::VAL (factor.value ()));
00191 }
00192
00194
00196 Dynamic operator/= (const ST divisor)
00197 {_value /= divisor; return *this;}
00198
00199
00203 Dynamic operator/ (const ST divisor)
00204 {return Dynamic (*this) /= divisor;}
00205
00207
00209 Dynamic operator+ (void) const {return Dynamic (*this);}
00210
00212
00215 Dynamic operator- (void) const
00216 {return Dynamic (*this) *= ST (-1.0);}
00217
00219
00223 template<template<typename, typename> class Q1, typename QT, typename ST1,
00224 typename DQ>
00225 bool isCommensurable (const Q1<Quantity<QT, ST1>, DQ> &) const
00226 {
00228 typedef typename QuantityTraits<QT>::Dimension Dim;
00229
00230 return (_rl_n == Dim::canonicalNumRL
00231 && _rl_d == Dim::canonicalDenomRL
00232 && _rm_n == Dim::canonicalNumRM
00233 && _rm_d == Dim::canonicalDenomRM
00234 && _rt_n == Dim::canonicalNumRT
00235 && _rt_d == Dim::canonicalDenomRT
00236 && _re_n == Dim::canonicalNumRE
00237 && _re_d == Dim::canonicalDenomRE
00238 && _rte_n == Dim::canonicalNumRTE
00239 && _rte_d == Dim::canonicalDenomRTE
00240 && _ra_n == Dim::canonicalNumRA
00241 && _ra_d == Dim::canonicalDenomRA
00242 && _rlu_n == Dim::canonicalNumRLU
00243 && _rlu_d == Dim::canonicalDenomRLU);
00244 }
00245
00247
00251 template<typename ST1>
00252 bool isCommensurable (const Dynamic<ST1> &quantity) const
00253 {
00254 return (_rl_n == quantity._rl_n
00255 && _rl_d == quantity._rl_d
00256 && _rm_n == quantity._rm_n
00257 && _rm_d == quantity._rm_d
00258 && _rt_n == quantity._rt_n
00259 && _rt_d == quantity._rt_d
00260 && _re_n == quantity._re_n
00261 && _re_d == quantity._re_d
00262 && _rte_n == quantity._rte_n
00263 && _rte_d == quantity._rte_d
00264 && _ra_n == quantity._ra_n
00265 && _ra_d == quantity._ra_d
00266 && _rlu_n == quantity._rlu_n
00267 && _rlu_d == quantity._rlu_d);
00268 }
00269
00271
00278 template<template<typename, typename> class Q1, typename QT, typename ST1,
00279 typename SU>
00280 bool operator== (const Q1<Quantity<QT, ST1>, SU> &quantity)
00281 {
00282 if (isCommensurable (quantity))
00283 return value () == quantity.standard_value ();
00284
00285 else
00286 {throw DimensionMismatch ();}
00287
00288 }
00289
00291
00297 template<typename ST1>
00298 bool operator== (Dynamic<ST1> quantity)
00299 {if (isCommensurable (quantity))
00300 return value () == quantity.value ();
00301
00302 else
00303 {throw DimensionMismatch ();}
00304
00305 }
00306
00308
00314 template<template<typename, typename> class Q1, typename QT, typename ST1,
00315 typename SU>
00316 bool operator!= (const Q1<Quantity<QT, ST1>, SU> &quantity)
00317 {
00318 if (isCommensurable (quantity))
00319 return value () != quantity.standard_value ();
00320
00321 else
00322 {throw DimensionMismatch ();}
00323
00324 }
00325
00327
00333 template<typename ST1>
00334 bool operator!= (Dynamic<ST1> quantity)
00335 {if (isCommensurable (quantity))
00336 return value () != quantity.value ();
00337
00338 else
00339 {throw DimensionMismatch ();}
00340
00341 }
00342
00344
00350 template<template<typename, typename> class Q1, typename QT, typename ST1,
00351 typename SU>
00352 bool operator> (const Q1<Quantity<QT, ST1>, SU> &quantity)
00353 {
00354 if (isCommensurable (quantity))
00355 return value () > quantity.standard_value ();
00356
00357 else
00358 {throw DimensionMismatch ();}
00359
00360 }
00361
00363
00369 template<typename ST1>
00370 bool operator> (Dynamic<ST1> quantity)
00371 {if (isCommensurable (quantity))
00372 return value () > quantity.value ();
00373
00374 else
00375 {throw DimensionMismatch ();}
00376
00377 }
00378
00380
00386 template<template<typename, typename> class Q1, typename QT, typename ST1,
00387 typename SU>
00388 bool operator< (const Q1<Quantity<QT, ST1>, SU> &quantity)
00389 {
00390 if (isCommensurable (quantity))
00391 return value () < quantity.standard_value ();
00392
00393 else
00394 {throw DimensionMismatch ();}
00395
00396 }
00397
00399
00405 template<typename ST1>
00406 bool operator< (Dynamic<ST1> quantity)
00407 {if (isCommensurable (quantity))
00408 return value () < quantity.value ();
00409
00410 else
00411 {throw DimensionMismatch ();}
00412
00413 }
00414
00416
00422 template<template<typename, typename> class Q1, typename QT, typename ST1,
00423 typename SU>
00424 bool operator>= (const Q1<Quantity<QT, ST1>, SU> &quantity)
00425 {
00426 if (isCommensurable (quantity))
00427 return value () >= quantity.standard_value ();
00428
00429 else
00430 {throw DimensionMismatch ();}
00431
00432 }
00433
00435
00441 template<typename ST1>
00442 bool operator>= (Dynamic<ST1> quantity)
00443 {if (isCommensurable (quantity))
00444 return value () >= quantity.value ();
00445
00446 else
00447 {throw DimensionMismatch ();}
00448
00449 }
00450
00452
00458 template<template<typename, typename> class Q1, typename QT, typename ST1,
00459 typename SU>
00460 bool operator<= (const Q1<Quantity<QT, ST1>, SU> &quantity)
00461 {
00462 if (isCommensurable (quantity))
00463 return value () <= quantity.standard_value ();
00464
00465 else
00466 {throw DimensionMismatch ();}
00467
00468 }
00469
00471
00477 template<typename ST1>
00478 bool operator<= (Dynamic<ST1> quantity)
00479 {if (isCommensurable (quantity))
00480 return value () <= quantity.value ();
00481
00482 else
00483 {throw DimensionMismatch ();}
00484
00485 }
00486
00488
00491 template<template<typename, typename> class Q1, typename QT,
00492 typename SU>
00493 static Dynamic<ST>
00494 pow (const Q1<Quantity<QT, ST>, SU> &quantity, const int &exp)
00495 {
00496 typedef typename QuantityTraits<QT>::Dimension Dim;
00497
00498 return
00499 Dynamic<ST>
00500 (Dim::canonicalNumRL * exp, Dim::canonicalDenomRL,
00501 Dim::canonicalNumRM * exp, Dim::canonicalDenomRM,
00502 Dim::canonicalNumRT * exp, Dim::canonicalDenomRT,
00503 Dim::canonicalNumRE * exp, Dim::canonicalDenomRE,
00504 Dim::canonicalNumRTE * exp, Dim::canonicalDenomRTE,
00505 Dim::canonicalNumRA * exp, Dim::canonicalDenomRA,
00506 Dim::canonicalNumRLU * exp, Dim::canonicalDenomRLU,
00507 ST(std::pow(quantity.standard_value (), exp)));
00508 }
00509
00511
00516 template<template<typename, typename> class Q1, typename QT,
00517 typename SU>
00518 static Dynamic<ST> pow (const Q1<Quantity<QT, ST>, SU> &quantity,
00519 const long int &exp)
00520 {
00521 typedef typename QuantityTraits<QT>::Dimension Dim;
00522
00523 return
00524 Dynamic<ST>
00525 (Dim::canonicalNumRL * exp, Dim::canonicalDenomRL,
00526 Dim::canonicalNumRM * exp, Dim::canonicalDenomRM,
00527 Dim::canonicalNumRT * exp, Dim::canonicalDenomRT,
00528 Dim::canonicalNumRE * exp, Dim::canonicalDenomRE,
00529 Dim::canonicalNumRTE * exp, Dim::canonicalDenomRTE,
00530 Dim::canonicalNumRA * exp, Dim::canonicalDenomRA,
00531 Dim::canonicalNumRLU * exp, Dim::canonicalDenomRLU,
00532 ST(std::pow(quantity.standard_value (), double(exp))));
00533 }
00534
00536
00540 template<template<typename, typename> class Q1, typename QT,
00541 typename SU>
00542 static Dynamic<ST> pow (const Q1<Quantity<QT, ST>, SU> &quantity,
00543 const double &exp)
00544 {
00545 std::pair<long, long> rational = BSUtilities::contFrac (exp);
00546
00547 typedef typename QuantityTraits<QT>::Dimension Dim;
00548
00549 return
00550 Dynamic<ST>
00551 (Dim::canonicalNumRL * rational.first,
00552 Dim::canonicalDenomRL * rational.second,
00553 Dim::canonicalNumRM * rational.first,
00554 Dim::canonicalDenomRM * rational.second,
00555 Dim::canonicalNumRT * rational.first,
00556 Dim::canonicalDenomRT * rational.second,
00557 Dim::canonicalNumRE * rational.first,
00558 Dim::canonicalDenomRE * rational.second,
00559 Dim::canonicalNumRTE * rational.first,
00560 Dim::canonicalDenomRTE * rational.second,
00561 Dim::canonicalNumRA * rational.first,
00562 Dim::canonicalDenomRA * rational.second,
00563 Dim::canonicalNumRLU * rational.first,
00564 Dim::canonicalDenomRLU * rational.second,
00565 ST(std::pow(quantity.standard_value (), exp)));
00566 }
00567
00568 };
00569
00570 }
00571
00572 #endif