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


class Array {
    method permanent {
        var r = @^self.len
 
        var sum = 0
        r.permutations { |*a|
            var prod = 1
            [a,r].zip {|row,col| prod *= self[row][col] }
            sum += prod
        }
 
        return sum
    }
}
 
var m1 = [[1,2],[3,4]]
 
var m2 = [[1, 2, 3, 4],
          [4, 5, 6, 7],
          [7, 8, 9, 10],
          [10, 11, 12, 13]]
 
var m3 = [[0, 1, 2, 3, 4],
          [5, 6, 7, 8, 9],
          [10, 11, 12, 13, 14],
          [15, 16, 17, 18, 19],
          [20, 21, 22, 23, 24]]
 
[m1, m2, m3].each { |m|
  say "determinant:\t #{m.determinant}\npermanent:\t #{m.permanent}\n"
}