📄 matrix.c
字号:
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include "matrix.h"
int main( int argc, char *argv[] )
{
MATRIX *A, *B, *C, *D, *E, *I;
USHORT i, j;
double dVal;
printf( "\n\nHello World\n\n" );
A = dimension( 3, 1, COL );
C = dimension( 3, 3, ROW );
I = dimension( 3, 3, ROW );
printf( "Matrices dimensioned\n" );
in_matrix( C, 0, 0, 2.0 );
in_matrix( C, 0, 1, 3.0 );
in_matrix( C, 1, 0, 1.0 );
in_matrix( C, 1, 1, 4.0 );
in_matrix( C, 2, 2, 6.0 );
in_matrix( A, 0, 0, 1.0 );
in_matrix( A, 1, 0, 1.0 );
in_matrix( A, 2, 0, 6.0 );
in_matrix( I, 0, 0, 1.0 );
in_matrix( I, 1, 1, 1.0 );
in_matrix( I, 2, 2, 1.0 );
printf( "Matrix C, to be decomposed\n" );
mat_print( C );
B = mult_matrices( C, I );
printf( "B = CI = C\n" );
mat_print( B );
printf( "Constant Matrix\n" );
mat_print( A );
D = solve( C, A );
printf( "Solution 0.2, 0.2, 1.0\n" );
mat_print( D );
remove_matrix( D );
change_rep( &C );
printf( "C in column rep\n" );
mat_print( C );
D = solve( C, A );
printf( "Solution 0.2, 0.2, 1.0 C in COL rep\n" );
mat_print( D );
remove_matrix( D );
D = const_mult_matrix( C, 2.0 );
printf( "D = 2 * C\n" );
mat_print( D );
remove_matrix( D );
D = add_matrices( C, I );
printf( "D = C + I\n" );
mat_print( D );
remove_matrix( D );
D = sub_matrices( C, I );
printf( "D = C - I\n" );
mat_print( D );
remove_matrix( D );
return( 0 );
} /* main */
/*** dimension() *********************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY:
* Allocate storage for a matrix of given dimension.
* All fields within the matrix structure are initialized.
* A pointer to a structure defining the new matrix, or
* a NULL pointer if enough memory isn't available is returned.
*
* INPUT :
* new_matrix = dimension( num_rows, num_cols, matrix_type )
*
* num_rows : Number of rows in matrix
* num_cols : Number of columns in matrix
* matrix_type : Storage method for matrix
*
* OUTPUT :
* MATRIX * : Pointer to dimensioned matrix
* NULL : Error, Out of memory
*
* OPERATIONS :
* Allocate storage for matrix body
* Use matrix_type to determine how many row/column pointers are
* needed, then allocate storage for them.
* If enough memory wasn't available return null, else
* Initialize matrix body with given parameters, and all first row
* pointers to NULL.
*
***********************************************************************/
MATRIX *dimension( BYTE num_rows, BYTE num_cols, BYTE matrix_type )
{
MATRIX *mat;
USHORT usSize;
USHORT usNumPointers;
usSize = sizeof( MATRIX );
mat = ( MATRIX * )malloc( usSize );
if( mat == NULL )
return( NULL );
switch( matrix_type ) {
case ROW :
usNumPointers = num_rows;
break;
case COL :
usNumPointers = num_cols;
break;
case FULL:
usNumPointers = num_rows + num_cols;
break;
} /* switch( matrix_type ) */
usSize = usNumPointers * sizeof( MATRIX_ELEM * );
mat->pFirst = malloc( usSize );
if( mat->pFirst == NULL )
return( NULL );
mat->bRow = num_rows;
mat->bCol = num_cols;
mat->bType = matrix_type;
while( usNumPointers-- > 0 )
( *mat->pFirst )[ usNumPointers ] = NULL;
return( mat );
} /* dimension */
/*** in_matrix() ********************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY :
* Enter the passed number into the desired matrix at the specified
* location.
*
* INPUT :
* ret_condition = in_matrix( pMatrix, bRow, bCol, dValue )
*
* pMatrix : Pointer to matrix which element is to be stored
* bRow : Row where element is to be stored
* bCol : Column where element is to be stored
* dVal : Value to be stored in matrix pMatrix
*
* OUTPUT :
* 0 : Element was stored properly
* 1 : Error, pMatrix was NULL
* 2 : Error, row or col > matrix dimensions
*
* OPERATIONS :
* Confirm matrix exist and desired location is whithin it.
* From matrix type, determine number of links and maximum length
* for these links.
* Ensure that only non-zero elements are stored in the matrix.
* If the location to be stored is the first in a chain, allocate
* storage for an element and add it directly into the chain
* else if the first element of the chain is to be replaced,
* replace old element with new. If element is zero, existing
* element must be removed from the chain, and it's memory
* freed.
* else scan chain to desired location. Then insert new element into
* chain as above.
*
**********************************************************************/
int in_matrix( MATRIX *pMatrix, BYTE bRow, BYTE bCol, double dValue )
{
MATRIX_ELEM *pNew;
MATRIX_ELEM *pTemp;
MATRIX_ELEM *pRemove;
MATRIX_ELEM *pFound;
BYTE bType;
BYTE bLink;
BYTE bIndex;
if( pMatrix == NULL )
return( 1 );
if( ( pMatrix->bRow < bRow ) || ( pMatrix->bCol < bCol ) )
return( 2 );
bType = pMatrix->bType;
bType = pMatrix->bType & LOW;
switch( bType ) {
case ROW :
bLink = bRow;
bIndex = bCol;
break;
case COL :
bLink = bCol;
bIndex = bRow;
break;
} /* switch( bType ) */
if( ( ( *pMatrix->pFirst )[ bLink ] == NULL ) && ( dValue != 0.0 ) ){
pNew = make_elem( bIndex, dValue );
( *pMatrix->pFirst )[ bLink ] = pNew;
} else if( ( *pMatrix->pFirst )[ bLink ]->index == bIndex ) {
if( dValue != 0.0 )
( *pMatrix->pFirst )[ bLink ]->elem = dValue;
else {
pRemove = ( *pMatrix->pFirst )[ bLink ];
( *pMatrix->pFirst )[ bLink ] = pRemove->pNext;
free( pRemove );
} /* else */
} else if( ( *pMatrix->pFirst )[ bLink ]->index > bIndex ) {
if( dValue != 0.0 ) {
pNew = make_elem( bIndex, dValue );
pNew->pNext = ( *pMatrix->pFirst )[ bLink ];
( *pMatrix->pFirst )[ bLink ] = pNew;
} /* if( dValue != 0.0 ) */
} else {
pTemp = find_location( ( *pMatrix->pFirst )[ bLink ], bIndex );
if( pTemp->index == bIndex ) {
if( dValue == 0.0 ) {
pRemove = pTemp->pNext;
pTemp->pNext = pRemove->pNext;
free( pRemove );
} else {
pTemp->pNext->elem = dValue;
} /* else */
} else if( dValue != 0.0 ) {
pNew = make_elem( bIndex, dValue );
insert_in_list( pTemp, pNew );
} /* else */
} /* else */
return( 0 );
} /* in_matrix */
/*** make_elem() ********************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY :
* Allocate storage for a matrix element, and initialize it.
*
* INPUT :
* new_element = make_elem( bIndex, dValue )
*
* bIndex : Index of new element. In a ROW matrix, this
* represents the column of the element. In a COL
* matrix, this represents the row of the element.
* dValue : Numerical value of element.
*
* OUTPUT :
* MATRIX_ELEM * : Pointer to allocated matrix element.
* NULL : Error, Out of memory.
*
* OPERATIONS :
* Allocate storage for element.
* if memory wasn't available return NULL
* else Initialize all element to values passed to function.
*
************************************************************************/
MATRIX_ELEM *make_elem( BYTE bIndex, double dValue )
{
MATRIX_ELEM *pTemp;
if( ( pTemp = ( MATRIX_ELEM * )malloc( sizeof( MATRIX_ELEM ) ) ) == NULL )
return( NULL );
pTemp->index = bIndex;
pTemp->elem = dValue;
pTemp->pNext = NULL;
return( pTemp );
} /* make_elem */
/*** insert_in_list() ********************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY :
* Insert matrix element into chain of row / column elements.
*
* INPUT :
* insert_in_list( pPosition, pToAdd )
*
* pPosition : Pointer to element imediately before position
* where new element is to be inserted in chain.
* pToAdd : Element to insert in chain.
*
* OUTPUT :
* None.
*
* OPERATIONS :
* Save next pointer of Position, for once it is replaced, it woult
* be lost.
* Replace next pointer of Position with address of ToAdd element.
* Store saved next pointer in ToAdd element.
*
***************************************************************************/
void insert_in_list( MATRIX_ELEM *pPosition, MATRIX_ELEM *pToAdd )
{
MATRIX_ELEM *temp;
temp = pPosition->pNext;
pPosition->pNext = pToAdd;
pToAdd->pNext = temp;
} /* insert_in_list */
/*** out_matrix() ***********************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY :
* Retrieve the number stored in the passed matrix at the specified
* location. The element is left as found.
*
* INPUT :
* ret_condition = out_matrix( pMatrix, bRow, bCol, pdValue )
*
* pMatrix : Pointer to matrix which element is to be located.
* bRow : Row of desired element.
* bCol : Column of desired element.
* pdValue : Pointer to double where output value is placed.
*
* OUTPUT :
* 0 : Element was found and returned properly
* 1 : Error, pMatrix was NULL
* 2 : Error, row or col > matrix dimensions
*
*
* OPERATIONS :
* Determine number of chains and maximum length from matrix type.
* Find specified location in chain, and return it's value.
* If the element isn't in the chain, it must be zero.
*
***************************************************************************/
double out_matrix( MATRIX *pMatrix, BYTE bRow, BYTE bCol, double *pdValue )
{
MATRIX_ELEM *pTemp;
MATRIX_ELEM *pList;
BYTE bNumPointers;
BYTE bIndex;
BYTE bType;
if( pMatrix == NULL )
return( 1 );
if( ( pMatrix->bRow < bRow ) || ( pMatrix->bCol < bCol ) )
return( 2 );
bType = pMatrix->bType & LOW;
switch( bType ) {
case FULL:
case ROW :
bNumPointers = bRow;
bIndex = bCol;
break;
case COL :
bNumPointers = bCol;
bIndex = bRow;
break;
} /* switch( type */
pList = ( *pMatrix->pFirst )[ bNumPointers ];
if( pList == NULL )
*pdValue = 0.0;
else if( pList->index == bIndex )
*pdValue = (*pMatrix->pFirst)[ bNumPointers ]->elem;
else {
pTemp = find_location( ( *pMatrix->pFirst )[ bNumPointers ], bIndex );
if( pTemp->pNext->index == bIndex )
*pdValue = pTemp->pNext->elem;
else
*pdValue = 0.0;
} /* else */
return( 0 );
} /* out_matrix */
/*** find_location() ********************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY :
* Find an element in the chain with the specified index. Return a
* pointer to the element imediately preceeding the element, or the spot
* where the element would be located in the chain if it isn't present.
*
* INPUT :
* matrix_elem = find_location( pChain, bIndex )
*
* pChain : Pointer to beginning of chain to be searched.
* bIndex : Index of desired element. This corresponds to the row
* for COL matrices and the column for ROW matrices.
*
* OUTPUT :
* MATRIX_ELEM * : Pointer to element preceeding desired element's
* location in chain.
*
* OPERATIONS :
* Initialize both current and old location pointers to the start of
* the chain.
* Scan chain until the index of the current element is greater that
* the desired location, or the chain ends. Before updating the
* current location pointer, store it in the old location pointer.
* Return the old location pointer which will now point to the desired
* element.
***************************************************************************/
MATRIX_ELEM *find_location( MATRIX_ELEM *pFirst, BYTE bIndex )
{
MATRIX_ELEM *pCurr;
MATRIX_ELEM *pOld;
pCurr = pFirst;
pOld = pFirst;
while( pCurr != NULL ) {
if( pCurr->index < bIndex ) {
pOld = pCurr;
pCurr = pCurr->pNext;
} else
break;
} /* while */
return( pOld );
} /* find_location */
/*** remove_from_list() *****************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY :
* Remove the element with the specified index for the given chain.
*
* INPUT :
* ret_condition = remove_from_list( pFirst, to_remove )
*
* pFirst : Pointer to first element in chain from which element
* is to be removed.
* to_remove : Index of element to remove.
*
* OUTPUT :
* 0 : Element was removed.
* 1 : Element wasn't found, chain left unchanged.
*
* OPERATIONS :
* Determine if the element to remove is in the chain.
* find_location will return a pointer the the element preceeding the
* element to be removed.
* if the element is in the chain, remove it. First save the pointer
* to the element to be discarded. Then update the next pointer
* returned from find_location. Return the memory to the pool that
* was occupied by the discarded element.
*
***************************************************************************/
int remove_from_list( MATRIX_ELEM *start, BYTE to_remove )
{
MATRIX_ELEM *pTemp;
MATRIX_ELEM *pRemoved;
pTemp = find_location( start, to_remove );
if( pTemp->pNext->index == to_remove ) {
pRemoved = pTemp->pNext->pNext;
pTemp->pNext->pNext = pRemoved->pNext;
free( pRemoved );
return( 0 );
} else
return( 1 );
} /* remove_from_list */
/*** add_matrices() ***********************************************************
*
* Mike Foley
* January 21, 1989
*
* FUNCTIONAL SUMMARY :
* Add two matrices together.
*
* INPUT :
* result_matrix = add_matrices( pMatrix1, pMatrix2 )
*
* pMatrix1 : Pointer to first matrix.
* pMatrix2 : Pointer to second matrix.
*
* OUTPUT :
* MATRIX * : Pointer to result matrix, pMatrix1 + pMatrix2.
* NULL : Error condition :
* Matrix dimensions don't match.
* Out of memory.
*
* OPERATIONS :
* If either matrix is NULL, return the other matrix. This treat NULL
* like a zero.
* Check that demensions of matrices match.
* Dimension space for resultant matrix.
* Ensure that both matrices are in the same format.
* For each row in the matrices :
* Scan each chain adding elements with equal indices. Update
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -