Skip to content

Multifactorial for IntMath, BigIntegerMath and LongMath #7430

@siemieniuk

Description

@siemieniuk

1. What are you trying to do?

I tried to calculate a number of possible Stirling permutations, which is defined as $n!!$, where n >= 0.

Initially I thought about creating an issue related to implement in Guava a method called doubleFactorial(n), however since doubleFactorial is a special case of multifactorial, I thought whether it wouldn't be more beneficial to just implement a generalization of the mentioned concept.

Multifactorial is defined as:

multifactorial(n, k) =

  • n * multifactorial(n - k, k), if $n \gt k$
  • n, if $1 \le n \le k$
  • multifactorial(n+k, k) / (n + k), if $n \le 0$ and $n$ is not a negative multiple of $k$

Examples:

  • multifactorial(n, 1) produces exactly the same as n!
  • multifactorial(n, 2) is the same as double factorial, so n(n-2)(n-4)...
  • multifactorial(n, 3) means n(n-3)(n-6)...

2. What's the best code you can write to accomplish that without the new feature?

I had to implement double factorial by hand, such like:

int doubleFactorial(int n) {
    if (n == 0 || n == 1) {
        return 1;
    }
    int res = n;
    for (int i=n-2; i>1; i-=2) {
        res *= i;
    }
    return res;
}

For multifactorial, the code is very similar. Value 2 is parametrized (for example as k), and the condition becomes:

for (int i=n-k; i>(k-1); i-=k) {
    ....
}

3. What would that same code look like if we added your feature?

Instead of creating double factorial (or multifactorial as a general concept), we could simply type:

int result = IntMath.multiFactorial(6, 2); // 6!!, which is 6*4*2=48
long result2 = LongMath.multiFactorial(6,3); // 6*3 = 18
BigInteger result3 = BigIntegerMath.multiFactorial(4, 1) // the same as 4! = 4*3*2*1 = 24

(Optional) What would the method signatures for your feature look like?

For com.google.common.math.IntMath:

public static int multiFactorial​(int n, int k)

For com.google.common.math.LongMath:

public static long multiFactorial​(int n, int k)

For com.google.common.math.BigIntegerMath:

public static java.math.BigInteger multiFactorial​(int n, int k)

Concrete Use Cases

Remove need for creation of double factorial method “by hand”, which saves time in combinatorial computations. Requested feature (multifactorial) is a generalization of this concept, but the implementation is really similar to double factorial.

Packages

com.google.common.math

Checklist

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions