Gan_Matrix *pmA; pmA = gan_mat_alloc ( 3, 5 );or
Gan_Matrix mA; gan_mat_form ( &mA, 3, 5 );Both these examples create a matrix with three rows and five columns. The former allocates a structure and passes back a pointer to it, whereas the latter builds the matrix using the provided structure mA. Whichever routine is used, the two matrices are equivalent in every way and can be used in all the Gandalf general size matrix routines.
In the above calls Gandalf will invoke malloc() to create the data block to hold the matrix elements. Sometimes you will want to provide the data block yourself, avoiding the malloc() call, if you know the size, or at least the maximum size, of the matrix. Then you can use the following routine.
Gan_Matrix mA; double adAData; gan_mat_form_data ( &mA, 3, 5, adXData, 10 );The last argument is the size of the array adXData passed in. This means that although the matrix mA is created with size five, the size of the data block, 10, is also stored, and this allows the size of mA to change (see gan_mat_set_size() below) up to size 10.
Once you have finished with a matrix, use the routine
gan_mat_free ( pmA ); /* for a pointer variable, OR */ gan_mat_free ( &mA ); /* for a structure variable */The gan_mat_free() routine applies without modification to all the methods of creating the matrix. The matrix structure maintains knowledge of which parts of it (the structure, the data block) were dynamically allocated, and only frees the bits that were allocated. To free several rectangular matrices at once use the variable argument list routine
gan_mat_free_va ( pmA, pmB, pmC, NULL ); /* free matrices A, B & C */which must be terminated by NULL to indicate the end of the list.
From now on, we use the convention that a ``square'' matrix refers to a square matrix with one of the special types listed above. A square general matrix falls into the category of rectangular matrices, for the purpose of the Gandalf linear algebra package. To create a square matrix with one of the special types use a function from one of the families
Gan_SquMatrix *psmS, *psmL, *psmU, *psmD, *psmsI; psmS = gan_symmat_alloc ( 3 ); /* create a 3x3 symmetric matrix */ psmL = gan_ltmat_alloc ( 3 ); /* create a 3x3 lower triangular matrix */ psmU = gan_utmat_alloc ( 3 ); /* create a 3x3 upper triangular matrix */ psmD = gan_diagmat_alloc ( 3 ); /* create a 3x3 diagonal matrix */ psmD = gan_scalImat_alloc ( 3 ); /* create a 3x3 scaled Identity matrix */or
Gan_SquMatrix smS, smL, smU, smD, smsI; gan_symmat_form ( &smS, 3 ); /* create a 3x3 symmetric matrix */ gan_ltmat_form ( &smL, 3 ); /* create a 3x3 lower triangular matrix */ gan_utmat_form ( &smU, 3 ); /* create a 3x3 upper triangular matrix */ gan_diagmat_form ( &smD, 3 ); /* create a 3x3 diagonal matrix */ gan_scalImat_form ( &smsI, 3 ); /* create a 3x3 scaled Identity matrix */There are also ..._form_data() functions available for the case that an array to hold the matrix data is already available. The size of the data array depends on the type of matrix; for instance a symmetric and triangular matrix has ten independent elements, while a diagonal matrix has only four, and a scaled identity matrix only one. The general formula for the number of independent elements in a triangular or symmetric matrix is
Gan_SquMatrix smS, smL, smU, smD, smsI; double adSdata, adLdata, adUdata, adDdata, dsIdata; gan_symmat_form_data ( &smS, 4, adSdata, 10 ); /* create 4x4 symmetric matrix */ gan_ltmat_form_data ( &smL, 4, adLdata, 10 ); /* create 4x4 lower triangular matrix */ gan_utmat_form_data ( &smU, 4, adUdata, 10 ); /* create 4x4 upper triangular matrix */ gan_diagmat_form_data ( &smD, 4, adDdata, 4 ); /* create 4x4 diagonal matrix */ gan_scalImat_form_data ( &smsI, 4, &dsIdata, 1 ); /* create 4x4 scaled Ident. mat. */The final way of creating a square matrix should be used only when the matrix type is a variable:
Gan_SquMatrixType type; Gan_SquMatrix *psmA, smA; double adAdata; /* ... set matrix type e.g. GAN_SYMMETRIC_MATRIX ... */ psmA = gan_squmat_alloc ( type, 4 ); /* create 4x4 square matrix, pointer version, OR */ gan_squmat_form ( &smA, type, 4 ); /* create 4x4 square matrix, structure version, OR */ gan_squmat_form_data ( &smA, type, 4, adAdata, 10 ); /* create 4x4 square matrix */These routines call the lower level routine specific to the provided type. Whichever type of matrix is created, use the function
gan_squmat_free ( psmA );to free the memory associated with it. The gan_squmat_free() routine applies to all the square matrix types and all methods (..._alloc(), ..._form() and ..._form_data()) of creating the matrix. The matrix structure maintains knowledge of which parts of it (the structure, the data block) were dynamically allocated, and only frees the bits that were allocated. To free several square matrices at once use the variable argument list routine
gan_squmat_free_va ( &smsI, &smD, &smU, &smL, &smS, NULL ); /* free square matrices */which must be terminated by NULL to indicate the end of the list.
From now on the example code fragments we provide will use the convention that matrices are declared as structures rather than pointers, but bear in mind that either style may be used.
Error detection: All the above matrix creation routines return a pointer to the created matrix. If an error occurs, the Gandalf error handler is invoked and NULL is returned. The most likely error modes are failing to allocate the data required (i.e. internal malloc() or realloc() calls failing), or passing too small an array into the ..._form_data() routines.