                   /* Listing 1 */

/*****************************************************
           File Name: MATRIX_T.C
       Expanded Name: matrix type
Global Funciton List: cr_matrix
                      cr_matrix_s
                      fr_matrix
                      fr_matrix_s
         Description: Library of functions for
                      creation and destruction of
                      objects of type matrix_t.
*****************************************************/

/* Standard C */
#include <stdlib.h>

/* Own */
#include <matrix_t.h>

/*****************************************************
       Name: cr_matrix
 Parameters: NumRow - number of rows in matrix 
             NumCol - number of cols in matrix
     Return: matrix_t type or NULL if out of memory
Description: Constructor function for type matrix_t.
             Creates a matrix of size NumRow by
             NumCol on the heap.  The matrix resides
             in multiple blocks of memory.
*****************************************************/
matrix_t cr_matrix( size_t NumRow, size_t NumCol )
   {

   matrix_t Matrix;

   /* Allocate pointers to rows. */
   Matrix = calloc( 1, NumRow * sizeof ( double * ) );

   if ( Matrix != NULL )
      {

      size_t i;

      /* Allocate rows and set pointers to them. */
      for ( i = 0; i < NumRow; i++ )
         {

         Matrix[i] = calloc( NumCol,
               sizeof ( double ) );

         if ( Matrix[i] == NULL )
            {
            /* Out of memory */
            fr_matrix( Matrix, NumRow );
            Matrix = NULL;
            break;
            }   /* if Matrix[i] */

         }   /* for i */
      }   /* if Matrix */

   return ( Matrix );

   }   /* function cr_matrix */


/*****************************************************
       Name: cr_matrix_s
 Parameters: NumRow - number of rows in matrix 
             NumCol - number of cols in matrix
     Return: matrix_t type or NULL is out of memory
Description: Constructor function for type matrix_t.
             Creates a matrix of size NumRow by
             NumCol on the heap.  The matrix resides
             in a single contiguous block of memory.
*****************************************************/
matrix_t cr_matrix_s( size_t NumRow, size_t NumCol )
   {

   matrix_t Matrix;

   size_t SizeCol;

   SizeCol = NumCol * sizeof ( double );
   Matrix = calloc( 1, NumRow * ( sizeof ( double * )
         + SizeCol ) );

   if ( Matrix != NULL )
      {
      size_t i;
      Matrix[0] = (double *)&( Matrix[NumRow] );
      for ( i = 1; i < NumRow; i++ )
         {
         Matrix[i] = (double *)
               &( Matrix[i - 1][NumCol] );
         }
      }

   return ( Matrix );

   }   /* function cr_matrix_s */


/*****************************************************
       Name: fr_matrix
 Parameters: Matrix - matrix to free
             NumRow - number of rows in matrix 
             NumCol - number of cols in matrix
Description: Destructor function for type matrix_t.
             Frees a matrix that resides in multiple
             blocks of memory and was created with the
             function cr_matrix.
*****************************************************/
void fr_matrix( matrix_t Matrix, size_t NumRow )
   {

   if ( Matrix != NULL )
      {

      size_t i;

      for ( i = 0; i < NumRow; i++ )
         {
         if ( Matrix[i] != NULL )
            {
            free( Matrix[i] );
            }
         }   /* for i */

      free( Matrix );

      }   /* if Matrix */

   }   /* function fr_matrix */


/*****************************************************
       Name: fr_matrix_s
 Parameters: Matrix - matrix to free
Description: Destructor function for type matrix_t.
             Frees a matrix that resides in a single
             contiguous block of memory and was
             created with the function cr_matrix_s.
*****************************************************/
void fr_matrix_s( matrix_t Matrix )
   {

   if ( Matrix != NULL )
      {
      free( Matrix );
      }   /* if Matrix */

   }   /* function fr_matrix_s */

/* End of File */

