2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -0,0 +1,97 @@
import static java.util.Arrays.stream;
import java.util.Locale;
import static java.util.stream.IntStream.range;
public class Test {
static double dotProduct(double[] a, double[] b) {
return range(0, a.length).mapToDouble(i -> a[i] * b[i]).sum();
}
static double[][] matrixMul(double[][] A, double[][] B) {
double[][] result = new double[A.length][B[0].length];
double[] aux = new double[B.length];
for (int j = 0; j < B[0].length; j++) {
for (int k = 0; k < B.length; k++)
aux[k] = B[k][j];
for (int i = 0; i < A.length; i++)
result[i][j] = dotProduct(A[i], aux);
}
return result;
}
static double[][] pivotize(double[][] m) {
int n = m.length;
double[][] id = range(0, n).mapToObj(j -> range(0, n)
.mapToDouble(i -> i == j ? 1 : 0).toArray())
.toArray(double[][]::new);
for (int i = 0; i < n; i++) {
double maxm = m[i][i];
int row = i;
for (int j = i; j < n; j++)
if (m[j][i] > maxm) {
maxm = m[j][i];
row = j;
}
if (i != row) {
double[] tmp = id[i];
id[i] = id[row];
id[row] = tmp;
}
}
return id;
}
static double[][][] lu(double[][] A) {
int n = A.length;
double[][] L = new double[n][n];
double[][] U = new double[n][n];
double[][] P = pivotize(A);
double[][] A2 = matrixMul(P, A);
for (int j = 0; j < n; j++) {
L[j][j] = 1;
for (int i = 0; i < j + 1; i++) {
double s1 = 0;
for (int k = 0; k < i; k++)
s1 += U[k][j] * L[i][k];
U[i][j] = A2[i][j] - s1;
}
for (int i = j; i < n; i++) {
double s2 = 0;
for (int k = 0; k < j; k++)
s2 += U[k][j] * L[i][k];
L[i][j] = (A2[i][j] - s2) / U[j][j];
}
}
return new double[][][]{L, U, P};
}
static void print(double[][] m) {
stream(m).forEach(a -> {
stream(a).forEach(n -> System.out.printf(Locale.US, "%5.1f ", n));
System.out.println();
});
System.out.println();
}
public static void main(String[] args) {
double[][] a = {{1.0, 3, 5}, {2.0, 4, 7}, {1.0, 1, 0}};
double[][] b = {{11.0, 9, 24, 2}, {1.0, 5, 2, 6}, {3.0, 17, 18, 1},
{2.0, 5, 7, 1}};
for (double[][] m : lu(a))
print(m);
System.out.println();
for (double[][] m : lu(b))
print(m);
}
}

View file

