1 /////////////////////////////////////////////////////////////////
4 // Sparse matrix computations
5 /////////////////////////////////////////////////////////////////
11 #include "SafeVector.h"
16 const float POSTERIOR_CUTOFF = 0.01; // minimum posterior probability
17 // value that is maintained in the
18 // sparse matrix representation
20 typedef pair<int,float> PIF; // Sparse matrix entry type
25 struct PIF2 { // Sparse matrix entry type
32 /////////////////////////////////////////////////////////////////
35 // Class for sparse matrix computations
36 /////////////////////////////////////////////////////////////////
40 int seq1Length, seq2Length; // dimensions of matrix
41 VI rowSize; // rowSize[i] = # of cells in row i
42 SafeVector<PIF> data; // data values
43 SafeVector<SafeVector<PIF>::iterator> rowPtrs; // pointers to the beginning of each row
46 SafeVector<PIF2> data2;
47 /////////////////////////////////////////////////////////////////
48 // SparseMatrix::SparseMatrix()
50 // Private constructor.1
51 /////////////////////////////////////////////////////////////////
54 /////////////////////////////////////////////////////////////////
55 // SparseMatrix::SparseMatrix()
57 // Constructor. Builds a sparse matrix from a posterior matrix.
58 // Note that the expected format for the posterior matrix is as
59 // a (seq1Length+1) x (seq2Length+1) matrix where the 0th row
60 // and 0th column are ignored (they should contain all zeroes).
61 /////////////////////////////////////////////////////////////////
63 SparseMatrix (int seq1Length, int seq2Length, const VF &posterior) :
64 seq1Length (seq1Length), seq2Length (seq2Length) {
68 assert (seq1Length > 0);
69 assert (seq2Length > 0);
71 // calculate memory required; count the number of cells in the
72 // posterior matrix above the threshold
73 VF::const_iterator postPtr = posterior.begin();
74 for (int i = 0; i <= seq1Length; i++){
75 for (int j = 0; j <= seq2Length; j++){
76 if (*(postPtr++) >= POSTERIOR_CUTOFF){
77 assert (i != 0 && j != 0);
84 data.resize(numCells);
85 rowSize.resize (seq1Length + 1); rowSize[0] = -1;
86 rowPtrs.resize (seq1Length + 1); rowPtrs[0] = data.end();
88 // build sparse matrix
89 postPtr = posterior.begin() + seq2Length + 1; // note that we're skipping the first row here
90 SafeVector<PIF>::iterator dataPtr = data.begin();
91 for (int i = 1; i <= seq1Length; i++){
92 postPtr++; // and skipping the first column of each row
94 for (int j = 1; j <= seq2Length; j++){
95 if (*postPtr >= POSTERIOR_CUTOFF){
97 dataPtr->second = *postPtr;
102 rowSize[i] = dataPtr - rowPtrs[i];
106 //////////////////////////////////////////////////////////////////////////
107 // SparseMatrix::SetSparseMatrix()
110 //////////////////////////////////////////////////////////////////////////
111 void SetSparseMatrix(int inseq1Length, int inseq2Length, const Trimat<float> &bppMat, float cutoff = 0.01) {
112 seq1Length = inseq1Length;
113 seq2Length = inseq2Length;
117 assert (seq1Length > 0);
118 assert (seq2Length > 0);
123 for (int i = 1; i <= seq1Length; i++) {
124 for (int j = i; j <= seq2Length; j++) {
125 if (bppMat.ref(i, j) >= cutoff ) {
132 data.resize(numCells);
133 for (int i = 0; i < numCells; i++) {
137 rowSize.resize (seq1Length + 1); rowSize[0] = -1;
138 rowPtrs.resize (seq1Length + 1); rowPtrs[0] = data.end();
140 SafeVector<PIF>::iterator dataPtr = data.begin();
141 for (int i = 1; i <= seq1Length; i++) {
142 rowPtrs[i] = dataPtr;
143 for (int j = i; j <= seq2Length; j++) {
144 if ( bppMat.ref(i, j) >= cutoff ) {
146 dataPtr->second = bppMat.ref(i, j);
150 rowSize[i] = dataPtr - rowPtrs[i];
154 for(int k = 1; k <= seq1Length; k++) {
155 for(int m = k, n = k; n <= k + 300 && m >= 1 && n <= seq2Length; m--, n++) {
156 if ((tmp = GetValue(m, n)) > 0) {
165 for(int m = k, n = k + 1; n <= k + 300 && m >= 1 && n <= seq2Length; m--, n++) {
166 if ((tmp = GetValue(m, n)) > 0) {
177 /////////////////////////////////////////////////////////////////
178 // SparseMatrix::GetRowPtr()
180 // Returns the pointer to a particular row in the sparse matrix.
181 /////////////////////////////////////////////////////////////////
183 SafeVector<PIF>::iterator GetRowPtr (int row) const {
184 assert (row >= 1 && row <= seq1Length);
188 /////////////////////////////////////////////////////////////////
189 // SparseMatrix::GetValue()
191 // Returns value at a particular row, column.
192 /////////////////////////////////////////////////////////////////
194 float GetValue (int row, int col){
195 assert (row >= 1 && row <= seq1Length);
196 assert (col >= 1 && col <= seq2Length);
197 for (int i = 0; i < rowSize[row]; i++){
198 if (rowPtrs[row][i].first == col) return rowPtrs[row][i].second;
203 void SetValue(int row, int col, float value) {
204 assert (row >= 1 && row <= seq1Length);
205 assert (col >= 1 && col <= seq2Length);
206 for (int i = 0; i < rowSize[row]; i++){
207 if (rowPtrs[row][i].first == col) rowPtrs[row][i].second = value;
211 /////////////////////////////////////////////////////////////////
212 // SparseMatrix::GetRowSize()
214 // Returns the number of entries in a particular row.
215 /////////////////////////////////////////////////////////////////
217 int GetRowSize (int row) const {
218 assert (row >= 1 && row <= seq1Length);
222 /////////////////////////////////////////////////////////////////
223 // SparseMatrix::GetSeq1Length()
225 // Returns the first dimension of the matrix.
226 /////////////////////////////////////////////////////////////////
228 int GetSeq1Length () const {
232 /////////////////////////////////////////////////////////////////
233 // SparseMatrix::GetSeq2Length()
235 // Returns the second dimension of the matrix.
236 /////////////////////////////////////////////////////////////////
238 int GetSeq2Length () const {
242 /////////////////////////////////////////////////////////////////
243 // SparseMatrix::GetRowPtr
245 // Returns the pointer to a particular row in the sparse matrix.
246 /////////////////////////////////////////////////////////////////
248 int GetNumCells () const {
252 /////////////////////////////////////////////////////////////////
253 // SparseMatrix::Print()
255 // Prints out a sparse matrix.
256 /////////////////////////////////////////////////////////////////
258 void Print (ostream &outfile) const {
259 outfile << "Sparse Matrix:" << endl;
260 for (int i = 1; i <= seq1Length; i++){
261 outfile << " " << i << ":";
262 for (int j = 0; j < rowSize[i]; j++){
263 outfile << " (" << rowPtrs[i][j].first << "," << rowPtrs[i][j].second << ")";
269 /////////////////////////////////////////////////////////////////
270 // SparseMatrix::ComputeTranspose()
272 // Returns a new sparse matrix containing the transpose of the
274 /////////////////////////////////////////////////////////////////
276 SparseMatrix *ComputeTranspose () const {
278 // create a new sparse matrix
279 SparseMatrix *ret = new SparseMatrix();
280 int numCells = data.size();
282 ret->seq1Length = seq2Length;
283 ret->seq2Length = seq1Length;
286 ret->data.resize (numCells);
287 ret->rowSize.resize (seq2Length + 1); ret->rowSize[0] = -1;
288 ret->rowPtrs.resize (seq2Length + 1); ret->rowPtrs[0] = ret->data.end();
291 for (int i = 1; i <= seq2Length; i++) ret->rowSize[i] = 0;
292 for (int i = 0; i < numCells; i++)
293 ret->rowSize[data[i].first]++;
296 for (int i = 1; i <= seq2Length; i++){
297 ret->rowPtrs[i] = (i == 1) ? ret->data.begin() : ret->rowPtrs[i-1] + ret->rowSize[i-1];
301 SafeVector<SafeVector<PIF>::iterator> currPtrs = ret->rowPtrs;
303 for (int i = 1; i <= seq1Length; i++){
304 SafeVector<PIF>::iterator row = rowPtrs[i];
305 for (int j = 0; j < rowSize[i]; j++){
306 currPtrs[row[j].first]->first = i;
307 currPtrs[row[j].first]->second = row[j].second;
308 currPtrs[row[j].first]++;
315 /////////////////////////////////////////////////////////////////
316 // SparseMatrix::GetPosterior()
318 // Return the posterior representation of the sparse matrix.
319 /////////////////////////////////////////////////////////////////
321 VF *GetPosterior () const {
323 // create a new posterior matrix
324 VF *posteriorPtr = new VF((seq1Length+1) * (seq2Length+1)); assert (posteriorPtr);
325 VF &posterior = *posteriorPtr;
327 // build the posterior matrix
328 for (int i = 0; i < (seq1Length+1) * (seq2Length+1); i++) posterior[i] = 0;
329 for (int i = 1; i <= seq1Length; i++){
330 VF::iterator postPtr = posterior.begin() + i * (seq2Length+1);
331 for (int j = 0; j < rowSize[i]; j++){
332 postPtr[rowPtrs[i][j].first] = rowPtrs[i][j].second;