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 COMPACTMATRIXI_H 00023 #define COMPACTMATRIXI_H 00024 00025 //may need to enable the following lines for Cygwin compilation 00026 //#ifndef SIZE_MAX 00027 //#define SIZE_MAX (4294967295U) //assumes 32bit GCC 00028 //#endif 00029 00030 #include "halfmatrixi.h" 00031 00032 namespace Sleipnir { 00033 00034 class CCompactMatrixBase { 00035 protected: 00036 CCompactMatrixBase( ) : m_cBits(0), m_aiData(NULL), m_fMemory(true) { } 00037 00038 ~CCompactMatrixBase( ) { 00039 00040 if( m_fMemory && m_aiData ) 00041 delete[] m_aiData; } 00042 00043 void Initialize( unsigned char, bool ); 00044 00045 unsigned char Get( size_t iX, size_t iY ) const { 00046 size_t* pi; 00047 unsigned char cRet, cShift; 00048 00049 if( !( m_cBits && m_aiData ) ) 00050 return 0; 00051 pi = GetWord( iX, iY, cShift ); 00052 // Bits starting at Shift, mask m_cBits long 00053 cRet = (unsigned char)( ( *pi >> cShift ) & ( SIZE_MAX >> ( ( 8 * sizeof(*m_aiData) ) - m_cBits ) ) ); 00054 // If we overflow a boundary... 00055 if( ( cShift + m_cBits ) > ( 8 * sizeof(*m_aiData) ) ) 00056 // Bits starting at 0, mask (m_cBits-Shift) long, shift left by bits we got 00057 cRet |= ( *( pi + 1 ) & ( SIZE_MAX >> ( ( 16 * sizeof(*m_aiData) ) - m_cBits - 00058 cShift ) ) ) << ( ( 8 * sizeof(*m_aiData) ) - cShift ); 00059 00060 return cRet; 00061 } 00062 00063 void Set( size_t iX, size_t iY, unsigned char cValue ) { 00064 unsigned char cShift; 00065 size_t iMask; 00066 size_t* pi; 00067 00068 if( !( m_cBits && m_aiData ) ) 00069 return; 00070 pi = GetWord( iX, iY, cShift ); 00071 iMask = ( SIZE_MAX >> ( ( 8 * sizeof(*m_aiData) ) - m_cBits ) ) << cShift; 00072 *pi = ( *pi & ~iMask ) | ( ( (size_t)cValue << cShift ) & iMask ); 00073 if( ( cShift + m_cBits ) > ( 8 * sizeof(*m_aiData) ) ) { 00074 pi++; 00075 iMask = SIZE_MAX >> ( ( 16 * sizeof(*m_aiData) ) - m_cBits - cShift ); 00076 *pi = ( *pi & ~iMask ) | 00077 ( ( cValue >> ( ( 8 * sizeof(*m_aiData) ) - cShift ) ) & iMask ); 00078 } 00079 } 00080 00081 virtual size_t CountWords( ) const = 0; 00082 virtual size_t* GetWord( size_t, size_t, unsigned char& ) const = 0; 00083 00084 bool m_fMemory; 00085 unsigned char m_cBits; 00086 size_t* m_aiData; 00087 }; 00088 00089 class CCompactMatrixImpl : protected CHalfMatrixBase, protected CCompactMatrixBase { 00090 protected: 00091 CCompactMatrixImpl( ) : m_iSize(0) { } 00092 00093 size_t* GetWord( size_t iX, size_t iY, unsigned char& cShift ) const { 00094 size_t iIndex; 00095 00096 // Closed form for sum(m_iSize - i - 1, i=0..(iX-1)) + iY 00097 iIndex = ( iX * ( m_iSize - 1 ) ) - ( iX * ( iX - 1 ) / 2 ) + iY; 00098 iIndex *= m_cBits; 00099 cShift = (unsigned char)( iIndex % ( 8 * sizeof(*m_aiData) ) ); 00100 iIndex /= 8 * sizeof(*m_aiData); 00101 00102 return &m_aiData[ iIndex ]; } 00103 00104 size_t CountWords( ) const { 00105 size_t iRet; 00106 00107 return ( ( m_cBits && ( iRet = m_iSize * ( m_iSize - 1 ) / 2 ) ) ? 00108 ( ( ( ( iRet * m_cBits ) - 1 ) / ( 8 * sizeof(*m_aiData) ) ) + 1 ) : 0 ); } 00109 00110 uint32_t m_iSize; 00111 }; 00112 00113 class CCompactFullMatrixImpl : protected CCompactMatrixBase { 00114 protected: 00115 CCompactFullMatrixImpl( ) : m_iRows(0), m_iColumns(0) { } 00116 00117 size_t CountWords( ) const { 00118 size_t iRet; 00119 iRet = m_iRows * m_iColumns; 00120 return ( ( ( ( iRet * m_cBits ) - 1 ) / ( 8 * sizeof(*m_aiData) ) ) + 1 ); 00121 } 00122 00123 size_t* GetWord( size_t iY, size_t iX, unsigned char& cShift ) const { 00124 size_t iIndex; 00125 00126 iIndex = ( ( iY * m_iColumns ) + iX ) * m_cBits; 00127 cShift = (unsigned char)( iIndex % ( 8 * sizeof(*m_aiData) ) ); 00128 iIndex /= 8 * sizeof(*m_aiData); 00129 00130 return &m_aiData[ iIndex ]; } 00131 00132 uint32_t m_iRows; 00133 uint32_t m_iColumns; 00134 }; 00135 00136 } 00137 00138 #endif // COMPACTMATRIXI_H