improvements in the way factorials are computed

This commit is contained in:
Tiago Gomes 2012-04-18 02:46:38 +01:00
parent cd8714460e
commit d8e757f9ab
3 changed files with 15 additions and 20 deletions

View File

@ -44,7 +44,7 @@ HistogramSet::operator[] (unsigned idx) const
unsigned unsigned
HistogramSet::nrHistograms (void) const HistogramSet::nrHistograms (void) const
{ {
return Util::multichoose (size_, hist_.size()); return HistogramSet::nrHistograms (size_, hist_.size());
} }
@ -77,7 +77,7 @@ HistogramSet::getHistograms (unsigned N, unsigned R)
unsigned unsigned
HistogramSet::nrHistograms (unsigned N, unsigned R) HistogramSet::nrHistograms (unsigned N, unsigned R)
{ {
return Util::multichoose (N, R); return Util::nrCombinations (N + R - 1, R - 1);
} }
@ -99,16 +99,17 @@ vector<double>
HistogramSet::getNumAssigns (unsigned N, unsigned R) HistogramSet::getNumAssigns (unsigned N, unsigned R)
{ {
HistogramSet hs (N, R); HistogramSet hs (N, R);
unsigned N_factorial = Util::factorial (N); double N_fac = Util::logFactorial (N);
unsigned H = hs.nrHistograms(); unsigned H = hs.nrHistograms();
vector<double> numAssigns; vector<double> numAssigns;
numAssigns.reserve (H); numAssigns.reserve (H);
for (unsigned h = 0; h < H; h++) { for (unsigned h = 0; h < H; h++) {
unsigned prod = 1; double prod = 0.0;
for (unsigned r = 0; r < R; r++) { for (unsigned r = 0; r < R; r++) {
prod *= Util::factorial (hs[r]); prod += Util::logFactorial (hs[r]);
} }
numAssigns.push_back (LogAware::tl (N_factorial / prod)); double res = N_fac - prod;
numAssigns.push_back (Globals::logDomain ? res : std::exp (res));
hs.nextHistogram(); hs.nextHistogram();
} }
return numAssigns; return numAssigns;

View File

@ -84,8 +84,12 @@ double
logFactorial (unsigned num) logFactorial (unsigned num)
{ {
double result = 0.0; double result = 0.0;
for (unsigned i = 1; i <= num; i++) { if (num < 150) {
result += std::log (i); result = std::log (factorial (num));
} else {
for (unsigned i = 1; i <= num; i++) {
result += std::log (i);
}
} }
return result; return result;
} }
@ -93,7 +97,7 @@ logFactorial (unsigned num)
unsigned unsigned
choose (unsigned n, unsigned k) nrCombinations (unsigned n, unsigned k)
{ {
assert (n >= k); assert (n >= k);
int diff = n - k; int diff = n - k;
@ -117,14 +121,6 @@ choose (unsigned n, unsigned k)
unsigned
multichoose (unsigned n, unsigned k)
{
return choose (n + k - 1, k);
}
unsigned unsigned
expectedSize (const Ranges& ranges) expectedSize (const Ranges& ranges)
{ {

View File

@ -56,9 +56,7 @@ double factorial (unsigned);
double logFactorial (unsigned); double logFactorial (unsigned);
unsigned choose (unsigned, unsigned); unsigned nrCombinations (unsigned, unsigned);
unsigned multichoose (unsigned, unsigned);
unsigned expectedSize (const Ranges&); unsigned expectedSize (const Ranges&);