Brief notes and practical examples with the product operator.
import numpy as np
From the Greek alphabet, the capital Pi letter, represented by the symbol $\large \Pi$, is mathematical notation for product. This operator has as function the product or multiplication of multiples elements of a sequence. It is commonly associated to another mathematical symbol (greek capital Sigma, $\large \Sigma$), but its functionality is easily memorized by the sound of the word "product": Ppproduct = Pppi.
$$ \large \prod_{i=m}^n x_i = x_m \cdot x_{m+1} \cdot x_{m+2} \cdot \cdots \cdot x_{n-2} \cdot x_{n-1} \cdot x_{n} $$where:
For example, given the explicit sequence [1, 3, 7, 9, 13], the summation of all 5 elements is denoted as:
$$ \large \begin{aligned} \prod_{i=1}^5 x_i &= x_1 + x_2 + x_3 + x_4 + x_5 \\ &= 1 \cdot 3 \cdot 7 \cdot 9 \cdot 13 \\ &= 2457 \end{aligned} $$seq = [1, 3, 7, 9, 13]
result = 1
for x in seq:
result *= x
print(result)
2457
Notice that in many algorithms the lower and the upper bounds are represented by the interval $[0,N-1]$, which denote the index bound of a digital array. Although, the main idea is still the same.
$$ \large \prod_{k=0}^{N-1} = \prod_{k}^N $$x = [1, 3, 7, 9, 13]
result = x[0] * x[1] * x[2] * x[3] * x[4]
print(result)
2457
The library Numpy has a very convenient method that makes the summing process easier and much more readable.
x = np.array([1, 3, 7, 9, 13])
result = x.prod() # or np.prod(x)
print(result)
2457
This operator can be nested:
$$ \large \begin{aligned} \prod_{i=2}^4 \prod_{j=5}^6 (i + j) &= [(2 + 5) \cdot (2 + 6)] \cdot [(3 + 5) \cdot (3 + 6)] \cdot [(4 + 5) \cdot (4 + 6)] \\ &= (7 \cdot 8) \cdot (8 \cdot 9) \cdot (9 \cdot 10) \\ &= 56 \cdot 72 \cdot 90 \\ &= 362880 \end{aligned} $$result = 1
for i in range(2, 4+1):
for j in range(5, 6+1):
result *= i + j
print(result)
362880
Nested product are very commonly used to notate multidimensional isotropic or anisotropic objects. For example, given the matrix:
$$ \large M = \begin{bmatrix} 1 & 2 \\ 2 & 3 \\ 3 & 4 \end{bmatrix} $$The product of all elements can be expressed as:
$$ \large \begin{aligned} \prod_i^M \prod_j^N M_{ij} &= 1 \cdot 2 \cdot 2 \cdot 3 \cdot 3 \cdot 4 \\ &= 144 \end{aligned} $$matrix = np.array([
[1, 2],
[2, 3],
[3, 4]
])
M = len(matrix)
N = len(matrix[0])
result = 1
for i in range(M):
for j in range(N):
result *= matrix[i][j]
print(result, np.prod(matrix))
144 144
x = 10
N = 4
print(np.prod([x for _ in range(N)]))
print(x**N)
print(np.prod([x]*N))
10000 10000 10000
x = np.array([1, 20, 3, 40])
y = np.array([10, 2, 30, 4])
print(np.prod(x) * np.prod(y))
print(np.prod(x * y))
5760000 5760000
n = 5
N = np.arange(n) + 1
print(np.prod(N))
120
Infinity product: An infinite product is when the upper bound is infinity and its product result converges to a known theoretical number. For example, the John Wallis product:
$$ \large \lim_{k \rightarrow \infty} \prod_{n=1}^k \frac{4n^2}{4n^2 - 1} = \frac{\pi}{2} $$N = np.arange(1e6) + 1.
result = np.prod(4*N**2/(4*N**2 - 1))
print(result, np.pi/2)
1.5707959340960744 1.5707963267948966