Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bob
bob.core
Commits
7ec3e39b
Commit
7ec3e39b
authored
Oct 27, 2014
by
Manuel Günther
Browse files
Added new boost headers for gamma distribution as well.
parent
f90e424e
Changes
4
Hide whitespace changes
Inline
Side-by-side
bob/core/include/bob.core/boost/exponential_distribution.hpp
View file @
7ec3e39b
...
...
@@ -24,7 +24,6 @@
#include <boost/random/detail/config.hpp>
#include <boost/random/uniform_01.hpp>
#include <bob.core/boost/operators.hpp>
namespace
bob
{
...
...
bob/core/include/bob.core/boost/gamma_distribution.hpp
0 → 100644
View file @
7ec3e39b
/* boost random/gamma_distribution.hpp header file
*
* Copyright Jens Maurer 2002
* Copyright Steven Watanabe 2010
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOB_BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
#define BOB_BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <istream>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/uniform_01.hpp>
#include <bob.core/boost/exponential_distribution.hpp>
namespace
bob
{
namespace
core
{
namespace
random
{
// The algorithm is taken from Knuth
/**
* The gamma distribution is a continuous distribution with two
* parameters alpha and beta. It produces values > 0.
*
* It has
* \f$\displaystyle p(x) = x^{\alpha-1}\frac{e^{-x/\beta}}{\beta^\alpha\Gamma(\alpha)}\f$.
*/
template
<
class
RealType
=
double
>
class
gamma_distribution
{
public:
typedef
RealType
input_type
;
typedef
RealType
result_type
;
class
param_type
{
public:
typedef
gamma_distribution
distribution_type
;
/**
* Constructs a @c param_type object from the "alpha" and "beta"
* parameters.
*
* Requires: alpha > 0 && beta > 0
*/
param_type
(
const
RealType
&
alpha_arg
=
RealType
(
1.0
),
const
RealType
&
beta_arg
=
RealType
(
1.0
))
:
_alpha
(
alpha_arg
),
_beta
(
beta_arg
)
{
}
/** Returns the "alpha" parameter of the distribution. */
RealType
alpha
()
const
{
return
_alpha
;
}
/** Returns the "beta" parameter of the distribution. */
RealType
beta
()
const
{
return
_beta
;
}
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters to a @c std::ostream. */
template
<
class
CharT
,
class
Traits
>
friend
std
::
basic_ostream
<
CharT
,
Traits
>&
operator
<<
(
std
::
basic_ostream
<
CharT
,
Traits
>&
os
,
const
param_type
&
parm
)
{
os
<<
parm
.
_alpha
<<
' '
<<
parm
.
_beta
;
return
os
;
}
/** Reads the parameters from a @c std::istream. */
template
<
class
CharT
,
class
Traits
>
friend
std
::
basic_istream
<
CharT
,
Traits
>&
operator
>>
(
std
::
basic_istream
<
CharT
,
Traits
>&
is
,
param_type
&
parm
)
{
is
>>
parm
.
_alpha
>>
std
::
ws
>>
parm
.
_beta
;
return
is
;
}
#endif
/** Returns true if the two sets of parameters are the same. */
friend
bool
operator
==
(
const
param_type
&
lhs
,
const
param_type
&
rhs
)
{
return
lhs
.
_alpha
==
rhs
.
_alpha
&&
lhs
.
_beta
==
rhs
.
_beta
;
}
/** Returns true if the two sets fo parameters are different. */
friend
bool
operator
!=
(
const
param_type
&
lhs
,
const
param_type
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
private:
RealType
_alpha
;
RealType
_beta
;
};
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT
(
!
std
::
numeric_limits
<
RealType
>::
is_integer
);
#endif
/**
* Creates a new gamma_distribution with parameters "alpha" and "beta".
*
* Requires: alpha > 0 && beta > 0
*/
explicit
gamma_distribution
(
const
result_type
&
alpha_arg
=
result_type
(
1.0
),
const
result_type
&
beta_arg
=
result_type
(
1.0
))
:
_exp
(
result_type
(
1
)),
_alpha
(
alpha_arg
),
_beta
(
beta_arg
)
{
BOOST_ASSERT
(
_alpha
>
result_type
(
0
));
BOOST_ASSERT
(
_beta
>
result_type
(
0
));
init
();
}
/** Constructs a @c gamma_distribution from its parameters. */
explicit
gamma_distribution
(
const
param_type
&
parm
)
:
_exp
(
result_type
(
1
)),
_alpha
(
parm
.
alpha
()),
_beta
(
parm
.
beta
())
{
init
();
}
// compiler-generated copy ctor and assignment operator are fine
/** Returns the "alpha" paramter of the distribution. */
RealType
alpha
()
const
{
return
_alpha
;
}
/** Returns the "beta" parameter of the distribution. */
RealType
beta
()
const
{
return
_beta
;
}
/** Returns the smallest value that the distribution can produce. */
RealType
min
BOOST_PREVENT_MACRO_SUBSTITUTION
()
const
{
return
0
;
}
/* Returns the largest value that the distribution can produce. */
RealType
max
BOOST_PREVENT_MACRO_SUBSTITUTION
()
const
{
return
(
std
::
numeric_limits
<
RealType
>::
infinity
)();
}
/** Returns the parameters of the distribution. */
param_type
param
()
const
{
return
param_type
(
_alpha
,
_beta
);
}
/** Sets the parameters of the distribution. */
void
param
(
const
param_type
&
parm
)
{
_alpha
=
parm
.
alpha
();
_beta
=
parm
.
beta
();
init
();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void
reset
()
{
_exp
.
reset
();
}
/**
* Returns a random variate distributed according to
* the gamma distribution.
*/
template
<
class
Engine
>
result_type
operator
()(
Engine
&
eng
)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using
std
::
tan
;
using
std
::
sqrt
;
using
std
::
exp
;
using
std
::
log
;
using
std
::
pow
;
#endif
if
(
_alpha
==
result_type
(
1
))
{
return
_exp
(
eng
)
*
_beta
;
}
else
if
(
_alpha
>
result_type
(
1
))
{
// Can we have a boost::mathconst please?
const
result_type
pi
=
result_type
(
3.14159265358979323846
);
for
(;;)
{
result_type
y
=
tan
(
pi
*
boost
::
uniform_01
<
RealType
>
()(
eng
));
result_type
x
=
sqrt
(
result_type
(
2
)
*
_alpha
-
result_type
(
1
))
*
y
+
_alpha
-
result_type
(
1
);
if
(
x
<=
result_type
(
0
))
continue
;
if
(
boost
::
uniform_01
<
RealType
>
()(
eng
)
>
(
result_type
(
1
)
+
y
*
y
)
*
exp
((
_alpha
-
result_type
(
1
))
*
log
(
x
/
(
_alpha
-
result_type
(
1
)))
-
sqrt
(
result_type
(
2
)
*
_alpha
-
result_type
(
1
))
*
y
))
continue
;
return
x
*
_beta
;
}
}
else
/* alpha < 1.0 */
{
for
(;;)
{
result_type
u
=
boost
::
uniform_01
<
RealType
>
()(
eng
);
result_type
y
=
_exp
(
eng
);
result_type
x
,
q
;
if
(
u
<
_p
)
{
x
=
exp
(
-
y
/
_alpha
);
q
=
_p
*
exp
(
-
x
);
}
else
{
x
=
result_type
(
1
)
+
y
;
q
=
_p
+
(
result_type
(
1
)
-
_p
)
*
pow
(
x
,
_alpha
-
result_type
(
1
));
}
if
(
u
>=
q
)
continue
;
return
x
*
_beta
;
}
}
}
template
<
class
URNG
>
RealType
operator
()(
URNG
&
urng
,
const
param_type
&
parm
)
const
{
return
gamma_distribution
(
parm
)(
urng
);
}
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes a @c gamma_distribution to a @c std::ostream. */
template
<
class
CharT
,
class
Traits
>
friend
std
::
basic_ostream
<
CharT
,
Traits
>&
operator
<<
(
std
::
basic_ostream
<
CharT
,
Traits
>&
os
,
const
gamma_distribution
&
gd
)
{
os
<<
gd
.
param
();
return
os
;
}
/** Reads a @c gamma_distribution from a @c std::istream. */
template
<
class
CharT
,
class
Traits
>
friend
std
::
basic_istream
<
CharT
,
Traits
>&
operator
>>
(
std
::
basic_istream
<
CharT
,
Traits
>&
is
,
gamma_distribution
&
gd
)
{
gd
.
read
(
is
);
return
is
;
}
#endif
/**
* Returns true if the two distributions will produce identical
* sequences of random variates given equal generators.
*/
friend
bool
operator
==
(
const
gamma_distribution
&
lhs
,
const
gamma_distribution
&
rhs
)
{
return
lhs
.
_alpha
==
rhs
.
_alpha
&&
lhs
.
_beta
==
rhs
.
_beta
&&
lhs
.
_exp
==
rhs
.
_exp
;
}
/**
* Returns true if the two distributions can produce different
* sequences of random variates, given equal generators.
*/
friend
bool
operator
!=
(
const
gamma_distribution
&
lhs
,
const
gamma_distribution
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
private:
/// \cond hide_private_members
template
<
class
CharT
,
class
Traits
>
void
read
(
std
::
basic_istream
<
CharT
,
Traits
>&
is
)
{
param_type
parm
;
if
(
is
>>
parm
)
{
param
(
parm
);
}
}
void
init
()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using
std
::
exp
;
#endif
_p
=
exp
(
result_type
(
1
))
/
(
_alpha
+
exp
(
result_type
(
1
)));
}
/// \endcond
bob
::
core
::
random
::
exponential_distribution
<
RealType
>
_exp
;
result_type
_alpha
;
result_type
_beta
;
// some data precomputed from the parameters
result_type
_p
;
};
}
}
}
// namespaces
#endif // BOB_BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
bob/core/include/bob.core/random.h
View file @
7ec3e39b
...
...
@@ -21,12 +21,16 @@ namespace bob { namespace core { namespace random {
template
<
class
RealType
=
double
>
using
lognormal_distribution
=
boost
::
random
::
lognormal_distribution
<
RealType
>
;
template
<
class
RealType
=
double
>
using
gamma_distribution
=
boost
::
random
::
gamma_distribution
<
RealType
>
;
template
<
class
IntType
=
int
,
class
RealType
=
double
>
using
binomial_distribution
=
boost
::
random
::
binomial_distribution
<
IntType
,
RealType
>
;
template
<
class
IntType
,
class
WeightType
>
template
<
class
IntType
=
int
,
class
WeightType
=
double
>
using
discrete_distribution
=
boost
::
random
::
discrete_distribution
<
IntType
,
WeightType
>
;
}
}
}
// namespaces
#else
...
...
@@ -37,6 +41,7 @@ namespace bob { namespace core { namespace random {
#include <bob.core/boost/lognormal_distribution.hpp>
#include <bob.core/boost/binomial_distribution.hpp>
#include <bob.core/boost/discrete_distribution.hpp>
#include <bob.core/boost/gamma_distribution.hpp>
#endif // BOOST VERSION
...
...
bob/core/random/gamma.cpp
View file @
7ec3e39b
...
...
@@ -53,7 +53,7 @@ template <typename T>
boost
::
shared_ptr
<
void
>
make_gamma
(
PyObject
*
alpha
)
{
T
calpha
=
1.
;
if
(
alpha
)
calpha
=
PyBlitzArrayCxx_AsCScalar
<
T
>
(
alpha
);
return
boost
::
make_shared
<
bo
ost
::
gamma_distribution
<
T
>>
(
calpha
);
return
boost
::
make_shared
<
bo
b
::
core
::
random
::
gamma_distribution
<
T
>>
(
calpha
);
}
PyObject
*
PyBoostGamma_SimpleNew
(
int
type_num
,
PyObject
*
alpha
)
{
...
...
@@ -130,7 +130,7 @@ int PyBoostGamma_Converter(PyObject* o, PyBoostGammaObject** a) {
}
template
<
typename
T
>
PyObject
*
get_alpha
(
PyBoostGammaObject
*
self
)
{
return
PyBlitzArrayCxx_FromCScalar
(
boost
::
static_pointer_cast
<
bo
ost
::
gamma_distribution
<
T
>>
(
self
->
distro
)
->
alpha
());
return
PyBlitzArrayCxx_FromCScalar
(
boost
::
static_pointer_cast
<
bo
b
::
core
::
random
::
gamma_distribution
<
T
>>
(
self
->
distro
)
->
alpha
());
}
/**
...
...
@@ -156,7 +156,7 @@ static PyObject* PyBoostGamma_GetDtype(PyBoostGammaObject* self) {
}
template
<
typename
T
>
PyObject
*
reset
(
PyBoostGammaObject
*
self
)
{
boost
::
static_pointer_cast
<
bo
ost
::
gamma_distribution
<
T
>>
(
self
->
distro
)
->
reset
();
boost
::
static_pointer_cast
<
bo
b
::
core
::
random
::
gamma_distribution
<
T
>>
(
self
->
distro
)
->
reset
();
Py_RETURN_NONE
;
}
...
...
@@ -177,7 +177,7 @@ static PyObject* PyBoostGamma_Reset(PyBoostGammaObject* self) {
}
template
<
typename
T
>
PyObject
*
call
(
PyBoostGammaObject
*
self
,
PyBoostMt19937Object
*
rng
)
{
typedef
bo
ost
::
gamma_distribution
<
T
>
distro_t
;
typedef
bo
b
::
core
::
random
::
gamma_distribution
<
T
>
distro_t
;
return
PyBlitzArrayCxx_FromCScalar
((
*
boost
::
static_pointer_cast
<
distro_t
>
(
self
->
distro
))(
*
rng
->
rng
));
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment