LU decomposition: Difference between revisions
Content added Content deleted
(→{{header|jq}}: typo) |
(→{{header|Tcl}}: Added zkl) |
||
Line 2,437: | Line 2,437: | ||
0 1 0 0 |
0 1 0 0 |
||
0 0 0 1 |
0 0 0 1 |
||
</pre> |
|||
=={{header|zkl}}== |
|||
{{trans|Common Lisp}} |
|||
{{trans|D}} to get the conversion from column major to row major correct. |
|||
A matrix is a list of lists, ie list of rows in row major order. |
|||
<lang zkl>fcn make_array(n,m,v){ (m).pump(List.createLong(m).write,v)*n } |
|||
fcn eye(n){ // Creates a nxn identity matrix. |
|||
I:=make_array(n,n,0.0); |
|||
foreach j in (n){ I[j][j]=1.0 } |
|||
I |
|||
} |
|||
// Creates the pivoting matrix for A. |
|||
fcn pivotize(A){ |
|||
n:=A.len(); // rows |
|||
P:=eye(n); |
|||
foreach i in (n){ |
|||
max,row:=A[i][i],i; |
|||
foreach j in ([i..n-1]){ |
|||
if(A[j][i]>max) max,row=A[j][i],j; |
|||
} |
|||
if(i!=row) P.swap(i,row); |
|||
} |
|||
// Return P. |
|||
P |
|||
} |
|||
// Decomposes a square matrix A by PA=LU and returns L, U and P. |
|||
fcn lu(A){ |
|||
n:=A.len(); |
|||
L:=make_array(n,n,0.0); |
|||
U:=make_array(n,n,0.0); |
|||
P:=pivotize(A); |
|||
A=matMult(P,A); |
|||
foreach j in (n){ |
|||
L[j][j]=1.0; |
|||
foreach i in (j+1){ |
|||
U[i][j]=A[i][j] - |
|||
(i).reduce('wrap(s,k){ s + U[k][j]*L[i][k] },0.0); |
|||
} |
|||
foreach i in ([j..n-1]){ |
|||
L[i][j]=( A[i][j] - |
|||
(j).reduce('wrap(s,k){ s + U[k][j]*L[i][k] },0.0) ) / |
|||
U[j][j]; |
|||
} |
|||
} |
|||
// Return L, U and P. |
|||
return(L,U,P); |
|||
} |
|||
fcn matMult(a,b){ |
|||
n,m,p:=a[0].len(),a.len(),b[0].len(); |
|||
ans:=make_array(n,m,0.0); |
|||
foreach i,j,k in (m,p,n){ ans[i][j]+=a[i][k]*b[k][j]; } |
|||
ans |
|||
}</lang> |
|||
Example 1 |
|||
<lang zkl>g:=L(L(1.0,3.0,5.0),L(2.0,4.0,7.0),L(1.0,1.0,0.0)); |
|||
lu(g).apply2("println");</lang> |
|||
{{out}} |
|||
<pre> |
|||
L(L(1,0,0),L(0.5,1,0),L(0.5,-1,1)) |
|||
L(L(2,4,7),L(0,1,1.5),L(0,0,-2)) |
|||
L(L(0,1,0),L(1,0,0),L(0,0,1)) |
|||
</pre> |
|||
Example 2 |
|||
<lang zkl>lu(L( L(11.0, 9.0, 24.0, 2.0), |
|||
L( 1.0, 5.0, 2.0, 6.0), |
|||
L( 3.0, 17.0, 18.0, 1.0), |
|||
L( 2.0, 5.0, 7.0, 1.0) )).apply2(T(printM,Console.writeln.fpM("-"))); |
|||
fcn printM(m) { m.pump(Console.println,rowFmt) } |
|||
fcn rowFmt(row){ ("%9.5f "*row.len()).fmt(row.xplode()) }</lang> |
|||
The list apply2 method is side effects only, it doesn't aggregate results. When given a list of actions, it applies the action and passes the result to the next action. The fpM method is partial application with a mask, "-" truncates the parameters at that point (in this case, no parameters, ie just print a blank line, not the result of printM). |
|||
{{out}} |
|||
<pre> |
|||
1.00000 0.00000 0.00000 0.00000 |
|||
0.27273 1.00000 0.00000 0.00000 |
|||
0.09091 0.28750 1.00000 0.00000 |
|||
0.18182 0.23125 0.00360 1.00000 |
|||
11.00000 9.00000 24.00000 2.00000 |
|||
0.00000 14.54545 11.45455 0.45455 |
|||
0.00000 0.00000 -3.47500 5.68750 |
|||
0.00000 0.00000 0.00000 0.51079 |
|||
1.00000 0.00000 0.00000 0.00000 |
|||
0.00000 0.00000 1.00000 0.00000 |
|||
0.00000 1.00000 0.00000 0.00000 |
|||
0.00000 0.00000 0.00000 1.00000 |
|||
</pre> |
</pre> |