A pascal matrix is a two-dimensional square matrix holding numbers from   Pascal's triangle,   also known as   binomial coefficients   and which can be shown as   nCr.

Shown below are truncated   5-by-5   matrices   M[i, j]   for   i,j   in range   0..4. 


A Pascal upper-triangular matrix that is populated with   jCi:

[[1, 1, 1, 1, 1],
 [0, 1, 2, 3, 4],
 [0, 0, 1, 3, 6],
 [0, 0, 0, 1, 4],
 [0, 0, 0, 0, 1]]

A Pascal lower-triangular matrix that is populated with   iCj   (the transpose of the upper-triangular matrix):

[[1, 0, 0, 0, 0],
 [1, 1, 0, 0, 0],
 [1, 2, 1, 0, 0],
 [1, 3, 3, 1, 0],
 [1, 4, 6, 4, 1]]

A Pascal symmetric matrix that is populated with   i+jCi:

[[1, 1, 1, 1, 1],
 [1, 2, 3, 4, 5],
 [1, 3, 6, 10, 15],
 [1, 4, 10, 20, 35],
 [1, 5, 15, 35, 70]]



Task

Write functions capable of generating each of the three forms of   n-by-n   matrices.

Use those functions to display upper, lower, and symmetric Pascal   5-by-5   matrices on this page.

The output should distinguish between different matrices and the rows of each matrix   (no showing a list of 25 numbers assuming the reader should split it into rows).



Note
 
The   Cholesky decomposition   of a Pascal symmetric matrix is the Pascal lower-triangle matrix of the same size.




get "libhdr"
manifest $( size = 5 $)
 
// Matrix index
let ix(mat, n, x, y) = mat+y*n+x
 
let lower(m, n) be
    for y=0 to n-1
        for x=0 to n-1 do
            !ix(m,n,x,y) :=
                x>y       -> 0,
                x=y | x=0 -> 1,
                !ix(m,n,x-1,y-1) + !ix(m,n,x,y-1) 
 
 
let upper(m, n) be
    for y=0 to n-1
        for x=0 to n-1 do
            !ix(m,n,x,y) :=
                x<y       -> 0,
                x=y | y=0 -> 1,
                !ix(m,n,x-1,y-1) + !ix(m,n,x-1,y)
 
let symmetric(m, n) be
    for y=0 to n-1
        for x=0 to n-1 do
            !ix(m,n,x,y) :=
                x=0 | y=0 -> 1,
                !ix(m,n,x-1,y) + !ix(m,n,x,y-1)
 
// Print matrix
let writemat(m, n, d) be
    for y=0 to n-1
    $(  for x=0 to n-1
        $(  writed(!ix(m,n,x,y), d)
            wrch(' ')
        $)
        wrch('*N')
    $)
 
// Generate and print 5-by-5 matrices
let start() be
$(  let mat = vec size * size
 
    writes("Upper-triangular matrix:*N")
    upper(mat, size) ; writemat(mat, size, 2)
 
    writes("*NLower-triangular matrix:*N")
    lower(mat, size) ; writemat(mat, size, 2)
 
    writes("*NSymmetric matrix:*N")
    symmetric(mat, size) ; writemat(mat, size, 2)
$)