likelihoods.hpp

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * $Id: likelihoods.hpp,v 1.15 2007/10/18 05:04:29 brook Exp $
00003  */
00004 
00005 /*
00006  * Copyright (c) 2007 Brook Milligan.
00007  * Distributed under the Boost Software License, Version 1.0. (See
00008  * accompanying file LICENSE_1_0.txt or copy at
00009  * http://www.boost.org/LICENSE_1_0.txt)
00010  */
00011 
00017 #ifndef BOOST_LIKELIHOODS_HPP
00018 #define BOOST_LIKELIHOODS_HPP
00019 
00020 #include <cmath>
00021 #include <limits>
00022 #include <boost/concept_check.hpp>
00023 #include <boost/operators.hpp>
00024 #include <boost/probabilities.hpp>
00025 
00026 namespace boost
00027 {
00028 
00029   namespace probabilities
00030   {
00031 
00068     template < typename Domain = linear_domain, typename Value = double,
00069                typename Validator = null_validator<Value> >
00070     class likelihood
00071       :   boost::multiplicative<likelihood<Domain,Value,Validator>
00072         , boost::multiplicative2<likelihood<Domain,Value,Validator>,Value
00073         , boost::multiplicative2<likelihood<Domain,Value,Validator>,
00074                                  probability<Domain,Value,Validator>
00075         , boost::totally_ordered<likelihood<Domain,Value,Validator>
00076         , boost::totally_ordered2<likelihood<Domain,Value,Validator>,Value
00077         , boost::totally_ordered2<likelihood<Domain,Value,Validator>,
00078                                   probability<Domain,Value,Validator>
00079         > > > > > >
00080     {
00081     public:
00088       typedef Domain domain_type;
00095       typedef Value value_type;
00097       typedef Validator validator_type;
00098 
00099     private:
00100       BOOST_CLASS_REQUIRE(value_type, boost, AssignableConcept);
00101       BOOST_CLASS_REQUIRE(value_type, boost, CopyConstructibleConcept);
00102       BOOST_CLASS_REQUIRE(value_type, boost, EqualityComparableConcept);
00103       BOOST_CLASS_REQUIRE(value_type, boost, ComparableConcept);
00104       BOOST_CLASS_REQUIRE(validator_type, probabilities, ValidatorConcept);
00105 
00106     public:
00115       likelihood ()
00116         : l_(domain_traits<likelihood_tag,domain_type,value_type>::
00117              default_value()) 
00118         { validator_type::is_valid(l_,domain_type()); }
00127       template <typename T>
00128       explicit likelihood (const T& t)
00129         : l_(t)
00130       {
00131         function_requires< ConvertibleConcept<T,value_type> >();
00132         validator_type::is_valid(l_,domain_type());
00133       }
00142       template <typename T, typename D>
00143       likelihood (const T& t, D)
00144         : l_(domain_traits<likelihood_tag,domain_type,value_type>::
00145              transform_domain(D(),t))
00146       {
00147         function_requires< ConvertibleConcept<T,value_type> >();
00148         validator_type::is_valid(l_,domain_type());
00149       }
00151       template <typename D, typename V, typename VV>
00152       likelihood (const likelihood<D,V,VV>& l)
00153         : l_(l.value_cast(domain_type()))
00154       {
00155         function_requires< ConvertibleConcept<V,value_type> >();
00156         validator_type::is_valid(l_,domain_type());
00157       }
00161       template <typename D, typename V, typename VV>
00162       likelihood (const probability<D,V,VV>& l)
00163         : l_(l.value_cast(domain_type()))
00164       {
00165         function_requires< ConvertibleConcept<V,value_type> >();
00166         validator_type::is_valid(l_,domain_type());
00167       }
00168       likelihood (const likelihood& l) : l_(l.l_) { }
00169       ~likelihood () { }
00170       likelihood& operator = (const likelihood& l)
00171       { likelihood l_(l); swap(l_); return *this; }
00172       void swap (likelihood& l) { std::swap (l_, l.l_); }
00173       
00184 
00185       template <typename D,typename V, typename VV>
00186       likelihood& operator += (const likelihood<D,V,VV>& l)
00187       {
00188         function_requires< ConvertibleConcept<V,value_type> >();
00189         domain_traits<likelihood_tag,domain_type,value_type>::assign_add
00190           (l_,value_type(l.value_cast(domain_type())));
00191         validator_type::is_valid(l_,domain_type());
00192         return *this;
00193       }
00202       template <typename T>
00203       likelihood& operator += (const T& t)
00204       {
00205         function_requires< ConvertibleConcept<T,value_type> >();
00206         value_type domain_t
00207           (domain_traits<likelihood_tag,domain_type,value_type>::
00208            transform_domain(linear_domain(),t));
00209         domain_traits<likelihood_tag,domain_type,value_type>::
00210           assign_add(l_,domain_t);
00211         validator_type::is_valid(l_,domain_type());
00212         return *this;
00213       }
00215       template <typename D, typename V, typename VV>
00216       likelihood& operator += (const probability<D,V,VV>& p)
00217       {
00218         function_requires< ConvertibleConcept<V,value_type> >();
00219         domain_traits<likelihood_tag,domain_type,value_type>::assign_add
00220           (l_,value_type(p.value_cast(domain_type())));
00221         validator_type::is_valid(l_,domain_type());
00222         return *this;
00223       }
00224       
00226       template <typename D, typename V, typename VV>
00227       likelihood& operator -= (const likelihood<D,V,VV>& l)
00228       {
00229         function_requires< ConvertibleConcept<V,value_type> >();
00230         domain_traits<likelihood_tag,domain_type,value_type>::assign_sub
00231           (l_,value_type(l.value_cast(domain_type())));
00232         validator_type::is_valid(l_,domain_type());
00233         return *this;
00234       }
00243       template <typename T>
00244       likelihood& operator -= (const T& t)
00245       {
00246         function_requires< ConvertibleConcept<T,value_type> >();
00247         value_type domain_t
00248           (domain_traits<likelihood_tag,domain_type,value_type>::
00249            transform_domain(linear_domain(),t));
00250         domain_traits<likelihood_tag,domain_type,value_type>::
00251           assign_sub(l_,domain_t);
00252         validator_type::is_valid(l_,domain_type());
00253         return *this;
00254       }
00256       template <typename D, typename V, typename VV>
00257       likelihood& operator -= (const probability<D,V,VV>& p)
00258       {
00259         function_requires< ConvertibleConcept<V,value_type> >();
00260         domain_traits<likelihood_tag,domain_type,value_type>::assign_sub
00261           (l_,value_type(p.value_cast(domain_type())));
00262         validator_type::is_valid(l_,domain_type());
00263         return *this;
00264       }
00265       
00267       template <typename D, typename V, typename VV>
00268       likelihood& operator *= (const likelihood<D,V,VV>& l)
00269       {
00270         function_requires< ConvertibleConcept<V,value_type> >();
00271         domain_traits<likelihood_tag,domain_type,value_type>::assign_mpy
00272           (l_,value_type(l.value_cast(domain_type())));
00273         validator_type::is_valid(l_,domain_type());
00274         return *this;
00275       }
00284       template <typename T>
00285       likelihood& operator *= (const T& t)
00286       {
00287         function_requires< ConvertibleConcept<T,value_type> >();
00288         value_type domain_t
00289           (domain_traits<likelihood_tag,domain_type,value_type>::
00290            transform_domain(linear_domain(),t));
00291         domain_traits<likelihood_tag,domain_type,value_type>::
00292           assign_mpy(l_,domain_t);
00293         validator_type::is_valid(l_,domain_type());
00294         return *this;
00295       }
00297       template <typename D, typename V, typename VV>
00298       likelihood& operator *= (const probability<D,V,VV>& p)
00299       {
00300         function_requires< ConvertibleConcept<V,value_type> >();
00301         domain_traits<likelihood_tag,domain_type,value_type>::assign_mpy
00302           (l_,value_type(p.value_cast(domain_type())));
00303         validator_type::is_valid(l_,domain_type());
00304         return *this;
00305       }
00306       
00308       template <typename D, typename V, typename VV>
00309       likelihood& operator /= (const likelihood<D,V,VV>& l)
00310       {
00311         function_requires< ConvertibleConcept<V,value_type> >();
00312         domain_traits<likelihood_tag,domain_type,value_type>::assign_div
00313           (l_,value_type(l.value_cast(domain_type())));
00314         validator_type::is_valid(l_,domain_type());
00315         return *this;
00316       }
00325       template <typename T>
00326       likelihood& operator /= (const T& t)
00327       {
00328         function_requires< ConvertibleConcept<T,value_type> >();
00329         value_type domain_t
00330           (domain_traits<likelihood_tag,domain_type,value_type>::
00331            transform_domain(linear_domain(),t));
00332         domain_traits<likelihood_tag,domain_type,value_type>::
00333           assign_div(l_,domain_t);
00334         validator_type::is_valid(l_,domain_type());
00335         return *this;
00336       }
00338       template <typename D, typename V, typename VV>
00339       likelihood& operator /= (const probability<D,V,VV>& p)
00340       {
00341         function_requires< ConvertibleConcept<V,value_type> >();
00342         domain_traits<likelihood_tag,domain_type,value_type>::assign_div
00343           (l_,value_type(p.value_cast(domain_type())));
00344         validator_type::is_valid(l_,domain_type());
00345         return *this;
00346       }
00348 
00350       likelihood operator + () const { return *this; }
00351 
00353       template <typename D>
00354       likelihood<D,value_type,validator_type> domain_cast (D) const
00355       { return likelihood<D,value_type,validator_type>(value_cast(D())); }
00356 
00358       template <typename D>
00359       value_type value_cast (D) const
00360       {
00361         return domain_traits<likelihood_tag,D,value_type>::
00362           transform_domain(domain_type(),l_);
00363       }
00364 
00365     private:
00366       value_type l_;
00367     };
00368 
00370 
00371 
00381     template <typename TargetDomain, typename SourceDomain,
00382               typename Value, typename Validator>
00383     likelihood<TargetDomain,Value,Validator>
00384     domain_cast (const likelihood<SourceDomain,Value,Validator>& l)
00385     { return l.domain_cast (TargetDomain()); }
00386     
00401     template <typename TargetDomain, typename SourceDomain,
00402               typename Value, typename Validator>
00403     typename likelihood<TargetDomain,Value,Validator>::value_type
00404     value_cast (const likelihood<SourceDomain,Value,Validator>& l)
00405     { return l.value_cast(TargetDomain()); }
00407 
00409 
00410 
00411     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00412               typename Rdomain, typename Rvalue, typename Rvalidator>
00413     likelihood<Ldomain, Lvalue, Lvalidator>
00414     operator + (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,
00415                 const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)
00416     {
00417       likelihood<Ldomain,Lvalue,Lvalidator> l(lhs);
00418       l += rhs;
00419       return l;
00420     }
00422     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00423               typename Rdomain, typename Rvalue, typename Rvalidator>
00424     likelihood<Ldomain, Lvalue, Lvalidator>
00425     operator + (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,
00426                 const probability<Rdomain,Rvalue,Rvalidator>& rhs)
00427     {
00428       likelihood<Ldomain,Lvalue,Lvalidator> l(lhs);
00429       l += rhs;
00430       return l;
00431     }
00433     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00434               typename Rdomain, typename Rvalue, typename Rvalidator>
00435     likelihood<Ldomain, Lvalue, Lvalidator>
00436     operator + (const probability<Ldomain,Lvalue,Lvalidator>& lhs,
00437                 const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)
00438     {
00439       likelihood<Ldomain,Lvalue,Lvalidator> l(lhs);
00440       l += rhs;
00441       return l;
00442     }
00443 
00445     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00446               typename Rdomain, typename Rvalue, typename Rvalidator>
00447     likelihood<Ldomain, Lvalue, Lvalidator>
00448     operator - (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,
00449                 const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)
00450     {
00451       likelihood<Ldomain,Lvalue,Lvalidator> l(lhs);
00452       l -= rhs;
00453       return l;
00454     }
00455 
00457     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00458               typename Rdomain, typename Rvalue, typename Rvalidator>
00459     likelihood<log_domain, Lvalue, Lvalidator>
00460     operator * (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,
00461                 const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)
00462     {
00463       likelihood<log_domain, Lvalue, Lvalidator> p(lhs);
00464       p *= rhs;
00465       return p;
00466     }
00468     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00469               typename Rdomain, typename Rvalue, typename Rvalidator>
00470     likelihood<log_domain, Lvalue, Lvalidator>
00471     operator * (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,
00472                 const probability<Rdomain,Rvalue,Rvalidator>& rhs)
00473     {
00474       likelihood<log_domain, Lvalue, Lvalidator> p(lhs);
00475       p *= rhs;
00476       return p;
00477     }
00479     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00480               typename Rdomain, typename Rvalue, typename Rvalidator>
00481     likelihood<log_domain, Lvalue, Lvalidator>
00482     operator * (const probability<Ldomain,Lvalue,Lvalidator>& lhs,
00483                 const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)
00484     {
00485       likelihood<log_domain, Lvalue, Lvalidator> p(lhs);
00486       p *= rhs;
00487       return p;
00488     }
00489 
00491     template <typename Ldomain, typename Lvalue, typename Lvalidator,
00492               typename Rdomain, typename Rvalue, typename Rvalidator>
00493     likelihood<log_domain, Lvalue, Lvalidator>
00494     operator / (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,
00495                 const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)
00496     {
00497       likelihood<log_domain, Lvalue, Lvalidator> p(lhs);
00498       p /= rhs;
00499       return p;
00500     }
00502 
00504 
00505 
00516 #define COMPARE(OP)                                                           \
00517     template <typename Ldomain, typename Lvalue, typename Lvalidator,         \
00518               typename Rdomain, typename Rvalue, typename Rvalidator>         \
00519     bool                                                                      \
00520     operator OP (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,            \
00521                  const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)            \
00522     { return lhs.value_cast(log_domain()) OP rhs.value_cast(log_domain()); }  \
00523     template <typename Ldomain, typename Lvalue, typename Lvalidator,         \
00524               typename Rdomain, typename Rvalue, typename Rvalidator>         \
00525     bool                                                                      \
00526     operator OP (const likelihood<Ldomain,Lvalue,Lvalidator>& lhs,            \
00527                  const probability<Rdomain,Rvalue,Rvalidator>& rhs)           \
00528     { return lhs.value_cast(log_domain()) OP rhs.value_cast(log_domain()); }  \
00529     template <typename Ldomain, typename Lvalue, typename Lvalidator,         \
00530               typename Rdomain, typename Rvalue, typename Rvalidator>         \
00531     bool                                                                      \
00532     operator OP (const probability<Ldomain,Lvalue,Lvalidator>& lhs,           \
00533                  const likelihood<Rdomain,Rvalue,Rvalidator>& rhs)            \
00534     { return lhs.value_cast(log_domain()) OP rhs.value_cast(log_domain()); }
00535 
00536     COMPARE(==)
00537     COMPARE(!=)
00538     COMPARE(<)
00539     COMPARE(<=)
00540     COMPARE(>=)
00541     COMPARE(>)
00542 
00543 #undef COMPARE
00544 
00556 #define COMPARE_T(OP)                                                         \
00557     template <typename Domain,typename Value,typename Validator,typename T>   \
00558     bool                                                                      \
00559     operator OP (const likelihood<Domain,Value,Validator>& lhs, const T& rhs) \
00560     {                                                                         \
00561       function_requires< ConvertibleConcept<T,Value> >();                     \
00562       return lhs.value_cast(linear_domain()) OP rhs;                          \
00563     }                                                                         \
00564     template <typename Domain,typename Value,typename Validator,typename T>   \
00565     bool                                                                      \
00566     operator OP (const T& lhs, const likelihood<Domain,Value,Validator>& rhs) \
00567     {                                                                         \
00568       function_requires< ConvertibleConcept<T,Value> >();                     \
00569       return lhs OP rhs.value_cast(linear_domain());                          \
00570     }
00571 
00572     COMPARE_T(==)
00573     COMPARE_T(!=)
00574     COMPARE_T(<)
00575     COMPARE_T(<=)
00576     COMPARE_T(>=)
00577     COMPARE_T(>)
00578 
00579 #undef COMPARE_T
00581 
00583 
00584 
00592     template <typename Domain, typename Value, typename Validator,
00593               typename Integer>
00594     likelihood<Domain, Value, Validator>
00595     pow (const likelihood<Domain,Value,Validator>& base, Integer n)
00596     {
00597       function_requires< boost::IntegerConcept<Integer> >();
00598       return likelihood<Domain,Value,Validator>
00599         (domain_traits<likelihood_tag,Domain,Value>::
00600          pow(base.value_cast(Domain()), n));
00601     }
00603 
00604   } // namespace probabilities
00605 
00606 } // namespace boost
00607 
00608 namespace std
00609 {
00610 
00645   template <typename Domain, typename Value>
00646   struct numeric_limits< boost::probabilities::likelihood<Domain,Value> >
00647   {
00648     static const bool is_specialized = true;
00649 
00650     static Value min() throw() { return numeric_limits<Value>::min(); }
00651     static Value max() throw() { return numeric_limits<Value>::max(); }
00652 
00653     static const int digits = numeric_limits<Value>::digits;
00654     static const int digits10 = numeric_limits<Value>::digits10;
00655     static const bool is_signed = false;
00656     static const bool is_integer = numeric_limits<Value>::is_integer;
00657     static const bool is_exact = numeric_limits<Value>::is_exact;
00658     static const int radix = numeric_limits<Value>::radix;
00659     static Value epsilon() throw() { return numeric_limits<Value>::epsilon(); }
00660     static Value round_error() throw()
00661     { return numeric_limits<Value>::round_error(); }
00662 
00663     static const int min_exponent = numeric_limits<Value>::min_exponent;
00664     static const int min_exponent10 = numeric_limits<Value>::min_exponent10;
00665     static const int max_exponent = numeric_limits<Value>::max_exponent;
00666     static const int max_exponent10 = numeric_limits<Value>::max_exponent10;
00667 
00668     static const bool has_infinity = numeric_limits<Value>::has_infinity;
00669     static const bool has_quiet_NaN = numeric_limits<Value>::has_quiet_NaN;
00670     static const bool has_signaling_NaN
00671     = numeric_limits<Value>::has_signaling_NaN;
00672     static const float_denorm_style has_denorm
00673     = numeric_limits<Value>::has_denorm;
00674     static const bool has_denorm_loss = numeric_limits<Value>::has_denorm_loss;
00675 
00676     static Value infinity() throw()
00677     { return numeric_limits<Value>::infinity(); }
00678     static Value quiet_NaN() throw()
00679     { return numeric_limits<Value>::quiet_NaN(); }
00680     static Value signaling_NaN() throw()
00681     { return numeric_limits<Value>::signaling_NaN(); }
00682     static Value denorm_min() throw()
00683     { return numeric_limits<Value>::denorm_min(); }
00684 
00685     static const bool is_iec559 = numeric_limits<Value>::is_iec559;
00686     static const bool is_bounded = numeric_limits<Value>::is_bounded;
00687     static const bool is_modulo = numeric_limits<Value>::is_modulo;
00688 
00689     static const bool traps = numeric_limits<Value>::traps;
00690     static const bool tinyness_before = numeric_limits<Value>::tinyness_before;
00691     static const float_round_style round_style
00692     = numeric_limits<Value>::round_style;
00693   };
00694 
00695 } // namespace std
00696 
00697 #endif

Generated on Thu Oct 18 11:10:28 2007 for Boost.Probability: C++ Probability and Likelihood Library by  doxygen 1.4.5