5

There does not seem to be a PyTorch function for computing a factorial. Is there a method to do this in PyTorch? I am looking to manually compute a Poisson distribution in Torch (I am aware this exists: https://pytorch.org/docs/stable/generated/torch.poisson.html) and the formula requires a factorial in the denominator.

Poisson Distribution: https://en.wikipedia.org/wiki/Poisson_distribution

kjans_tbme
  • 87
  • 6
  • 1
    Take a look at this https://stackoverflow.com/questions/5136447/function-for-factorial-in-python – Meredith Jackson Oct 01 '20 at 14:22
  • Thanks, it looks like I can use a combination of Torch functions to compute a factorial exclusively in Torch. – kjans_tbme Oct 01 '20 at 14:41
  • 1
    Doesn't `lgamma` give you what you need? (In combination with `exp`, obviously, though you may do better to keep things in log form until right at the end anyway.) – Mark Dickinson Oct 01 '20 at 15:16

2 Answers2

7

I think you can find it as torch.jit._builtins.math.factorial BUT pytorch as well as numpy and scipy (Factorial in numpy and scipy) uses python's builtin math.factorial:

import math

import numpy as np
import scipy as sp
import torch


print(torch.jit._builtins.math.factorial is math.factorial)
print(np.math.factorial is math.factorial)
print(sp.math.factorial is math.factorial)
True
True
True

But, in contrast, scipy in addition to "mainstream" math.factorial contains the very "special" factorial function scipy.special.factorial. Unlike function from math module it operates on arrays:

from scipy import special

print(special.factorial is math.factorial)
False
# the all known factorial functions
factorials = (
    math.factorial,
    torch.jit._builtins.math.factorial,
    np.math.factorial,
    sp.math.factorial,
    special.factorial,
)

# Let's run some tests
tnsr = torch.tensor(3)

for fn in factorials:
    try:
        out = fn(tnsr)
    except Exception as err:
        print(fn.__name__, fn.__module__, ':', err)
    else:
        print(fn.__name__, fn.__module__, ':', out)
factorial math : 6
factorial math : 6
factorial math : 6
factorial math : 6
factorial scipy.special._basic : tensor(6., dtype=torch.float64)
tnsr = torch.tensor([1, 2, 3])

for fn in factorials:
    try:
        out = fn(tnsr)
    except Exception as err:
        print(fn.__name__, fn.__module__, ':', err)
    else:
        print(fn.__name__, fn.__module__, ':', out)
factorial math : only integer tensors of a single element can be converted to an index
factorial math : only integer tensors of a single element can be converted to an index
factorial math : only integer tensors of a single element can be converted to an index
factorial math : only integer tensors of a single element can be converted to an index
factorial scipy.special._basic : tensor([1., 2., 6.], dtype=torch.float64)
trsvchn
  • 8,033
  • 3
  • 23
  • 30
0

The built in math module (docs) provides a function that returns the factorial of a given integral as an int.

import math

x = math.factorial(5)
print(x)
print(type(x))

Output

120
<class 'int'>
JPI93
  • 1,507
  • 5
  • 10
  • Thank you for your response, but I was aware of other methods to compute a factorial in Python. I was looking for a method using exclusively PyTorch. – kjans_tbme Oct 01 '20 at 14:42
  • 1
    @kjans_tbme Oh I see, apologies for my misunderstanding. To the best of my knowledge there is not a factorial function within the PyTorch library - with the exception of `TorchScript` ([docs](https://pytorch.org/docs/stable/jit.html)) which itself makes the built in `math` module and `math.factorial` available. – JPI93 Oct 01 '20 at 14:52