Dynamic.h

Go to the documentation of this file.
00001 
00005 /* Copyright (C) 2002 - 2009, Bernd Speiser */
00006 /* This file is part of Quantity.
00007 
00008 Quantity is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 Quantity is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017   
00018 You should have received a copy of the GNU General Public License
00019 along with this program; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00021 02111-1307, USA.
00022 */
00023 
00024 #ifndef _Dynamic_h
00025 #define _Dynamic_h
00026 
00027 // Quantity includes
00028 #include "Quantity/Quantity.h"
00029 #include "Quantity/QuantityError.h"
00030 
00031 namespace quantity {
00032 
00034 //
00035 //  the Dynamic quantity
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 * Standardize<RHSU, RHST>::VAL (factor.value ()));
00191     }
00192 
00194 
00196     Dynamic operator/= (const ST divisor) 
00197                                       {_value /= divisor; return *this;}
00198 
00199 //* operator/ for right hand side division by an ST
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 } // end namespace quantity
00571 
00572 #endif /* _Dynamic_h */

Generated on Mon Jul 27 15:55:44 2009 for Quantities by  doxygen 1.5.3