home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 21 / IOPROG_21.ISO / SOFT / LIBMAT.ZIP / MATRIX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-20  |  8.1 KB  |  307 lines

  1. /**************************************************/
  2. /*    matrix.c source for basic matrix class      */
  3. /**************************************************/
  4.  
  5.  
  6. /**************************************************/
  7. /*            MatClass Source File                */
  8. /*       Copyright of C. R. Birchenhall           */
  9. /*       University of Manchester, UK.            */
  10. /*   MatClass is freeware. This file should be    */
  11. /* made freely available to users of any software */
  12. /* whose creation is wholly or partly dependent   */
  13. /*                on this file.                   */
  14. /**************************************************/
  15.  
  16. #include "matrix.hpp"
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20. // for sqrt
  21.  
  22. #ifndef __cplusplus
  23. #define NULL 0L
  24. #endif
  25.  
  26. void matrix::reset( INDEX nr, INDEX nc )
  27. {
  28.    static char *mName="reset" ;
  29.    matFunc func( mName ) ;
  30.    if ( ( nRows() != nr ) || ( nCols() != nc ) ) {
  31.       if ( nRefs() > 1 )
  32.          errorExit( mName, MREFS ) ;
  33.       pm->reset( nr, nc ) ;
  34.       debugInfo( func ) ;
  35.    } // if
  36.    return ;
  37. } // matrix::reset
  38.  
  39. void matrix::reset( INDEX nr )
  40. {
  41.     reset( nr, 1 ) ;
  42. } //  matrix::reset
  43.  
  44. #ifdef __cplusplus
  45. matrix::matrix( INDEX nr, INDEX nc ) : matObject( )
  46. #else
  47. matrix::matrix( INDEX nr, INDEX nc ) : ( )
  48. #endif
  49. {
  50.    static char *mName="matrix(,)" ;
  51.    matFunc func( mName ) ;
  52.    type = STANDARD ;
  53.    pm = new matMap( nr, nc ) ;
  54.    func.trace(TRUE) ; // debugInfo( func ) ;
  55. } // matrix::matrix( INDEX, INDEX )
  56.  
  57. #ifdef __cplusplus
  58. matrix::matrix( char* nameStr, INDEX nr, INDEX nc ) : matObject()
  59. #else
  60. matrix::matrix( char* nameStr, INDEX nr, INDEX nc ) : ()
  61. #endif
  62. {
  63.    static char *mName="matrix(ch,,)" ;
  64.    matFunc func( mName ) ;
  65.    type = STANDARD ;
  66.    pm = new matMap( nr, nc ) ;
  67.    pm->nm = nameStr ;
  68.    func.trace(TRUE) ; // debugInfo( func ) ;
  69. } // matrix::matrix( char*, INDEX, INDEX )
  70.  
  71. void matrix::clear( void )
  72. {
  73.    static char *mName="clear" ;
  74.    matFunc func( mName ) ; debugInfo( func ) ;
  75.    if ( pm != 0 )
  76.       pm->clear() ;
  77. } // matrix::clear
  78.  
  79. #ifdef __cplusplus
  80. matrix::matrix( void ) : matObject()
  81. #else
  82. matrix::matrix( void ) : ()
  83. #endif
  84. {
  85.    static char *mName="matrix" ;
  86.    matFunc func( mName ) ;
  87.    type = STANDARD ;
  88.    pm = new matMap ;
  89.    func.trace(TRUE) ; // debugInfo( func ) ;
  90. } // matrix::matrix( void )
  91.  
  92. matrix::~matrix( void )
  93. {
  94.    static char *mName="~matrix" ;
  95.    matFunc func( mName ) ; debugInfo( func ) ;
  96.    if ( pm != 0 && --pm->ref == 0 )
  97.       delete pm ;
  98. } // matrix::~matrix
  99.  
  100. #ifdef __cplusplus
  101. matrix::matrix( matrix &y ) : matObject()
  102. #else
  103. matrix::matrix( matrix &y ) : ()
  104. #endif
  105. {
  106.    static char *mName = "matrix(&y)" ;
  107.    matFunc func( mName ) ;
  108.    type = y.type ;
  109.    pm = y.pm ;
  110.    if ( pm != 0 )
  111.       pm->ref++ ;
  112.    func.trace(TRUE) ; // debugInfo( func ) ;
  113. } // matrix::matrix( matrix& )
  114.  
  115. INDEX matrix::isNull( void ) M_CONST
  116. { return ( pm == 0 || pm->pa == 0 ) ; }
  117.  
  118. INDEX matrix::isTrans( void ) M_CONST
  119. { return type == TRANSPOSED ; }
  120.  
  121. INDEX matrix::nRefs( void ) M_CONST
  122. { return pm == 0 ? 0 : pm->ref ; }
  123.  
  124. INDEX matrix::nRows( void ) M_CONST
  125. { return pm == 0 ? 0 : pm->nrow ; }
  126.  
  127. INDEX matrix::nCols( void ) M_CONST
  128. { return pm == 0 ? 0 : pm->ncol ; }
  129.  
  130. LONG matrix::size( void ) M_CONST
  131. { return ( pm == 0 ) ? 0 : (LONG)(pm->ncol) * (LONG)(pm->nrow) ; }
  132.  
  133. REAL& matrix::xmat( INDEX i, INDEX j ) M_CONST
  134. {
  135.    static char *mName = "xmat(i,j)" ;
  136.    if ( isNull() )
  137.       errorExit( mName, UNASS ) ;
  138.    if ( ( i < 1 ) || ( j < 1 ) || ( i > nRows() ) || ( j > nCols() ) )
  139.       errorExit( mName, NRANG ) ;
  140.    return pm->map[j][i] ;
  141. }// matrix::xmat
  142.  
  143. REAL& matrix::vec( LONG k ) M_CONST
  144. {
  145.    static char *mName = "vec()" ;
  146.    INDEX i, j, nr = nRows() ;
  147.    if ( isNull() )
  148.       errorExit( mName, UNASS ) ;
  149.    if ( k >= 1 ) {
  150.      k-- ;
  151.      i = (INDEX)( ( k % nr ) + 1) ;
  152.      j = (INDEX)( ( k / nr ) + 1) ;
  153.    } // if
  154.    if ( j > nCols() ) {
  155.       errorij( i, j ) ;
  156.       errorExit( mName, NRANG ) ;
  157.    } // if
  158.    return mat(i,j) ;
  159. } // matrix::vec
  160.  
  161. void matrix::capture( matrix& y )
  162. {
  163.    static char *mName = "capture" ;
  164.    matFunc func( mName ) ; debugInfo( func ) ;
  165.    if ( pm != 0 && --pm->ref == 0 )
  166.       delete pm ;
  167.    pm = y.pm ;
  168.    pm->ref++ ;
  169.    y.clear() ;
  170. } // matrix::capture
  171.  
  172. matrix& matrix::operator = ( const matrix &y )
  173. {
  174.    static char *mName = "op =" ;
  175.    matFunc func( mName ) ; debugInfo( func ) ;
  176.    if ( this->identity() == y.identity() )
  177.       return *this ;
  178.    INDEX nr = y.nRows(), nc = y.nCols(), j ;
  179.    if ( nRefs() <= 1 )
  180.       reset( nr, nc ) ;
  181.    else if ( ( nRows() != nr ) || ( nCols() != nc ) )
  182.       errorExit( mName, NEDIM ) ;
  183.    INDEX size = nr * sizeof( REAL ) ;
  184.    for ( j = 1 ; j <= nc ; j++ )
  185.       memcpy( (void *)(pm->map[j] + 1),
  186.           (void *)(y.pm->map[j] + 1), size ) ;
  187.    return *this ;
  188. } // matrix = matrix
  189.  
  190.  
  191. /***************************************************/
  192. /*   initialisation methods for matrix class       */
  193. /***************************************************/
  194.  
  195. #include <stdarg.h>
  196.  
  197. matrix& matrix::assign( INDEX nr, INDEX nc, ... )
  198. {
  199.    static char *mName = "assign" ;
  200.    matFunc func( mName ) ; debugInfo( func ) ;
  201.    if ( nr != nRows() || nc != nCols() ) {
  202.       if ( nRefs() > 1 )
  203.      errorExit( mName, NEDIM ) ;
  204.       else
  205.      reset( nr, nc ) ;
  206.    } // if
  207.    va_list ap ;
  208.    va_start( ap, nc ) ;
  209.    INDEX i , j ;
  210.    for ( i = 1 ; i <= nr ; i++ )
  211.       for ( j = 1; j <= nc ; j++ )
  212.      mat(i,j) = va_arg( ap , double ) ;
  213.    va_end( ap ) ;
  214.    return *this ;
  215. } // matrix::assign
  216.  
  217. /**************************************************************/
  218. /*   matrix (non-iostream) I/O for matrix class               */
  219. /**************************************************************/
  220.  
  221. outFile& matrix::info( outFile& f ) M_CONST
  222. {
  223.    if ( matListCtrl() > 3 )
  224.       return f ;
  225.    objectInfo( f ) ;
  226.    if ( pm != 0 )
  227.       putName( pm->nm.array(), f ) ;
  228.    else
  229.       putName( "", f ) ;
  230.    putName( "matrix", f ) ;
  231.    putField( nRows(), f ) ;
  232.    putField( nCols(), f ) ;
  233.    if ( pm != 0 )
  234.       putField( pm->identity(), f ) ;
  235.    else
  236.       putField( "NA", f ) ;
  237.    f.newLine() ;
  238.    return f ;
  239. } // matrix::info
  240.  
  241. outFile& matrix::display( outFile& f ) M_CONST
  242. {
  243.    static char *mName = "display" ;
  244.    matFunc func( mName ) ; debugInfo( func ) ;
  245.    int oldform = matFormat() ;
  246.    matFormat( oldform & SCIENTIFIC ? DISPLAY|SCIENTIFIC : DISPLAY ) ;
  247.    put( f ) ;
  248.    matFormat( oldform ) ;
  249.    return f ;
  250. } // matrix display
  251.  
  252. charArray matrix::name( char *newName )
  253. {
  254.    static char *mName = "name" ;
  255.    matFunc func( mName ) ; debugInfo( func ) ;
  256.    if ( pm == 0 )
  257.       pm = new matMap ;
  258.    if ( newName != 0 )
  259.       pm->nm = newName ;
  260.    return pm->nm ;
  261. } // matrix::name
  262.  
  263. outFile& matrix::print( char *title, outFile& f ) M_CONST
  264. {
  265.    static char *mName = "print" ;
  266.    matFunc func( mName ) ; debugInfo( func ) ;
  267.    f.newLine();
  268.    if ( title != 0 )
  269.       f.write( title ).newLine() ;
  270.    else if ( pm != 0 ) {
  271.       f.writeChar( pm->nm ) ; 
  272.       f.newLine() ;
  273.    } // else
  274.    display( f ) ;
  275.    f.newLine() ;
  276.    return f ;
  277. } // matrix::print
  278.  
  279. matrix& matrix::read( void )
  280. {
  281.    static char *mName = "read" ;
  282.    matFunc func( mName ) ; debugInfo( func ) ;
  283.    errout.newLine().write( "Input matrix with " ) ;
  284.    errout.writeIndex( nRows() ).write( " rows and " ) ;
  285.    errout.writeIndex( nCols() ).write( " columns : " ).newLine() ;
  286.    get( in ) ;
  287.    errout.write( "Ok." ).newLine() ;
  288.    return *this ;
  289. } // matrix::read
  290.  
  291. void matrix::checkDims( const matrix& y, char *name ) M_CONST
  292. /************************************************************
  293.    Check the two matrices are not null and that they
  294.    have the same dimension.
  295. ************************************************************/
  296. {
  297.    if ( isNull() )
  298.       errorExit( name, NULRF ) ;
  299.    if ( y.isNull() )
  300.       y.errorExit( name, NULRF ) ;
  301.    INDEX nr = nRows(), nc = nCols() ;
  302.    if ( ( nr != y.nRows() ) || ( nc != y.nCols() ) ) {
  303.       y.error( name, NEDIM ) ;
  304.       errorExit( name, NEDIM ) ;
  305.    } // if
  306. } // matrix::checkDims
  307.