For a given matrix, return the determinant and the permanent of the matrix.

The determinant is given by

 



det
(
A
)
=

∑

σ


sgn
⁡
(
σ
)

∏

i
=
1


n



M

i
,

σ

i






{\displaystyle \det(A)=\sum _{\sigma }\operatorname {sgn}(\sigma )\prod _{i=1}^{n}M_{i,\sigma _{i}}}


while the permanent is given by

 



perm
⁡
(
A
)
=

∑

σ



∏

i
=
1


n



M

i
,

σ

i






{\displaystyle \operatorname {perm} (A)=\sum _{\sigma }\prod _{i=1}^{n}M_{i,\sigma _{i}}}


In both cases the sum is over the permutations 



σ


{\displaystyle \sigma }

 of the permutations of 1, 2, ..., n. (A permutation's sign is 1 if there are an even number of inversions and -1 otherwise; see parity of a permutation.)

More efficient algorithms for the determinant are known: LU decomposition, see for example wp:LU decomposition#Computing the determinant. Efficient methods for calculating the permanent are not known.



Related task

 Permutations by swapping


import sequtils, permutationsswap
 
type Matrix[M,N: static[int]] = array[M, array[N, float]]
 
proc det[M,N](a: Matrix[M,N]): float =
  let n = toSeq 0..a.high
  for sigma, sign in n.permutations:
    var x = sign.float
    for i in n: x *= a[i][sigma[i]]
    result += x
 
proc perm[M,N](a: Matrix[M,N]): float =
  let n = toSeq 0..a.high
  for sigma, sign in n.permutations:
    var x = 1.0
    for i in n: x *= a[i][sigma[i]]
    result += x
 
const
  a = [ [1.0, 2.0]
      , [3.0, 4.0]
      ]
  b = [ [ 1.0,  2,  3,  4]
      , [ 4.0,  5,  6,  7]
      , [ 7.0,  8,  9, 10]
      , [10.0, 11, 12, 13]
      ]
  c = [ [ 0.0,  1,  2,  3,  4]
      , [ 5.0,  6,  7,  8,  9]
      , [10.0, 11, 12, 13, 14]
      , [15.0, 16, 17, 18, 19]
      , [20.0, 21, 22, 23, 24]
      ]
 
echo "perm: ", a.perm, " det: ", a.det
echo "perm: ", b.perm, " det: ", b.det
echo "perm: ", c.perm, " det: ", c.det