2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,12 +1,13 @@
|
|||
For a given matrix, return the [[wp:Determinant|determinant]] and the [[wp:Permanent|permanent]] of the matrix.
|
||||
|
||||
The determinant is given by
|
||||
:<math>\det(A) = \sum_\sigma\sgn(\sigma)\prod_{i=1}^n M_{i,\sigma_i}</math>
|
||||
:: <big><math>\det(A) = \sum_\sigma\sgn(\sigma)\prod_{i=1}^n M_{i,\sigma_i}</math></big>
|
||||
while the permanent is given by
|
||||
: <math> \operatorname{perm}(A)=\sum_\sigma\prod_{i=1}^n M_{i,\sigma_i}</math>
|
||||
:: <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.
|
||||
|
||||
;Cf.:
|
||||
* [[Permutations by swapping]]
|
||||
<br><br>
|
||||
|
|
|
|||
152
Task/Matrix-arithmetic/360-Assembly/matrix-arithmetic.360
Normal file
152
Task/Matrix-arithmetic/360-Assembly/matrix-arithmetic.360
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
* Matrix arithmetic 13/05/2016
|
||||
MATARI START
|
||||
STM R14,R12,12(R13) save caller's registers
|
||||
LR R12,R15 set R12 as base register
|
||||
USING MATARI,R12 notify assembler
|
||||
LA R11,SAVEAREA get the address of my savearea
|
||||
ST R13,4(R11) save caller's savearea pointer
|
||||
ST R11,8(R13) save my savearea pointer
|
||||
LR R13,R11 set R13 to point to my savearea
|
||||
LA R1,TT @tt
|
||||
BAL R14,DETER call deter(tt)
|
||||
LR R2,R0 R2=deter(tt)
|
||||
LR R3,R1 R3=perm(tt)
|
||||
XDECO R2,PG1+12 edit determinant
|
||||
XPRNT PG1,80 print determinant
|
||||
XDECO R3,PG2+12 edit permanent
|
||||
XPRNT PG2,80 print permanent
|
||||
EXITALL L R13,SAVEAREA+4 restore caller's savearea address
|
||||
LM R14,R12,12(R13) restore caller's registers
|
||||
XR R15,R15 set return code to 0
|
||||
BR R14 return to caller
|
||||
SAVEAREA DS 18F main savearea
|
||||
TT DC F'3' matrix size
|
||||
DC F'2',F'9',F'4',F'7',F'5',F'3',F'6',F'1',F'8' <==input
|
||||
PG1 DC CL80'determinant='
|
||||
PG2 DC CL80'permanent='
|
||||
XDEC DS CL12
|
||||
* recursive function (R0,R1)=deter(t) (python style)
|
||||
DETER CNOP 0,4 returns determinant and permanent
|
||||
STM R14,R12,12(R13) save all registers
|
||||
LR R9,R1 save R1
|
||||
L R2,0(R1) n
|
||||
BCTR R2,0 n-1
|
||||
LR R11,R2 n-1
|
||||
MR R10,R2 (n-1)*(n-1)
|
||||
SLA R11,2 (n-1)*(n-1)*4
|
||||
LA R11,1(R11) size of q array
|
||||
A R11,=A(STACKLEN) R11 storage amount required
|
||||
GETMAIN RU,LV=(R11) allocate storage for stack
|
||||
USING STACK,R10 make storage addressable
|
||||
LR R10,R1 establish stack addressability
|
||||
LA R1,SAVEAREB get the address of my savearea
|
||||
ST R13,4(R1) save caller's savearea pointer
|
||||
ST R1,8(R13) save my savearea pointer
|
||||
LR R13,R1 set R13 to point to my savearea
|
||||
LR R1,R9 restore R1
|
||||
LR R9,R1 @t
|
||||
L R4,0(R9) t(0)
|
||||
ST R4,N n=t(0)
|
||||
IF1 CH R4,=H'1' if n=1
|
||||
BNE SIF1 then
|
||||
L R2,4(R9) t(1)
|
||||
ST R2,R r=t(1)
|
||||
ST R2,S s=t(1)
|
||||
B EIF1 else
|
||||
SIF1 L R2,N n
|
||||
BCTR R2,0 n-1
|
||||
ST R2,Q q(0)=n-1
|
||||
ST R2,NM1 nm1=n-1
|
||||
LA R0,1 1
|
||||
ST R0,SGN sgn=1
|
||||
SR R0,R0 0
|
||||
ST R0,R r=0
|
||||
ST R0,S s=0
|
||||
LA R6,1 k=1
|
||||
LOOPK C R6,N do k=1 to n
|
||||
BH ELOOPK leave k
|
||||
SR R0,R0 0
|
||||
ST R0,JQ jq=0
|
||||
ST R0,KTI kti=0
|
||||
LA R7,1 iq=1
|
||||
LOOPIQ C R7,NM1 do iq=1 to n-1
|
||||
BH ELOOPIQ leave iq
|
||||
LR R2,R7 iq
|
||||
LA R2,1(R2) iq+1
|
||||
ST R2,IT it=iq+1
|
||||
L R2,KTI kti
|
||||
A R2,N kti+n
|
||||
ST R2,KTI kti=kti+n
|
||||
ST R2,KT kt=kti
|
||||
LA R8,1 jt=1
|
||||
LOOPJT C R8,N do jt=1 to n
|
||||
BH ELOOPJT leave jt
|
||||
L R2,KT kt
|
||||
LA R2,1(R2) kt+1
|
||||
ST R2,KT kt=kt+1
|
||||
IF2 CR R8,R6 if jt<>k
|
||||
BE EIF2 then
|
||||
L R2,JQ jq
|
||||
LA R2,1(R2) jq+1
|
||||
ST R2,JQ jq=jq+1
|
||||
L R1,KT kt
|
||||
SLA R1,2 *4
|
||||
L R2,0(R1,R9) t(kt)
|
||||
L R1,JQ jq
|
||||
SLA R1,2 *4
|
||||
ST R2,Q(R1) q(jq)=t(kt)
|
||||
EIF2 EQU * end if
|
||||
LA R8,1(R8) jt=jt+1
|
||||
B LOOPJT next jt
|
||||
ELOOPJT LA R7,1(R7) iq=iq+1
|
||||
B LOOPIQ next iq
|
||||
ELOOPIQ LR R1,R6 k
|
||||
SLA R1,2 *4
|
||||
L R5,0(R1,R9) t(k)
|
||||
LR R2,R5 R2,R5=t(k)
|
||||
LA R1,Q @q
|
||||
BAL R14,DETER call deter(q)
|
||||
LR R3,R0 R3=deter(q)
|
||||
ST R1,P p=perm(q)
|
||||
MR R4,R3 R5=t(k)*deter(q)
|
||||
M R4,SGN R5=sgn*t(k)*deter(q)
|
||||
A R5,R +r
|
||||
ST R5,R r=r+sgn*t(k)*deter(q)
|
||||
LR R5,R2 t(k)
|
||||
M R4,P R5=t(k)*perm(q)
|
||||
A R5,S +s
|
||||
ST R5,S s=s+t(k)*perm(q)
|
||||
L R2,SGN sgn
|
||||
LCR R2,R2 -sgn
|
||||
ST R2,SGN sgn=-sgn
|
||||
LA R6,1(R6) k=k+1
|
||||
B LOOPK next k
|
||||
ELOOPK EQU * end do
|
||||
EIF1 EQU * end if
|
||||
EXIT L R13,SAVEAREB+4 restore caller's savearea address
|
||||
L R2,R return value (determinant)
|
||||
L R3,S return value (permanent)
|
||||
XR R15,R15 set return code to 0
|
||||
FREEMAIN A=(R10),LV=(R11) free allocated storage
|
||||
LR R0,R2 first return value
|
||||
LR R1,R3 second return value
|
||||
L R14,12(R13) restore caller's return address
|
||||
LM R2,R12,28(R13) restore registers R2 to R12
|
||||
BR R14 return to caller
|
||||
IT DS F static area (out of stack)
|
||||
KT DS F "
|
||||
JQ DS F "
|
||||
KTI DS F "
|
||||
P DS F "
|
||||
DROP R12 base no longer needed
|
||||
STACK DSECT dynamic area (stack)
|
||||
SAVEAREB DS 18F function savearea
|
||||
N DS F n
|
||||
NM1 DS F n-1
|
||||
R DS F determinant accu
|
||||
S DS F permanent accu
|
||||
SGN DS F sign
|
||||
STACKLEN EQU *-STACK
|
||||
Q DS F sub matrix q((n-1)*(n-1)+1)
|
||||
YREGS
|
||||
END MATARI
|
||||
39
Task/Matrix-arithmetic/Haskell/matrix-arithmetic.hs
Normal file
39
Task/Matrix-arithmetic/Haskell/matrix-arithmetic.hs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
s_permutations :: [a] -> [([a], Int)]
|
||||
s_permutations = flip zip (cycle [1, -1]) . (foldl aux [[]])
|
||||
where aux items x = do
|
||||
(f,item) <- zip (cycle [reverse,id]) items
|
||||
f (insertEv x item)
|
||||
insertEv x [] = [[x]]
|
||||
insertEv x l@(y:ys) = (x:l) : map (y:) (insertEv x ys)
|
||||
|
||||
elemPos::[[a]] -> Int -> Int -> a
|
||||
elemPos ms i j = (ms !! i) !! j
|
||||
|
||||
prod:: Num a => ([[a]] -> Int -> Int -> a) -> [[a]] -> [Int] -> a
|
||||
prod f ms = product.zipWith (f ms) [0..]
|
||||
|
||||
s_determinant:: Num a => ([[a]] -> Int -> Int -> a) -> [[a]] -> [([Int],Int)] -> a
|
||||
s_determinant f ms = sum.map (\(is,s) -> fromIntegral s * prod f ms is)
|
||||
|
||||
determinant:: Num a => [[a]] -> a
|
||||
determinant ms = s_determinant elemPos ms.s_permutations $ [0..pred.length $ ms]
|
||||
|
||||
permanent:: Num a => [[a]] -> a
|
||||
permanent ms = sum.map (prod elemPos ms.fst).s_permutations $ [0..pred.length $ ms]
|
||||
|
||||
result ms = do
|
||||
putStrLn "Matrice:"
|
||||
mapM_ print ms
|
||||
putStrLn "Determinant:"
|
||||
print $ determinant ms
|
||||
putStrLn "Permanent:"
|
||||
print $ permanent ms
|
||||
|
||||
main = do
|
||||
let m1 = [[5]]
|
||||
let m2 = [[1,0,0],[0,1,0],[0,0,1]]
|
||||
let m3 = [[0,0,1],[0,1,0],[1,0,0]]
|
||||
let m4 = [[4,3],[2,5]]
|
||||
let m5 = [[2,5],[4,3]]
|
||||
let m6 = [[4,4],[2,2]]
|
||||
mapM_ result [m1,m2,m3,m4,m5,m6]
|
||||
55
Task/Matrix-arithmetic/Java/matrix-arithmetic-1.java
Normal file
55
Task/Matrix-arithmetic/Java/matrix-arithmetic-1.java
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import java.util.Scanner;
|
||||
|
||||
public class MatrixArithmetic {
|
||||
public static double[][] minor(double[][] a, int x, int y){
|
||||
int length = a.length-1;
|
||||
double[][] result = new double[length][length];
|
||||
for(int i=0;i<length;i++) for(int j=0;j<length;j++){
|
||||
if(i<x && j<y){
|
||||
result[i][j] = a[i][j];
|
||||
}else if(i>=x && j<y){
|
||||
result[i][j] = a[i+1][j];
|
||||
}else if(i<x && j>=y){
|
||||
result[i][j] = a[i][j+1];
|
||||
}else{ //i>x && j>y
|
||||
result[i][j] = a[i+1][j+1];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public static double det(double[][] a){
|
||||
if(a.length == 1){
|
||||
return a[0][0];
|
||||
}else{
|
||||
int sign = 1;
|
||||
double sum = 0;
|
||||
for(int i=0;i<a.length;i++){
|
||||
sum += sign * a[0][i] * det(minor(a,0,i));
|
||||
sign *= -1;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
public static double perm(double[][] a){
|
||||
if(a.length == 1){
|
||||
return a[0][0];
|
||||
}else{
|
||||
double sum = 0;
|
||||
for(int i=0;i<a.length;i++){
|
||||
sum += a[0][i] * perm(minor(a,0,i));
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
public static void main(String args[]){
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int size = sc.nextInt();
|
||||
double[][] a = new double[size][size];
|
||||
for(int i=0;i<size;i++) for(int j=0;j<size;j++){
|
||||
a[i][j] = sc.nextDouble();
|
||||
}
|
||||
sc.close();
|
||||
System.out.println("Determinant: "+det(a));
|
||||
System.out.println("Permanent: "+perm(a));
|
||||
}
|
||||
}
|
||||
15
Task/Matrix-arithmetic/Java/matrix-arithmetic-2.java
Normal file
15
Task/Matrix-arithmetic/Java/matrix-arithmetic-2.java
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
2
|
||||
1 2
|
||||
3 4
|
||||
Determinant: -2.0
|
||||
Permanent: 10.0
|
||||
|
||||
|
||||
5
|
||||
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
|
||||
Determinant: 0.0
|
||||
Permanent: 6778800.0
|
||||
86
Task/Matrix-arithmetic/Lua/matrix-arithmetic.lua
Normal file
86
Task/Matrix-arithmetic/Lua/matrix-arithmetic.lua
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
-- Johnson–Trotter permutations generator
|
||||
_JT={}
|
||||
function JT(dim)
|
||||
local n={ values={}, positions={}, directions={}, sign=1 }
|
||||
setmetatable(n,{__index=_JT})
|
||||
for i=1,dim do
|
||||
n.values[i]=i
|
||||
n.positions[i]=i
|
||||
n.directions[i]=-1
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
function _JT:largestMobile()
|
||||
for i=#self.values,1,-1 do
|
||||
local loc=self.positions[i]+self.directions[i]
|
||||
if loc >= 1 and loc <= #self.values and self.values[loc] < i then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function _JT:next()
|
||||
local r=self:largestMobile()
|
||||
if r==0 then return false end
|
||||
local rloc=self.positions[r]
|
||||
local lloc=rloc+self.directions[r]
|
||||
local l=self.values[lloc]
|
||||
self.values[lloc],self.values[rloc] = self.values[rloc],self.values[lloc]
|
||||
self.positions[l],self.positions[r] = self.positions[r],self.positions[l]
|
||||
self.sign=-self.sign
|
||||
for i=r+1,#self.directions do self.directions[i]=-self.directions[i] end
|
||||
return true
|
||||
end
|
||||
|
||||
-- matrix class
|
||||
|
||||
_MTX={}
|
||||
function MTX(matrix)
|
||||
setmetatable(matrix,{__index=_MTX})
|
||||
matrix.rows=#matrix
|
||||
matrix.cols=#matrix[1]
|
||||
return matrix
|
||||
end
|
||||
|
||||
function _MTX:dump()
|
||||
for _,r in ipairs(self) do
|
||||
print(unpack(r))
|
||||
end
|
||||
end
|
||||
|
||||
function _MTX:perm() return self:det(1) end
|
||||
function _MTX:det(perm)
|
||||
local det=0
|
||||
local jt=JT(self.cols)
|
||||
repeat
|
||||
local pi=perm or jt.sign
|
||||
for i,v in ipairs(jt.values) do
|
||||
pi=pi*self[i][v]
|
||||
end
|
||||
det=det+pi
|
||||
until not jt:next()
|
||||
return det
|
||||
end
|
||||
|
||||
-- test
|
||||
|
||||
matrix=MTX
|
||||
{
|
||||
{ 7, 2, -2, 4},
|
||||
{ 4, 4, 1, 7},
|
||||
{11, -8, 9, 10},
|
||||
{10, 5, 12, 13}
|
||||
}
|
||||
matrix:dump();
|
||||
print("det:",matrix:det(), "permanent:",matrix:perm(),"\n")
|
||||
|
||||
matrix2=MTX
|
||||
{
|
||||
{-2, 2,-3},
|
||||
{-1, 1, 3},
|
||||
{ 2, 0,-1}
|
||||
}
|
||||
matrix2:dump();
|
||||
print("det:",matrix2:det(), "permanent:",matrix2:perm())
|
||||
14
Task/Matrix-arithmetic/PARI-GP/matrix-arithmetic-3.pari
Normal file
14
Task/Matrix-arithmetic/PARI-GP/matrix-arithmetic-3.pari
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
matperm(M)=
|
||||
{
|
||||
my(n=matsize(M)[1],innerSums=vectorv(n));
|
||||
if(n==0, return(1));
|
||||
sum(x=1,2^n-1,
|
||||
my(k=valuation(x,2),s=M[,k+1],gray=bitxor(x, x>>1));
|
||||
if(bittest(gray,k),
|
||||
innerSums += s;
|
||||
,
|
||||
innerSums -= s;
|
||||
);
|
||||
(-1)^hammingweight(gray)*factorback(innerSums)
|
||||
)*(-1)^n;
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
sub insert( $x, @xs) { [@xs[0..$_-1], $x, @xs[$_..*]] for 0..@xs }
|
||||
sub insert ($x, @xs) { ([flat @xs[0 ..^ $_], $x, @xs[$_ .. *]] for 0 .. @xs) }
|
||||
sub order ($sg, @xs) { $sg > 0 ?? @xs !! @xs.reverse }
|
||||
|
||||
multi σ_permutations ([]) { [] => 1 }
|
||||
|
||||
multi σ_permutations ([$x, *@xs]) {
|
||||
σ_permutations(@xs).map({ order($_.value, insert($x, $_.key)) }) Z=> (1,-1) xx *
|
||||
σ_permutations(@xs).map({ |order($_.value, insert($x, $_.key)) }) Z=> |(1,-1) xx *
|
||||
}
|
||||
|
||||
sub m_arith ( @a, $op ) {
|
||||
|
|
@ -41,7 +41,8 @@ my @tests = (
|
|||
);
|
||||
|
||||
sub dump (@matrix) {
|
||||
say $_».fmt: "%3s" for @matrix, '';
|
||||
say $_».fmt: "%3s" for @matrix;
|
||||
say '';
|
||||
}
|
||||
|
||||
for @tests -> @matrix {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue