user
Every square matrix 

A
{\displaystyle {\displaystyle A}}
 can be decomposed into a product of a lower triangular matrix 

L
{\displaystyle {\displaystyle L}}
 and a upper triangular matrix 

U
{\displaystyle {\displaystyle U}}
,
as described in LU decomposition.

:   A
    =
    L
    U
    {\displaystyle {\displaystyle A=LU}}

It is a modified form of Gaussian elimination.
While the Cholesky decomposition only works for symmetric,
positive definite matrices, the more general LU decomposition
works for any square matrix.

There are several algorithms for calculating L and U.
To derive *Crout's algorithm* for a 3x3 example,
we have to solve the following system:

:   A
    =


    (

    a

    11


    a

    12


    a

    13

    a

    21


    a

    22


    a

    23

    a

    31


    a

    32


    a

    33
    )
    =


    (

    l

    11

    0

    0

    l

    21


    l

    22

    0

    l

    31


    l

    32


    l

    33
    )


    (

    u

    11


    u

    12


    u

    13


    0


    u

    22


    u

    23


    0

    0


    u

    33
    )
    =
    L
    U
    {\displaystyle {\displaystyle A={\begin{pmatrix}a\_{11}&a\_{12}&a\_{13}\\a\_{21}&a\_{22}&a\_{23}\\a\_{31}&a\_{32}&a\_{33}\\\end{pmatrix}}={\begin{pmatrix}l\_{11}&0&0\\l\_{21}&l\_{22}&0\\l\_{31}&l\_{32}&l\_{33}\\\end{pmatrix}}{\begin{pmatrix}u\_{11}&u\_{12}&u\_{13}\\0&u\_{22}&u\_{23}\\0&0&u\_{33}\end{pmatrix}}=LU}}

We now would have to solve 9 equations with 12 unknowns. To make the system uniquely solvable, usually the diagonal elements of 

L
{\displaystyle {\displaystyle L}}
 are set to 1

:   l

    11
    =
    1
    {\displaystyle {\displaystyle l\_{11}=1}}
:   l

    22
    =
    1
    {\displaystyle {\displaystyle l\_{22}=1}}
:   l

    33
    =
    1
    {\displaystyle {\displaystyle l\_{33}=1}}

so we get a solvable system of 9 unknowns and 9 equations.

:   A
    =


    (

    a

    11


    a

    12


    a

    13

    a

    21


    a

    22


    a

    23

    a

    31


    a

    32


    a

    33
    )
    =


    (

    1

    0

    0

    l

    21

    1

    0

    l

    31


    l

    32

    1
    )


    (

    u

    11


    u

    12


    u

    13


    0


    u

    22


    u

    23


    0

    0


    u

    33
    )
    =


    (

    u

    11


    u

    12


    u

    13

    u

    11

    l

    21


    u

    12

    l

    21
    +

    u

    22


    u

    13

    l

    21
    +

    u

    23

    u

    11

    l

    31


    u

    12

    l

    31
    +

    u

    22

    l

    32


    u

    13

    l

    31
    +

    u

    23

    l

    32
    +

    u

    33
    )
    =
    L
    U
    {\displaystyle {\displaystyle A={\begin{pmatrix}a\_{11}&a\_{12}&a\_{13}\\a\_{21}&a\_{22}&a\_{23}\\a\_{31}&a\_{32}&a\_{33}\\\end{pmatrix}}={\begin{pmatrix}1&0&0\\l\_{21}&1&0\\l\_{31}&l\_{32}&1\\\end{pmatrix}}{\begin{pmatrix}u\_{11}&u\_{12}&u\_{13}\\0&u\_{22}&u\_{23}\\0&0&u\_{33}\end{pmatrix}}={\begin{pmatrix}u\_{11}&u\_{12}&u\_{13}\\u\_{11}l\_{21}&u\_{12}l\_{21}+u\_{22}&u\_{13}l\_{21}+u\_{23}\\u\_{11}l\_{31}&u\_{12}l\_{31}+u\_{22}l\_{32}&u\_{13}l\_{31}+u\_{23}l\_{32}+u\_{33}\end{pmatrix}}=LU}}

Solving for the other 

l
{\displaystyle {\displaystyle l}}
 and 

u
{\displaystyle {\displaystyle u}}
, we get the following equations:

:   u

    11
    =

    a

    11
    {\displaystyle {\displaystyle u\_{11}=a\_{11}}}
:   u

    12
    =

    a

    12
    {\displaystyle {\displaystyle u\_{12}=a\_{12}}}
:   u

    13
    =

    a

    13
    {\displaystyle {\displaystyle u\_{13}=a\_{13}}}

:   u

    22
    =

    a

    22
    −

    u

    12

    l

    21
    {\displaystyle {\displaystyle u\_{22}=a\_{22}-u\_{12}l\_{21}}}
:   u

    23
    =

    a

    23
    −

    u

    13

    l

    21
    {\displaystyle {\displaystyle u\_{23}=a\_{23}-u\_{13}l\_{21}}}

:   u

    33
    =

    a

    33
    −
    (

    u

    13

    l

    31
    +

    u

    23

    l

    32
    )
    {\displaystyle {\displaystyle u\_{33}=a\_{33}-(u\_{13}l\_{31}+u\_{23}l\_{32})}}

and for 

l
{\displaystyle {\displaystyle l}}
:

:   l

    21
    =


    1

    u

    11

    a

    21
    {\displaystyle {\displaystyle l\_{21}={\frac {1}{u\_{11}}}a\_{21}}}