@ -0,0 +1,23 @@
matlup(M) =
{
my (L = matid(#M), U = M, P = L);
for (i = 1, #M-1, \\ pivoting
p = M[z=i,i];
for (k = i, #M, if (M[k,i] > p, p = M[z=k,i]));
if (i != z, \\ swap rows
k = U[i,]; U[i,] = U[z,]; U[z,] = k;
k = P[i,]; P[i,] = P[z,]; P[z,] = k;
);
);
for (i = 1, #M-1, \\ decompose
for (k = i+1, #M,
L[k,i] = U[k,i] / U[i,i];
for (j = i, #M, U[k,j] -= L[k,i] * U[i,j])
)
);
[L,U,P] \\ return L,U,P triple matrix
}

View file

@ -0,0 +1,77 @@
for ( [1, 3, 5], # Test Matrices
[2, 4, 7],
[1, 1, 0]
),
( [11, 9, 24, 2],
[ 1, 5, 2, 6],
[ 3, 17, 18, 1],
[ 2, 5, 7, 1]
)
-> @test {
say-it 'A Matrix', @test;
say-it( $_[0], @($_[1]) ) for 'P Matrix', 'Aʼ Matrix', 'L Matrix', 'U Matrix' Z, lu @test;
}
sub lu (@a) {
die unless @a.&is-square;
my $n = +@a;
my @P = pivotize @a;
my @Aʼ = mmult @P, @a;
my @L = matrix-ident $n;
my @U = matrix-zero $n;
for ^$n -> $i {
for ^$n -> $j {
if $j >= $i {
@U[$i][$j] = @Aʼ[$i][$j] - [+] map { @U[$_][$j] * @L[$i][$_] }, ^$i
} else {
@L[$i][$j] = (@Aʼ[$i][$j] - [+] map { @U[$_][$j] * @L[$i][$_] }, ^$j) / @U[$j][$j];
}
}
}
return @P, @Aʼ, @L, @U;
}
sub pivotize (@m) {
my $size = +@m;
my @id = matrix-ident $size;
for ^$size -> $i {
my $max = @m[$i][$i];
my $row = $i;
for $i ..^ $size -> $j {
if @m[$j][$i] > $max {
$max = @m[$j][$i];
$row = $j;
}
}
if $row != $i {
@id[$row, $i] = @id[$i, $row]
}
}
@id
}
sub is-square (@m) { so @m == all @m[*] }
sub matrix-zero ($n, $m = $n) { map { [ flat 0 xx $n ] }, ^$m }
sub matrix-ident ($n) { map { [ flat 0 xx $_, 1, 0 xx $n - 1 - $_ ] }, ^$n }
sub mmult(@a,@b) {
my @p;
for ^@a X ^@b[0] -> ($r, $c) {
@p[$r][$c] += @a[$r][$_] * @b[$_][$c] for ^@b;
}
@p
}
sub rat-int ($num) {
return $num unless $num ~~ Rat;
return $num.narrow if $num.narrow.WHAT ~~ Int;
$num.nude.join: '/';
}
sub say-it ($message, @array) {
say "\n$message";
$_».&rat-int.fmt("%7s").say for @array;
}

View file

@ -1,69 +1,73 @@
/*REXX pgm makes a matrix from input, performs/shows LU decomposition. */
#=0; P.=0; PA.=0; L.=0; U.=0 /*initialize some variables to 0.*/
parse arg x /*get the matrix elements from CL*/
call makeMat /*make the A matrix from numbers.*/
call showMat 'A', N /*display the A matrix. */
call manPmat /*manufacture P (permutation).*/
call showMat 'P', N /*display the P matrix. */
call multMat /*multiply the A and P matrices.*/
call showMat 'PA', N /*display the PA matrix. */
do y=1 for N; call manUmat y /*manufacture U matrix, parts*/
call manLmat y /*manufacture L matrix, parts*/
/*REXX program creates a matrix from console input, performs/shows LU decomposition.*/
#=0; P.=0; PA.=0; L.=0; U.=0 /*initialize some variables to zero. */
parse arg x /*obtain matrix elements from the C.L. */
call makeMat /*make the A matrix from the numbers.*/
call showMat 'A', N /*display the A matrix. */
call manPmat /*manufacture P (permutation). */
call showMat 'P', N /*display the P matrix. */
call multMat /*multiply the A and P matrices. */
call showMat 'PA', N /*display the PA matrix. */
do y=1 for N; call manUmat y /*manufacture U matrix, parts. */
call manLmat y /*manufacture L matrix, parts. */
end
call showMat 'L', N /*display the L matrix. */
call showMat 'U', N /*display the U matrix. */
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────er subroutine───────────────────────*/
call showMat 'L', N /*display the L matrix. */
call showMat 'U', N /*display the U matrix. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
er: say; say '***error!***'; say; say arg(1); say; exit 13
/*──────────────────────────────────makeMat subroutine──────────────────*/
makeMat: ?=words(x); do N=1 for ?; if N**2==? then leave; end
if N**2\==? then call er 'not correct number of elements entered: ' ?
do r=1 for N /*build the "A" matrix from input*/
do c=1 for N; #=#+1; _=word(x,#); A.r.c=_
if \datatype(_,'N') then call er "element isn't numeric: " _
end /*c*/
end /*r*/
return
/*──────────────────────────────────manLmat subroutine──────────────────*/
manLmat: arg ? /*manufacture L (lower) matrix.*/
do r=1 for N
do c=1 for N; if r==c then do; L.r.c=1; iterate; end
if c\==? | r==c | c>r then iterate
_=PA.r.c
do k=1 for c-1; _=_-U.k.c*L.r.k; end /*k*/
L.r.c=_/U.c.c
end /*c*/
end /*r*/
return
/*──────────────────────────────────manPmat subroutine──────────────────*/
manPmat: c=N; do r=N by -1 for N /*manufacture P (permutation). */
P.r.c=1; c=c+1; if c>N then c=N%2; if c==N then c=1
end /*r*/
return
/*──────────────────────────────────manUmat subroutine──────────────────*/
manUmat: arg ? /*manufacture U (upper) matrix.*/
do r=1 for N; if r\==? then iterate
do c=1 for N; if c<r then iterate
_=PA.r.c
do k=1 for r-1; _=_-U.k.c*L.r.k; end /*k*/
U.r.c=_/1
end /*c*/
end /*r*/
return
/*──────────────────────────────────multMat subroutine──────────────────*/
multMat: do i =1 for N /*multiply matrix P & A ──► PA */
do j =1 for N
do k=1 for N; pa.i.j = (pa.i.j + p.i.k * a.k.j) / 1; end
end /*j*/
end /*i*/
return
/*──────────────────────────────────showMat subroutine──────────────────*/
showMat: parse arg mat,rows,cols; w=0; cols=word(cols rows,1); say
do r =1 for rows
do c=1 for cols; w=max(w,length(value(mat'.'r'.'c))); end
end
say center(mat 'matrix',cols*(w+1)+7,"")
do r =1 for rows; _=
do c=1 for cols; _=_ right(value(mat'.'r'.'c),w+1); end; say _
end
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
makeMat: ?=words(x); do N=1 for ?; if N**2==? then leave; end /*N*/
if N**2\==? then call er 'not correct number of elements entered: ' ?
do r=1 for N /*build the "A" matrix from the input*/
do c=1 for N; #=#+1; _=word(x,#); A.r.c=_
if \datatype(_,'N') then call er "element isn't numeric: " _
end /*c*/
end /*r*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
manLmat: parse arg ? /*manufacture L (lower) matrix.*/
do r=1 for N
do c=1 for N; if r==c then do; L.r.c=1; iterate; end
if c\==? | r==c | c>r then iterate
_=PA.r.c
do k=1 for c-1; _=_-U.k.c*L.r.k; end /*k*/
L.r.c=_/U.c.c
end /*c*/
end /*r*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
manPmat: c=N; do r=N by -1 for N /*manufacture P (permutation). */
P.r.c=1; c=c+1; if c>N then c=N%2; if c==N then c=1
end /*r*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
manUmat: parse arg ? /*manufacture U (upper) matrix.*/
do r=1 for N; if r\==? then iterate
do c=1 for N; if c<r then iterate
_=PA.r.c
do k=1 for r-1; _=_-U.k.c*L.r.k; end /*k*/
U.r.c=_/1
end /*c*/
end /*r*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
multMat: do i=1 for N /*multiply matrix P & A ──► PA */
do j=1 for N
do k=1 for N; pa.i.j=(pa.i.j + p.i.k * a.k.j) / 1
end /*k*/
end /*j*/
end /*i*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
showMat: parse arg mat,rows,cols; w=0; cols=word(cols rows,1); say
do r=1 for rows
do c=1 for cols; w=max(w, length( value( mat'.'r"."c ) ) )
end /*c*/
end /*r*/
say center(mat 'matrix',cols*(w+1)+7,"")
do r=1 for rows; _=
do c=1 for cols; _=_ right(value(mat'.'r'.'c),w+1); end /*c*/
say _
end /*r*/
return