add a way of calculate factorials of large numbers
This commit is contained in:
parent
f02d0fb798
commit
cd8714460e
@ -44,7 +44,7 @@ HistogramSet::operator[] (unsigned idx) const
|
|||||||
unsigned
|
unsigned
|
||||||
HistogramSet::nrHistograms (void) const
|
HistogramSet::nrHistograms (void) const
|
||||||
{
|
{
|
||||||
return Util::nrCombinations (size_ + hist_.size() - 1, hist_.size() - 1);
|
return Util::multichoose (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::nrCombinations (N + R - 1, R - 1);
|
return Util::multichoose (N, R);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,10 +69,10 @@ fromLog (Params& v)
|
|||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
factorial (double num)
|
factorial (unsigned num)
|
||||||
{
|
{
|
||||||
double result = 1.0;
|
double result = 1.0;
|
||||||
for (int i = 1; i <= num; i++) {
|
for (unsigned i = 1; i <= num; i++) {
|
||||||
result *= i;
|
result *= i;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -80,15 +80,47 @@ factorial (double num)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned
|
double
|
||||||
nrCombinations (unsigned n, unsigned r)
|
logFactorial (unsigned num)
|
||||||
{
|
{
|
||||||
assert (n >= r);
|
double result = 0.0;
|
||||||
unsigned prod = 1;
|
for (unsigned i = 1; i <= num; i++) {
|
||||||
for (int i = (int)n; i > (int)(n - r); i--) {
|
result += std::log (i);
|
||||||
prod *= i;
|
|
||||||
}
|
}
|
||||||
return (prod / factorial (r));
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
choose (unsigned n, unsigned k)
|
||||||
|
{
|
||||||
|
assert (n >= k);
|
||||||
|
int diff = n - k;
|
||||||
|
unsigned result = 0;
|
||||||
|
if (n < 150) {
|
||||||
|
unsigned prod = 1;
|
||||||
|
for (int i = n; i > diff; i--) {
|
||||||
|
prod *= i;
|
||||||
|
}
|
||||||
|
result = prod / factorial (k);
|
||||||
|
} else {
|
||||||
|
double prod = 0.0;
|
||||||
|
for (int i = n; i > diff; i--) {
|
||||||
|
prod += std::log (i);
|
||||||
|
}
|
||||||
|
prod -= logFactorial (k);
|
||||||
|
result = static_cast<unsigned> (std::exp (prod));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
multichoose (unsigned n, unsigned k)
|
||||||
|
{
|
||||||
|
return choose (n + k - 1, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -106,11 +138,11 @@ expectedSize (const Ranges& ranges)
|
|||||||
|
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
getNumberOfDigits (int number)
|
getNumberOfDigits (int num)
|
||||||
{
|
{
|
||||||
unsigned count = 1;
|
unsigned count = 1;
|
||||||
while (number >= 10) {
|
while (num >= 10) {
|
||||||
number /= 10;
|
num /= 10;
|
||||||
count ++;
|
count ++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
@ -52,9 +52,13 @@ void add (Params&, const Params&);
|
|||||||
|
|
||||||
void add (Params&, const Params&, unsigned);
|
void add (Params&, const Params&, unsigned);
|
||||||
|
|
||||||
double factorial (double);
|
double factorial (unsigned);
|
||||||
|
|
||||||
unsigned nrCombinations (unsigned, unsigned);
|
double logFactorial (unsigned);
|
||||||
|
|
||||||
|
unsigned choose (unsigned, unsigned);
|
||||||
|
|
||||||
|
unsigned multichoose (unsigned, unsigned);
|
||||||
|
|
||||||
unsigned expectedSize (const Ranges&);
|
unsigned expectedSize (const Ranges&);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user