You can import them like this:
In [7]: import scipy, numpy, math
In [8]: scipy.math.factorial, numpy.math.factorial, math.factorial
Out[8]:
(<function math.factorial>,
<function math.factorial>,
<function math.factorial>)
scipy.math.factorial and numpy.math.factorial seem to simply be aliases/references for/to math.factorial, that is scipy.math.factorial is math.factorial and numpy.math.factorial is math.factorial should both give True.
You can import them like this:
In [7]: import scipy, numpy, math
In [8]: scipy.math.factorial, numpy.math.factorial, math.factorial
Out[8]:
(<function math.factorial>,
<function math.factorial>,
<function math.factorial>)
scipy.math.factorial and numpy.math.factorial seem to simply be aliases/references for/to math.factorial, that is scipy.math.factorial is math.factorial and numpy.math.factorial is math.factorial should both give True.
The answer for Ashwini is great, in pointing out that scipy.math.factorial, numpy.math.factorial, math.factorial are the same functions. However, I'd recommend use the one that Janne mentioned, that scipy.special.factorial is different. The one from scipy can take np.ndarray as an input, while the others can't.
In [12]: import scipy.special
In [13]: temp = np.arange(10) # temp is an np.ndarray
In [14]: math.factorial(temp) # This won't work
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-039ec0734458> in <module>()
----> 1 math.factorial(temp)
TypeError: only length-1 arrays can be converted to Python scalars
In [15]: scipy.special.factorial(temp) # This works!
Out[15]:
array([ 1.00000000e+00, 1.00000000e+00, 2.00000000e+00,
6.00000000e+00, 2.40000000e+01, 1.20000000e+02,
7.20000000e+02, 5.04000000e+03, 4.03200000e+04,
3.62880000e+05])
So, if you are doing factorial to a np.ndarray, the one from scipy will be easier to code and faster than doing the for-loops.
Videos
when I try to find out the factorial using numpy, the process only uses 1 core. is there a way to vectorize this? for example- say we have to find n! so 1×2×3×4×5×6×7 can go to 1st core 8×9×10×12×13×14×15 can go to 2nd etc till .....×n goes to the last available core. then just multiply the resultant numbers.
I'm trying to find out way of making processes faster. if something is not clear, please comment it and I'll make it clear. thank you!
As @Oleg has suggested, you can do this with 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]
Maybe you could look into increasing the efficiency using table lookups if space efficiency isn't a major concern. It would greatly reduce the number of repeated calculations. The following isn't terribly efficient, but it's the basic idea.
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