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.




begin
    % initialises m to an upper Pascal matrix of size n %
    % the bounds of m must be at least 1 :: n, 1 :: n   %
    procedure upperPascalMatrix ( integer array m( *, * )
                                ; integer value n
                                ) ;
    begin
        for j := 1 until n do m( 1, j ) := 1;
        for i := 2 until n do begin
            m( i, 1 ) := 0;
            for j := 2 until n do m( i, j ) := m( i - 1, j - 1 ) + m( i, j - 1 )
        end for_i
    end upperPascalMatrix ;
 
    % initialises m to a lower Pascal matrix of size n  %
    % the bounds of m must be at least 1 :: n, 1 :: n   %
    procedure lowerPascalMatrix ( integer array m( *, * )
                               ; integer value n
                               ) ;
    begin
        for i := 1 until n do m( i, 1 ) := 1;
        for j := 2 until n do begin
            m( 1, j ) := 0;
            for i := 2 until n do m( i, j ) := m( i - 1, j - 1 ) + m( i - 1, j )
        end for_j
    end lowerPascalMatrix ;
 
    % initialises m to a symmetric Pascal matrix of size n %
    % the bounds of m must be at least 1 :: n, 1 :: n   %
    procedure symmetricPascalMatrix ( integer array m( *, * )
                                    ; integer value n
                                    ) ;
    begin
        for i := 1 until n do begin
            m( i, 1 ) := 1;
            m( 1, i ) := 1
        end for_i;
        for j := 2 until n do for i := 2 until n do m( i, j ) := m( i, j - 1 ) + m( i - 1, j )
    end symmetricPascalMatrix ;
 
    begin % test the pascal matrix procedures %
 
        % print the matrix m with the specified field width %
        % the bounds of m must be at least 1 :: n, 1 :: n   %
        procedure printMatrix ( integer array m( *, * )
                              ; integer value n
                              ; integer value fieldWidth
                              ) ;
        begin
            for i := 1 until n do begin
                write(                         i_w := fieldWidth, s_w := 0, " ", m( i, 1 ) );
                for j := 2 until n do writeon( i_w := fieldWidth, s_w := 0, " ", m( i, j ) )
            end for_i
        end printMatrix ;
 
        integer array m( 1 :: 10, 1 :: 10 );
        integer n, w;
 
        n := 5; w := 2;
        upperPascalMatrix(     m, n ); write( "upper:"     ); printMatrix( m, n, w );
        lowerPascalMatrix(     m, n ); write( "lower:"     ); printMatrix( m, n, w );
        symmetricPascalMatrix( m, n ); write( "symmetric:" ); printMatrix( m, n, w )
 
    end
 
end.