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.




/*REXX program  generates and displays  three forms of an   NxN   Pascal matrix.        */
numeric digits 50                                /*be able to calculate huge factorials.*/
parse arg N .                                    /*obtain the optional matrix size  (N).*/
if N==''  | N==","  then N= 5                    /*Not specified?  Then use the default.*/
                               call show  N,  upp(N),  'Pascal upper triangular matrix'
                               call show  N,  low(N),  'Pascal lower triangular matrix'
                               call show  N,  sym(N),  'Pascal symmetric matrix'
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
upp:  procedure; parse arg N;  $=                /*gen Pascal upper triangular matrix.  */
            do i=0  for N;  do j=0  for N; $=$ comb(j,   i);   end; end;   return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
low:  procedure; parse arg N;  $=                /*gen Pascal lower triangular matrix.  */
            do i=0  for N;  do j=0  for N; $=$ comb(i,   j);   end; end;   return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
sym:  procedure; parse arg N;  $=                /*generate  Pascal symmetric  matrix.  */
            do i=0  for N;  do j=0  for N; $=$ comb(i+j, i);   end; end;   return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
!:    procedure; parse arg x;  !=1;    do j=2  to x;  != !*j;  end;        return !
/*──────────────────────────────────────────────────────────────────────────────────────*/
comb: procedure; parse arg x,y;        if x=y  then return 1                /* {=} case.*/
                                       if y>x  then return 0                /* {>} case.*/
      if x-y<y  then y= x-y;  _= 1;    do j=x-y+1  to x;  _= _*j;  end;    return _ / !(y)
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: procedure; parse arg s,@;   w=0;    #=0                               /*get args. */
                       do x=1  for s**2;  w= max(w, 1 + length( word(@,x) ) );    end
      say;   say center( arg(3), 50, '─')                                   /*show title*/
                       do    r=1  for s;  if r==1  then $= '[['             /*row  1    */
                                                   else $= ' ['             /*rows 2   N*/
                          do c=1  for s;  #= #+1;   e= (c==s)               /*e ≡ "end".*/
                          $=$ || right( word(@, #), w) || left(',', \e) || left("]", e)
                          end   /*c*/                                       /* [↑]  row.*/
                       say $ || left(',', r\==s)left("]", r==s)             /*show row. */
                       end     /*r*/
      return