Sleipnir
|
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