- Sun 13 December 2015
- Python
- #three-array, #numpy
In this post I will discuss an implementation of the triangle product for 3-arrays in NumPy. You start by importing and setting the seed of the random number generator:
from itertools import product
import numpy as np
from numpy import random
random.seed(0)
A 3-array with random integer entries between 0 and 9, and size \(\left(2, 3, 4\right)\) can be obtain with random.random_integers(0, 9, (2, 3, 4))
:
[[[5 0 3 3]
[7 9 3 5]
[2 4 7 6]]
[[8 8 1 6]
[7 7 8 1]
[5 9 8 9]]]
Given three 3-arrays A
, B
, and C
, the triangle product can be implemented by the function mul_3
:
def mul_3(A, B, C):
a, p, q = A.shape
p, b, r = B.shape
q, r, c = C.shape
D = np.zeros((a, b, c))
for (i, j, k) in product(xrange(a), xrange(b), xrange(c)):
P = np.zeros((p, q, r))
for (x, y, z) in product(xrange(p), xrange(q), xrange(r)):
P[x, y, z] = A[i, x, y] * B[x, j, z] * C[y, z, k]
D[i, j, k] = P.sum()
return D
This is a very yanky implementation, since it implicitly assumes that the size of the three input arrays are such that the triangle product exists. For example:
a = 2; b = 2; c = 2;
p = 3; q = 4; r = 5;
A = random.random_integers(0, 9, (a, p, q))
B = random.random_integers(0, 9, (p, b, r))
C = random.random_integers(0, 9, (q, r, c))
D = mul_3(A, B, C)
Here A
has size \(\left(2, 3, 4\right)\):
[[[4 3 0 3]
[5 0 2 3]
[8 1 3 3]]
[[3 7 0 1]
[9 9 0 4]
[7 3 2 7]]]
B
has size \(\left(3, 2, 5\right)\):
[[[2 0 0 4 5]
[5 6 8 4 1]]
[[4 9 8 1 1]
[7 9 9 3 6]]
[[7 2 0 3 5]
[9 4 4 6 4]]]
C
has size \(\left(4, 5, 2\right)\):
[[[4 3]
[4 4]
[8 4]
[3 7]
[5 5]]
[[0 1]
[5 9]
[3 0]
[5 0]
[1 2]]
[[4 2]
[0 3]
[2 0]
[7 5]
[9 0]]
[[2 7]
[2 9]
[2 3]
[3 2]
[3 4]]]
and D
has size \(\left(2, 2, 2\right)\):
[[[ 2206. 2374.]
[ 3832. 3985.]]
[[ 3386. 3821.]
[ 5417. 5907.]]]
Now lets consider three cubic 3-arrays with the same size:
n = 3
X = random.random_integers(0, 9, (n, n, n))
Y = random.random_integers(0, 9, (n, n, n))
Z = random.random_integers(0, 9, (n, n, n))
You can compute six triangle products corresponding to the six possible permutations of the inputs:
Each of these products yields a different 3-array. Explicitly, mul_3(X, Y, Z)
gives:
[[[ 2917. 3313. 1870.]
[ 2174. 2617. 1412.]
[ 3773. 4375. 2698.]]
[[ 2658. 2780. 1955.]
[ 2173. 2202. 1575.]
[ 3498. 3706. 2647.]]
[[ 3017. 4176. 1873.]
[ 2775. 3216. 1796.]
[ 4315. 5436. 2937.]]]
mul_3(Y, Z, X)
gives:
[[[ 2268. 2044. 4254.]
[ 2243. 1942. 3578.]
[ 1716. 1550. 3384.]]
[[ 2904. 2824. 5646.]
[ 2578. 1982. 4482.]
[ 1880. 2172. 4745.]]
[[ 3205. 1942. 4949.]
[ 2626. 1557. 3865.]
[ 2362. 1574. 3979.]]]
mul_3(Z, X, Y)
gives:
[[[ 3406. 2945. 3785.]
[ 2895. 3055. 3398.]
[ 4697. 4184. 5530.]]
[[ 2469. 2436. 3299.]
[ 2165. 2311. 2924.]
[ 3114. 2966. 4680.]]
[[ 2491. 2186. 2813.]
[ 2238. 2178. 2546.]
[ 3777. 3448. 4690.]]]
mul_3(Z, Y, X)
gives:
[[[ 2826. 2768. 4890.]
[ 2035. 2209. 3423.]
[ 3515. 3538. 6302.]]
[[ 2528. 1922. 3687.]
[ 1987. 1414. 2816.]
[ 3282. 2555. 5036.]]
[[ 2446. 2282. 3737.]
[ 1475. 1930. 3222.]
[ 2569. 2898. 5009.]]]
mul_3(Y, X, Z)
gives:
[[[ 2481. 2799. 1741.]
[ 2148. 2367. 1561.]
[ 3692. 4362. 2781.]]
[[ 3121. 3833. 2235.]
[ 2612. 3306. 1817.]
[ 4718. 5600. 3897.]]
[[ 2579. 3197. 1738.]
[ 2491. 2674. 1571.]
[ 4290. 4765. 2884.]]]
mul_3(X, Z, Y)
gives:
[[[ 2678. 2724. 4463.]
[ 1895. 2292. 3367.]
[ 1890. 2000. 3541.]]
[[ 2439. 2352. 3538.]
[ 2421. 1986. 3397.]
[ 2128. 2008. 3253.]]
[[ 2381. 3040. 4967.]
[ 2234. 2564. 4066.]
[ 1952. 2343. 3900.]]]
Thus, the 2-array notion of non-commutativity carries over to 3-arrays with the triangle product.