This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/CLPBN/horus/Util.h

432 lines
8.7 KiB
C
Raw Normal View History

2013-02-07 17:50:02 +00:00
#ifndef YAP_PACKAGES_CLPBN_HORUS_UTIL_H_
#define YAP_PACKAGES_CLPBN_HORUS_UTIL_H_
2012-05-23 14:56:01 +01:00
#include <cmath>
#include <cassert>
#include <vector>
#include <queue>
2012-12-27 12:54:58 +00:00
#include <set>
2012-05-23 14:56:01 +01:00
#include <unordered_map>
2013-02-07 20:09:10 +00:00
#include <algorithm>
#include <limits>
#include <string>
2012-05-23 14:56:01 +01:00
#include <iostream>
2012-12-27 12:54:58 +00:00
#include <sstream>
2016-04-10 14:21:17 +01:00
#include <functional>
2012-05-23 14:56:01 +01:00
#include "Horus.h"
namespace Horus {
2012-05-23 14:56:01 +01:00
2012-05-24 16:14:13 +01:00
namespace {
2012-12-27 12:54:58 +00:00
const double NEG_INF = -std::numeric_limits<double>::infinity();
2013-02-07 23:53:13 +00:00
}
2012-05-24 16:14:13 +01:00
namespace Util {
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> void
addToVector (std::vector<T>&, const std::vector<T>&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> void
addToSet (std::set<T>&, const std::vector<T>&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> void
addToQueue (std::queue<T>&, const std::vector<T>&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> bool
contains (const std::vector<T>&, const T&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> bool contains
(const std::set<T>&, const T&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <typename K, typename V> bool
contains (const std::unordered_map<K, V>&, const K&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> size_t
indexOf (const std::vector<T>&, const T&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
template <class Operation> void
apply_n_times (Params& v1, const Params& v2, unsigned reps, Operation);
2013-02-07 13:37:15 +00:00
template <typename T> void
log (std::vector<T>&);
2012-05-24 16:14:13 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> void
exp (std::vector<T>&);
2012-05-24 16:14:13 +01:00
2013-02-07 13:37:15 +00:00
template <typename T> std::string
elementsToString (const std::vector<T>& v, std::string sep = " ");
2013-02-07 13:37:15 +00:00
template <typename T> std::string
toString (const T&);
2013-02-07 13:37:15 +00:00
template <> std::string
toString (const bool&);
2012-05-23 14:56:01 +01:00
double logSum (double, double);
unsigned maxUnsigned();
2013-02-07 13:37:15 +00:00
unsigned stringToUnsigned (std::string);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
double stringToDouble (std::string);
2012-05-23 14:56:01 +01:00
double factorial (unsigned);
double logFactorial (unsigned);
unsigned nrCombinations (unsigned, unsigned);
2012-05-24 22:55:20 +01:00
size_t sizeExpected (const Ranges&);
2012-05-23 14:56:01 +01:00
2012-05-24 16:14:13 +01:00
unsigned nrDigits (int);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
bool isInteger (const std::string&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
std::string parametersToString (
const Params&, unsigned = Constants::precision);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
std::vector<std::string> getStateLines (const Vars&);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
bool setHorusFlag (std::string option, std::string value);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
void printHeader (std::string, std::ostream& os = std::cout);
2012-05-23 14:56:01 +01:00
2013-02-07 13:37:15 +00:00
void printSubHeader (std::string, std::ostream& os = std::cout);
2012-05-23 14:56:01 +01:00
void printAsteriskLine (std::ostream& os = std::cout);
void printDashedLine (std::ostream& os = std::cout);
2013-02-07 23:53:13 +00:00
} // namespace Util
2012-05-23 14:56:01 +01:00
template <typename T> void
Util::addToVector (std::vector<T>& v, const std::vector<T>& elements)
2012-05-23 14:56:01 +01:00
{
v.insert (v.end(), elements.begin(), elements.end());
}
template <typename T> void
Util::addToSet (std::set<T>& s, const std::vector<T>& elements)
2012-05-23 14:56:01 +01:00
{
s.insert (elements.begin(), elements.end());
}
template <typename T> void
Util::addToQueue (std::queue<T>& q, const std::vector<T>& elements)
2012-05-23 14:56:01 +01:00
{
2012-05-24 22:55:20 +01:00
for (size_t i = 0; i < elements.size(); i++) {
2012-05-23 14:56:01 +01:00
q.push (elements[i]);
}
}
template <typename T> bool
Util::contains (const std::vector<T>& v, const T& e)
2012-05-23 14:56:01 +01:00
{
return std::find (v.begin(), v.end(), e) != v.end();
}
template <typename T> bool
Util::contains (const std::set<T>& s, const T& e)
2012-05-23 14:56:01 +01:00
{
return s.find (e) != s.end();
}
template <typename K, typename V> bool
Util::contains (const std::unordered_map<K, V>& m, const K& k)
2012-05-23 14:56:01 +01:00
{
return m.find (k) != m.end();
}
2012-05-24 22:55:20 +01:00
template <typename T> size_t
Util::indexOf (const std::vector<T>& v, const T& e)
2012-05-23 14:56:01 +01:00
{
2012-05-24 22:55:20 +01:00
return std::distance (v.begin(),
std::find (v.begin(), v.end(), e));
2012-05-23 14:56:01 +01:00
}
template <class Operation> void
Util::apply_n_times (
2013-02-07 13:37:15 +00:00
Params& v1,
const Params& v2,
unsigned repetitions,
Operation unary_op)
{
Params::iterator first = v1.begin();
Params::const_iterator last = v1.end();
Params::const_iterator first2 = v2.begin();
Params::const_iterator last2 = v2.end();
while (first != last) {
for (first2 = v2.begin(); first2 != last2; ++first2) {
std::transform (first, first + repetitions, first,
std::bind1st (unary_op, *first2));
first += repetitions;
}
}
}
template <typename T> void
Util::log (std::vector<T>& v)
2012-05-23 14:56:01 +01:00
{
std::transform (v.begin(), v.end(), v.begin(), ::log);
2012-05-23 14:56:01 +01:00
}
template <typename T> void
Util::exp (std::vector<T>& v)
2012-05-23 14:56:01 +01:00
{
std::transform (v.begin(), v.end(), v.begin(), ::exp);
2012-05-23 14:56:01 +01:00
}
2013-02-07 13:37:15 +00:00
template <typename T> std::string
Util::elementsToString (const std::vector<T>& v, std::string sep)
2012-05-24 16:14:13 +01:00
{
2013-02-07 13:37:15 +00:00
std::stringstream ss;
for (size_t i = 0; i < v.size(); i++) {
ss << ((i != 0) ? sep : "") << v[i];
}
return ss.str();
2012-05-24 16:14:13 +01:00
}
template <typename T> std::string
Util::toString (const T& t)
2012-05-24 16:14:13 +01:00
{
std::stringstream ss;
ss << t;
return ss.str();
2012-05-24 16:14:13 +01:00
}
2012-05-23 14:56:01 +01:00
inline double
Util::logSum (double x, double y)
2012-05-23 14:56:01 +01:00
{
// std::log (std::exp (x) + std::exp (y)) can overflow!
assert (std::isnan (x) == false);
assert (std::isnan (y) == false);
if (x == NEG_INF) {
return y;
}
if (y == NEG_INF) {
return x;
}
// if one value is much smaller than the other,
// keep the larger value
const double tol = 460.517; // log (1e200)
if (x < y - tol) {
return y;
}
if (y < x - tol) {
return x;
}
assert (std::isnan (x - y) == false);
const double exp_diff = std::exp (x - y);
if (std::isfinite (exp_diff) == false) {
// difference is too large
return x > y ? x : y;
}
// otherwise return the sum
return y + std::log (static_cast<double>(1.0) + exp_diff);
}
inline unsigned
Util::maxUnsigned()
2012-05-23 14:56:01 +01:00
{
2012-12-27 12:54:58 +00:00
return std::numeric_limits<unsigned>::max();
2012-05-23 14:56:01 +01:00
}
namespace LogAware {
2012-05-23 14:56:01 +01:00
inline double one() { return Globals::logDomain ? 0.0 : 1.0; }
inline double zero() { return Globals::logDomain ? NEG_INF : 0.0; }
inline double addIdenty() { return Globals::logDomain ? NEG_INF : 0.0; }
inline double multIdenty() { return Globals::logDomain ? 0.0 : 1.0; }
inline double withEvidence() { return Globals::logDomain ? 0.0 : 1.0; }
inline double noEvidence() { return Globals::logDomain ? NEG_INF : 0.0; }
inline double log (double v) { return Globals::logDomain ? ::log (v) : v; }
inline double exp (double v) { return Globals::logDomain ? ::exp (v) : v; }
2012-05-23 14:56:01 +01:00
void normalize (Params&);
double getL1Distance (const Params&, const Params&);
double getMaxNorm (const Params&, const Params&);
double pow (double, unsigned);
double pow (double, double);
void pow (Params&, unsigned);
void pow (Params&, double);
} // namespace LogAware
2012-05-23 14:56:01 +01:00
2013-02-08 00:28:32 +00:00
template <typename T> void
operator+=(std::vector<T>& v, double val)
{
std::transform (v.begin(), v.end(), v.begin(),
2013-02-07 13:37:15 +00:00
std::bind2nd (std::plus<double>(), val));
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator-=(std::vector<T>& v, double val)
{
std::transform (v.begin(), v.end(), v.begin(),
2013-02-07 13:37:15 +00:00
std::bind2nd (std::minus<double>(), val));
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator*=(std::vector<T>& v, double val)
{
std::transform (v.begin(), v.end(), v.begin(),
2013-02-07 13:37:15 +00:00
std::bind2nd (std::multiplies<double>(), val));
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator/=(std::vector<T>& v, double val)
{
std::transform (v.begin(), v.end(), v.begin(),
2013-02-07 13:37:15 +00:00
std::bind2nd (std::divides<double>(), val));
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator+=(std::vector<T>& a, const std::vector<T>& b)
{
assert (a.size() == b.size());
std::transform (a.begin(), a.end(), b.begin(), a.begin(),
2013-02-07 13:37:15 +00:00
std::plus<double>());
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator-=(std::vector<T>& a, const std::vector<T>& b)
{
assert (a.size() == b.size());
std::transform (a.begin(), a.end(), b.begin(), a.begin(),
2013-02-07 13:37:15 +00:00
std::minus<double>());
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator*=(std::vector<T>& a, const std::vector<T>& b)
{
assert (a.size() == b.size());
std::transform (a.begin(), a.end(), b.begin(), a.begin(),
2013-02-07 13:37:15 +00:00
std::multiplies<double>());
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator/=(std::vector<T>& a, const std::vector<T>& b)
{
assert (a.size() == b.size());
std::transform (a.begin(), a.end(), b.begin(), a.begin(),
2013-02-07 13:37:15 +00:00
std::divides<double>());
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator^=(std::vector<T>& v, double exp)
{
std::transform (v.begin(), v.end(), v.begin(),
2013-02-07 13:37:15 +00:00
std::bind2nd (std::ptr_fun<double, double, double> (std::pow), exp));
}
2013-02-08 00:28:32 +00:00
template <typename T> void
operator^=(std::vector<T>& v, int iexp)
{
std::transform (v.begin(), v.end(), v.begin(),
2013-02-07 13:37:15 +00:00
std::bind2nd (std::ptr_fun<double, int, double> (std::pow), iexp));
}
2013-02-08 00:28:32 +00:00
template <typename T> std::ostream&
operator<< (std::ostream& os, const std::vector<T>& v)
{
os << "[" ;
os << Util::elementsToString (v, ", ");
os << "]" ;
return os;
}
2013-02-13 19:09:11 +00:00
namespace FuncObj {
template<typename T>
2013-02-08 00:56:42 +00:00
struct max : public std::binary_function<T, T, T> {
T operator() (const T& x, const T& y) const {
return x < y ? y : x;
2013-02-08 00:56:42 +00:00
}};
template <typename T>
2013-02-08 00:56:42 +00:00
struct abs_diff : public std::binary_function<T, T, T> {
T operator() (const T& x, const T& y) const {
return std::abs (x - y);
2013-02-08 00:56:42 +00:00
}};
template <typename T>
2013-02-08 00:56:42 +00:00
struct abs_diff_exp : public std::binary_function<T, T, T> {
T operator() (const T& x, const T& y) const {
return std::abs (std::exp (x) - std::exp (y));
2013-02-08 00:56:42 +00:00
}};
2013-02-13 19:09:11 +00:00
} // namespace FuncObj
2013-02-07 23:53:13 +00:00
} // namespace Horus
2013-02-08 00:20:01 +00:00
#endif // YAP_PACKAGES_CLPBN_HORUS_UTIL_H_
2012-05-23 14:56:01 +01:00