Sleipnir
src/halfmatrix.h
00001 /*****************************************************************************
00002 * This file is provided under the Creative Commons Attribution 3.0 license.
00003 *
00004 * You are free to share, copy, distribute, transmit, or adapt this work
00005 * PROVIDED THAT you attribute the work to the authors listed below.
00006 * For more information, please see the following web page:
00007 * http://creativecommons.org/licenses/by/3.0/
00008 *
00009 * This file is a component of the Sleipnir library for functional genomics,
00010 * authored by:
00011 * Curtis Huttenhower (chuttenh@princeton.edu)
00012 * Mark Schroeder
00013 * Maria D. Chikina
00014 * Olga G. Troyanskaya (ogt@princeton.edu, primary contact)
00015 *
00016 * If you use this library, the included executable tools, or any related
00017 * code in your work, please cite the following publication:
00018 * Curtis Huttenhower, Mark Schroeder, Maria D. Chikina, and
00019 * Olga G. Troyanskaya.
00020 * "The Sleipnir library for computational functional genomics"
00021 *****************************************************************************/
00022 #ifndef HALFMATRIX_H
00023 #define HALFMATRIX_H
00024 
00025 #include <string.h>
00026 
00027 #include "halfmatrixi.h"
00028 #include "meta.h"
00029 
00030 namespace Sleipnir {
00031 
00047 template<class tType>
00048 class CHalfMatrix : protected CHalfMatrixBase {
00049 public:
00063     static size_t GetSpace( size_t iSize ) {
00064 
00065         return ( ( ( iSize * ( iSize - 1 ) ) / 2 ) * sizeof(tType) ); }
00066 
00067     CHalfMatrix( ) : m_aaData(NULL) { }
00068 
00069     virtual ~CHalfMatrix( ) {
00070 
00071         Reset( ); }
00072 
00077     void Reset( ) {
00078         size_t  i;
00079 
00080         if( m_aaData && m_fMemory ) {
00081             for( i = 0; ( i + 1 ) < m_iSize; ++i )
00082                 delete[] m_aaData[ i ];
00083             delete[] m_aaData; }
00084 
00085         m_iSize = 0;
00086         m_aaData = NULL; }
00087 
00088     tType* GetFullRow( size_t iY ) {
00089         size_t i, j;
00090         tType *newData = new tType[m_iSize];
00091         for(i=0; i<m_iSize; i++){
00092             if(i==iY){
00093                 newData[i] = 0;
00094             }else if(i<iY){
00095                 newData[i] = m_aaData[i][iY-i-1];
00096             }else{
00097                 for(j=i; j<m_iSize; j++){
00098                     newData[j] = m_aaData[iY][j-iY-1];
00099                 }
00100                 break;
00101             }
00102         }
00103         return newData;
00104     }
00105 
00123     const tType* Get( size_t iY ) const {
00124 
00125         return m_aaData[ iY ]; }
00126 
00144     tType* Get( size_t iY ) {
00145 
00146         return m_aaData[ iY ]; }
00147 
00168     tType& Get( size_t iY, size_t iX ) const {
00169         static tType    c_Zero  = 0;
00170 
00171         if( iX == iY )
00172             return c_Zero;
00173 
00174         HalfIndex( iY, iX );
00175         return m_aaData[ iY ][ iX ]; }
00176 
00197     void Set( size_t iY, size_t iX, const tType& Value ) {
00198 
00199         if( iX == iY )
00200             return;
00201 
00202         HalfIndex( iY, iX );
00203         m_aaData[ iY ][ iX ] = Value; }
00204 
00222     void Set( size_t iY, const tType* aValues ) {
00223 
00224         memcpy( m_aaData[ iY ], aValues, sizeof(*m_aaData[ iY ]) * ( m_iSize - iY - 1 ) ); }
00225 
00237     void Initialize( const CHalfMatrix& Mat ) {
00238 
00239         Initialize( Mat.GetSize( ), Mat.m_aaData ); }
00240 
00255     virtual void Initialize( size_t iSize, tType** aaData = NULL ) {
00256         size_t  i;
00257 
00258         Reset( );
00259         m_iSize = iSize;
00260         if( m_fMemory = !( m_aaData = aaData ) ) {
00261             m_aaData = iSize ? new tType*[ m_iSize - 1 ] : NULL;
00262             for( i = 0; ( i + 1 ) < m_iSize; ++i )
00263                 m_aaData[ i ] = new tType[ m_iSize - i - 1 ]; } }
00264 
00275     size_t GetSize( ) const {
00276 
00277         return m_iSize; }
00278 
00279     bool SetSize( size_t iSize, bool fClear = false ) {
00280         tType** aaData;
00281         size_t  i, iCur;
00282 
00283         if( !m_fMemory )
00284             return false;
00285         if( !iSize ) {
00286             Reset( );
00287             return true; }
00288 
00289         aaData = new tType*[iSize - 1];
00290         for( i = 0; ( i + 1 ) < iSize; ++i ) {
00291             aaData[i] = new tType[iCur = ( iSize - i - 1 )];
00292             if( i < m_iSize )
00293                 memcpy( aaData[i], m_aaData[i], ( min( iSize, m_iSize ) - i - 1 ) * sizeof(*aaData[i]) );
00294             if( fClear && ( iSize > m_iSize ) )
00295                 std::fill( aaData[i] + ( ( i < m_iSize ) ? ( m_iSize - i - 1 ) : 0 ), aaData[i] + iCur, CMeta::GetNaN( ) ); }
00296         Reset( );
00297         m_iSize = iSize;
00298         m_aaData = aaData;
00299 
00300         return true; }
00301 
00306     void Clear( ) {
00307         size_t  i;
00308 
00309         for( i = 0; ( i + 1 ) < m_iSize; ++i )
00310             memset( m_aaData[ i ], 0, ( m_iSize - i - 1 ) * sizeof(*m_aaData[ i ]) ); }
00311 
00332     bool Save( std::ostream& ostm, bool fBinary, char cSeparator = '\t' ) const {
00333 
00334         return ( fBinary ? SaveBinary( ostm ) : SaveText( ostm, cSeparator ) ); }
00335 
00336 protected:
00337 
00355     bool SaveBinary( std::ostream& ostm ) const {
00356         size_t      i;
00357         uint32_t    iSize;
00358 
00359         iSize = (uint32_t)GetSize( );
00360         ostm.write( (const char*)&iSize, sizeof(iSize) );
00361         for( i = 0; i < GetSize( ); ++i )
00362             ostm.write( (const char*)Get( i ), (std::streamsize)( sizeof(*Get( i )) *
00363                 ( GetSize( ) - i - 1 ) ) );
00364 
00365         return true; }
00366 
00386     bool SaveText( std::ostream& ostm, char cSeparator ) const {
00387         size_t  i, j;
00388 
00389         if( !GetSize( ) )
00390             return false;
00391 
00392         for( i = 0; ( i + 1 ) < GetSize( ); ++i ) {
00393             for( j = 0; j <= i; ++j )
00394                 ostm << cSeparator;
00395             ostm << Get( i, j++ );
00396             for( ; j < GetSize( ); ++j )
00397                 ostm << cSeparator << Get( i, j );
00398             ostm << std::endl; }
00399 
00400         return true; }
00401 
00406     bool    m_fMemory;
00411     tType** m_aaData;
00412 };
00413 
00418 typedef CHalfMatrix<float>  CDistanceMatrix;
00419 
00427 class CBinaryMatrix : public CHalfMatrix<unsigned char> {
00428 public:
00449     bool Get( size_t iY, size_t iX ) const {
00450 
00451         if( iX == iY )
00452             return false;
00453         HalfIndex( iY, iX );
00454         return ( ( m_aaData[ iY ][ iX / 8 ] >> ( iX % 8 ) ) & 1 ); }
00455 
00476     void Set( size_t iY, size_t iX, bool fValue ) {
00477         unsigned char   c;
00478 
00479         if( iX == iY )
00480             return;
00481         HalfIndex( iY, iX );
00482         c = 1 << (unsigned char)( iX % 8 );
00483         m_aaData[ iY ][ iX / 8 ] = ( m_aaData[ iY ][ iX / 8 ] & ~c ) | ( fValue ? c : 0 ); }
00484 
00502     void Initialize( size_t iSize, bool fClear = false, unsigned char** aabData = NULL ) {
00503         size_t  i, iCount;
00504 
00505         Reset( );
00506         m_iSize = iSize;
00507         if( m_fMemory = !( m_aaData = aabData ) ) {
00508             m_aaData = new unsigned char*[ m_iSize - 1 ];
00509             for( i = 0; ( i + 1 ) < m_iSize; ++i ) {
00510                 m_aaData[ i ] = new unsigned char[ iCount = ( ( ( m_iSize - i - 1 ) / 8 ) + 1 ) ];
00511                 if( fClear )
00512                     memset( m_aaData[ i ], 0, iCount * sizeof(*m_aaData[ i ]) ); } } }
00513 };
00514 
00515 }
00516 
00517 #endif // HALFMATRIX_H