Data update

This commit is contained in:
Ingy döt Net 2026-02-01 16:33:20 -08:00
parent 5150844a7d
commit 4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions

View file

@ -7,9 +7,23 @@ while the permanent is given by
:: <big><math> \operatorname{perm}(A)=\sum_\sigma\prod_{i=1}^n M_{i,\sigma_i}</math></big>
In both cases the sum is over the permutations <math>\sigma</math> 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 [[wp:Parity of a permutation|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.
;Complexity of known algorithms:
* [[wp:Laplace_expansion|Laplace expansion]] <math>O\bigl(n!\bigr)</math>
* [[wp:Leibniz_formula_for_determinants|Leibniz fomula]] <math>\Omega\bigl(n!\cdot n\bigr)</math>
* [[wp:Bareiss_algorithm|Bareiss algorithm]] <math>O\bigl(n^3\bigr)</math>
* [[wp:LU_decomposition|LU-decomposition]] <math>O\bigl(n^3\bigr)</math>
* [[wp:Strassen_algorithm|Strassen algorithm]] <math>O\bigl(n^{2.807}\bigr)</math>
* [[wp:Coppersmith%E2%80%93Winograd_algorithm|Coppersmith-Winograd algorithm]] <math>O\bigl(n^{2.376}\bigr)</math>
* [[wp:Jean-Fran%C3%A7ois_Le_Gall|Le Gall algorithm]]
* [https://codegolf.stackexchange.com/questions/236835/birds-algorithm-for-computing-determinants Bird's algorithm]
;Related task:
* [[wp:Computational_complexity_of_matrix_multiplication#Matrix_inversion,_determinant_and_Gaussian_elimination|Computational complexity of matrix multiplication]]
* [https://dai.fmph.uniba.sk/courses/FPRO/bird_pearls.pdf Richard Bird Pearls]
* [https://dai.fmph.uniba.sk/courses/FPRO/ Funkcionálne programovanie]
* [[Permutations by swapping]]
<br><br>

View file

@ -9,7 +9,7 @@ permutations: function [arr][
xs: new arr
sign: 1
ret: new @[@[xs, sign]]
ret: @[@[new xs, sign]]
while [true][
while [d > 1][
@ -28,7 +28,7 @@ permutations: function [arr][
xs\[d]: tmp
sign: neg sign
'ret ++ @[new @[xs, sign]]
'ret ++ @[@[new xs, sign]]
c\[d]: c\[d] + 1
]
@ -36,8 +36,8 @@ permutations: function [arr][
]
perm: function [a][
n: 0..dec size a
result: new 0.0
n: @ 0..dec size a
result: 0.0
loop permutate n 'sigma [
x: 1.0
loop n 'i -> x: x * get a\[i] sigma\[i]
@ -47,8 +47,8 @@ perm: function [a][
]
det: function [a][
n: 0..dec size a
result: new 0.0
n: @ 0..dec size a
result: 0.0
loop.with:'i permutations n 'p[
x: p\1
loop n 'i -> x: x * get a\[i] p\0\[i]

View file

@ -1,132 +0,0 @@
#include <iostream>
#include <array>
template<typename T, size_t N>
using vec = std::array<T,N>;
template<typename T, size_t N, size_t M = N>
using mat = std::array<vec<T,N>,M>;
/* generalized Kronecker delta - antisymmetrizer */
template<scalar T, size_t N>
constexpr int8_t gkd(const std::array<T,N>& v, const std::array<T,N>& orig)
{
bool trans = 0;
for(size_t i = 0; i < orig.size(); i++)
{
size_t cnt = 0;
for(size_t j = 0; j < std::min<size_t>(i + 1,v.size()); j++)
if(orig[i] == v[j]) ++cnt;
for(size_t j = i + 1; j < v.size(); j++)
{
if(orig[i] == v[j]) ++cnt;
if( v[i] > v[j]) trans += -1;
}
if(cnt != 1) return 0;
}
return trans ? -1 : 1;
}
/* generalized permanent delta - complete symmetrizer *
* equivalent to abs(gKd(v,orig)) or is_index_sequence */
template<scalar T, size_t N>
inline constexpr int8_t gpd(const std::array<T,N>& v, const std::array<T,N>& orig)
{
for(auto& i : orig)
if(std::count(v.begin(), v.end(), i) != 1) return 0;
return 1;
}
template<typename T, size_t N>
constexpr auto minor(const mat<T,N>& a, size_t x, size_t y)->mat<T,N-1> requires(N > 0)
{
mat<T,N-1> result;
for (size_t i = 0; i < N-1; i++)
for (size_t j = 0; j < N-1; j++)
result[i][j] = (i < x && j < y) ? a[i ][j ] :
(i >= x && j < y) ? a[i + 1][j ] :
(i < x && j >= y) ? a[i ][j + 1] :
a[i + 1][j + 1] ;
return result;
}
template<typename T, size_t N, bool SIGN = true>
constexpr double det(const mat<T,1>& a) requires(N == 1)
{
return double(a[0][0]);
}
template<typename T, size_t N, bool SIGN = true>
constexpr double det(const mat<T,N>& a) requires(N > 1)
{
double sum = 0;
bool sign = true;
for (size_t i = 0; i < a.size(); i++)
sum += double((sign += -1) && SIGN ? -1 : 1) * double(a[0][i]) * det<T,N-1,SIGN>(minor(a,0,i));
return sum;
}
template<typename T, size_t N>
inline constexpr double perm(const mat<T,N>& a) requires(N > 0) { return det<T,N,false>(a); }
template <typename T, size_t N, size_t M = N>
std::ostream &operator<<(std::ostream &os, const mat<T,N,M> &v)
{
for(size_t i = 0; i < N; i++)
{
os << '[';
for(size_t j = 0; j < M; j++)
{
printf("%+e", (double)v[i][j]);
if( j < (M - 1)) os << ", ";
}
os << ']' << std::endl;
}
return os;
}
template<typename T, size_t N>
void test(const mat<T,N>& m)
{
std::cout << m;
printf("Permanent: %+f Determinant: %+f\n", perm(m), det(m));
}
int main()
{
mat<int,2> A =
{
vec<int,2>{1,2},
vec<int,2>{3,4}
};
mat<int,3> B =
{
vec<int,3>{-2, 2, -3},
vec<int,3>{-1, 1, 3},
vec<int,3>{ 2, 0, -1}
};
mat<int,4> C =
{
vec<int,4>{ 1, 2, 3, 4},
vec<int,4>{ 4, 5, 6, 7},
vec<int,4>{ 7, 8, 9,10},
vec<int,4>{10,11,12,13}
};
mat<int,5> D =
{
vec<int,5>{ 0, 1, 2, 3, 4},
vec<int,5>{ 5, 6, 7, 8, 9},
vec<int,5>{10, 11, 12, 13, 14},
vec<int,5>{15, 16, 17, 18, 19},
vec<int,5>{20, 21, 22, 23, 24}
};
test(A);
std::cout << std::endl;
test(B);
std::cout << std::endl;
test(C);
std::cout << std::endl;
test(D);
return 0;
}

View file

@ -1,44 +0,0 @@
function det-perm ($array) {
if($array) {
$size = $array.Count
function prod($A) {
$prod = 1
if($A) { $A | foreach{$prod *= $_} }
$prod
}
function generate($sign, $n, $A) {
if($n -eq 1) {
$i = 0
$prod = prod @($A | foreach{$array[$i++][$_]})
[pscustomobject]@{det = $sign*$prod; perm = $prod}
}
else{
for($i = 0; $i -lt ($n - 1); $i += 1) {
generate $sign ($n - 1) $A
if($n % 2 -eq 0){
$i1, $i2 = $i, ($n-1)
$A[$i1], $A[$i2] = $A[$i2], $A[$i1]
}
else{
$i1, $i2 = 0, ($n-1)
$A[$i1], $A[$i2] = $A[$i2], $A[$i1]
}
$sign *= -1
}
generate $sign ($n - 1) $A
}
}
$det = $perm = 0
generate 1 $size @(0..($size-1)) | foreach{
$det += $_.det
$perm += $_.perm
}
[pscustomobject]@{det = "$det"; perm = "$perm"}
} else {Write-Error "empty array"}
}
det-perm 5
det-perm @(@(1,0,0),@(0,1,0),@(0,0,1))
det-perm @(@(0,0,1),@(0,1,0),@(1,0,0))
det-perm @(@(4,3),@(2,5))
det-perm @(@(2,5),@(4,3))
det-perm @(@(4,4),@(2,2))