Calculating factorials efficiently with Python and Numpy

In python / numpy - there is a way to build an expression containing factorials, but since in my script many factorials will be duplicated or reduced, wait until I specify the runtime to calculate it.

Let's say F(x) := x!

And I create an expression like (F(6) + F(7)) / F(4)- I can speed it up significantly, even do it in my head by doing

(F(6) * (1 + 7)) / F(4)
 = 5 * 6 * 8
 = 240

Basically, I’m going to generate such expressions and would like the computer to be smart and not calculate all factorials by multiplying by 1, that is, using my example, we don’t actually execute

(6*5*4*3*2 + 7*6*5*4*3*2) / 4*3*2

I really started developing the Factorial class, but I'm new to python and numpy, and I was wondering if this is a problem that has already been resolved.

+4
2

@Oleg, sympy:

import numpy as np
import sympy as sp

# preparation
n = sp.symbols("n")
F = sp.factorial

# create the equation
f = (F(n) + F(n + 1)) / F(n - 2)
print(f)               # => (factorial(n) + factorial(n + 1))/factorial(n - 2)

# reduce it
f = f.simplify()
print(f)               # => n*(n - 1)*(n + 2)

# evaluate it in SymPy
# Note: very slow!
print(f.subs(n, 6))    # => 240

# turn it into a numpy function
# Note: much faster!
f = sp.lambdify(n, f, "numpy")
a = np.arange(2, 10)
print(f(a))            # => [  8  30  72 140 240 378 560 792]
+4

, , . . , .

cache = {1:1}
def cached_factorial(n):
    if (n in cache):
        return cache[n]
    else:
        result = n * cached_factorial(n-1)
        cache[n] = result
        return result
+2

Source: https://habr.com/ru/post/1628225/


All Articles