:   l

    31
    =


    1

    u

    11

    a

    31
    {\displaystyle {\displaystyle l\_{31}={\frac {1}{u\_{11}}}a\_{31}}}

:   l

    32
    =


    1

    u

    22
    (

    a

    32
    −

    u

    12

    l

    31
    )
    {\displaystyle {\displaystyle l\_{32}={\frac {1}{u\_{22}}}(a\_{32}-u\_{12}l\_{31})}}

We see that there is a calculation pattern, which can be expressed as the following formulas, first for 

U
{\displaystyle {\displaystyle U}}

:   u

    i
    j
    =

    a

    i
    j
    −

    ∑

    k
    =
    1

    i
    −
    1

    u

    k
    j

    l

    i
    k
    {\displaystyle {\displaystyle u\_{ij}=a\_{ij}-\sum \_{k=1}^{i-1}u\_{kj}l\_{ik}}}

and then for 

L
{\displaystyle {\displaystyle L}}

:   l

    i
    j
    =


    1

    u

    j
    j
    (

    a

    i
    j
    −

    ∑

    k
    =
    1

    j
    −
    1

    u

    k
    j

    l

    i
    k
    )
    {\displaystyle {\displaystyle l\_{ij}={\frac {1}{u\_{jj}}}(a\_{ij}-\sum \_{k=1}^{j-1}u\_{kj}l\_{ik})}}

We see in the second formula that to get the 

l

i
j
{\displaystyle {\displaystyle l\_{ij}}}
 below the diagonal, we have to divide by the diagonal element (pivot) 

u

j
j
{\displaystyle {\displaystyle u\_{jj}}}
, so we get problems when 

u

j
j
{\displaystyle {\displaystyle u\_{jj}}}
 is either 0 or very small, which leads to numerical instability.

The solution to this problem is *pivoting* 

A
{\displaystyle {\displaystyle A}}
, which means rearranging the rows of 

A
{\displaystyle {\displaystyle A}}
, prior to the 

L
U
{\displaystyle {\displaystyle LU}}
 decomposition, in a way that the largest element of each column gets onto the diagonal of 

A
{\displaystyle {\displaystyle A}}
. Rearranging the rows means to multiply 

A
{\displaystyle {\displaystyle A}}
 by a permutation matrix 

P
{\displaystyle {\displaystyle P}}
:

:   P
    A
    ⇒

    A
    ′
    {\displaystyle {\displaystyle PA\Rightarrow A'}}

Example:

:   (

    0

    1


    1

    0
    )


    (

    1

    4


    2

    3
    )
    ⇒


    (

    2

    3


    1

    4
    )
    {\displaystyle {\displaystyle {\begin{pmatrix}0&1\\1&0\end{pmatrix}}{\begin{pmatrix}1&4\\2&3\end{pmatrix}}\Rightarrow {\begin{pmatrix}2&3\\1&4\end{pmatrix}}}}

The decomposition algorithm is then applied on the rearranged matrix so that

:   P
    A
    =
    L
    U
    {\displaystyle {\displaystyle PA=LU}}

Task description

The task is to implement a routine which will take a square nxn matrix 

A
{\displaystyle {\displaystyle A}}
 and return a lower triangular matrix 

L
{\displaystyle {\displaystyle L}}
, a upper triangular matrix 

U
{\displaystyle {\displaystyle U}}
 and a permutation matrix 

P
{\displaystyle {\displaystyle P}}
,
so that the above equation is fulfilled.

You should then test it on the following two examples and include your output.

Example 1

```
A

1   3   5
2   4   7
1   1   0

L

1.00000   0.00000   0.00000
0.50000   1.00000   0.00000
0.50000  -1.00000   1.00000

U

2.00000   4.00000   7.00000
0.00000   1.00000   1.50000
0.00000   0.00000  -2.00000

P

0   1   0
1   0   0
0   0   1

```

Example 2

```
A

11    9   24    2
 1    5    2    6
 3   17   18    1
 2    5    7    1

L

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

U

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

P

1   0   0   0
0   0   1   0
0   1   0   0
0   0   0   1

```
assistant
(formerly Perl 6)

Translation of Ruby.

```
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 X ^$n -> ($i,$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] }
    }
    @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;
            }
        }
        @id[$row, $i] = @id[$i, $row] if $row != $i;
    }
    @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 ~~ Int;
    $num.nude.join: '/';

}

sub say-it ($message, @array) {
    say "\n$message";
    $_».&rat-int.fmt("%7s").say for @array;
}

```

Output:

```
A Matrix
      1       3       5
      2       4       7
      1       1       0

P Matrix
      0       1       0
      1       0       0
      0       0       1

Aʼ Matrix
      2       4       7
      1       3       5
      1       1       0

L Matrix
      1       0       0
    1/2       1       0
    1/2      -1       1

U Matrix
      2       4       7
      0       1     3/2
      0       0      -2

A Matrix
     11       9      24       2
      1       5       2       6
      3      17      18       1
      2       5       7       1

P Matrix
      1       0       0       0
      0       0       1       0
      0       1       0       0
      0       0       0       1

Aʼ Matrix
     11       9      24       2
      3      17      18       1
      1       5       2       6
      2       5       7       1

L Matrix
      1       0       0       0
   3/11       1       0       0
   1/11   23/80       1       0
   2/11  37/160   1/278       1

U Matrix
     11       9      24       2
      0  160/11  126/11    5/11
      0       0 -139/40   91/16
      0       0       0  71/139

```