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.




 
sub print_matrix( M() as integer )
    'displays a matrix
    for row as integer = 0 to ubound(M, 1)
        for col as integer = 0 to ubound(M, 2)
            print using "####  ";M(row, col);
        next col
        print
    next row
    return
end sub
 
function fact( n as uinteger ) as uinteger 
    'quick and dirty factorial
    if n<2 then return 1 else return n*fact(n-1)
end function
 
function nCp( n as uinteger, p as uinteger ) as uinteger
    'quick and dirty binomial
    if p>n then return 0 else return fact(n)/(fact(p)*fact(n-p))
end function
 
sub make_pascal( M() as integer, typ as const ubyte )
    'allocate the matrix first
    'typ 0 = jCi, 1=iCj, 2=(j+i)Ci
    for i as uinteger = 0 to ubound(M,1)
        for j as uinteger = 0 to ubound(M,2)
            select case typ
                case 0
                    M(i,j) = nCp(j, i)
                case 1
                    M(i,j) = nCp(i, j)
                case 2
                    M(i,j) = nCp(i + j, j)
                case else
                    M(i, j) = 0
            end select
        next j
    next i
    return
end sub
 
dim as integer M(0 to 4, 0 to 4)
print "Upper triangular"
make_pascal( M(), 0 )
print_matrix( M() )
print "Lower triangular"
make_pascal( M(), 1 )
print_matrix( M() )
print "Symmetric"
make_pascal( M(), 2 )
print_matrix( M() )
print "Technically the matrix needn't be square :)"
dim as integer Q(0 to 4, 0 to 9)
make_pascal( Q(), 2 )
print_matrix( Q() )