View Javadoc
1   /*
2    * The baseCode project
3    * 
4    * Copyright (c) 2006 University of British Columbia
5    * 
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *       http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   *
18   */
19  package ubic.basecode.dataStructure.matrix;
20  
21  import java.util.List;
22  
23  import cern.colt.list.DoubleArrayList;
24  import cern.colt.matrix.DoubleMatrix1D;
25  
26  /**
27   * Dense 2D matrix implementation designed for very fast access of entire rows.
28   * <p>
29   * Implementation note: The key difference between this and the DenseDouble2DMatrixNamed is that this delegates to a
30   * DoubleArrayList[], while DenseDouble2DMatrixNamed delegates to a DenseDoubleMatrix2D.
31   * 
32   * @author pavlidis
33   * 
34   */
35  public class FastRowAccessDoubleMatrix<R, C> extends DoubleMatrix<R, C> {
36  
37      private static final long serialVersionUID = -5458302072944941517L;
38      private DoubleArrayList[] data;
39  
40      /**
41       * Implementation note: The input matrix is NOT COPIED (due to the way colt DoubleArrayList(double[]) is
42       * implemented).F
43       * 
44       * @param t
45       */
46      public FastRowAccessDoubleMatrix( double[][] t ) {
47          super();
48          data = new DoubleArrayList[t.length];
49          for ( int i = 0; i < t.length; i++ ) {
50              data[i] = new DoubleArrayList( t[i] );
51          }
52      }
53  
54      /**
55       * @param rows
56       * @param cols
57       */
58      public FastRowAccessDoubleMatrix( int rows, int cols ) {
59          super();
60          data = new DoubleArrayList[rows];
61          for ( int i = 0; i < rows; i++ ) {
62              data[i] = new DoubleArrayList( new double[cols] );
63          }
64      }
65  
66      /**
67       * @return double[][]
68       */
69      @Override
70      public double[][] asArray() {
71          double[][] result = new double[rows()][];
72          for ( int i = 0; i < rows(); i++ ) {
73              result[i] = getRow( i );
74          }
75          return result;
76      }
77  
78      /*
79       * (non-Javadoc)
80       * 
81       * @see basecode.dataStructure.matrix.DoubleMatrixNamed#columns()
82       */
83  
84      @Override
85      public int columns() {
86          assert data[0] != null;
87          return data[0].size();
88      }
89  
90      /*
91       * (non-Javadoc)
92       * 
93       * @see ubic.basecode.dataStructure.matrix.DoubleMatrixNamed#copy()
94       */
95      @Override
96      public DoubleMatrix<R, C> copy() {
97          DoubleMatrix<R, C> returnval = new FastRowAccessDoubleMatrix<R, C>( this.rows(), this.columns() );
98  
99          for ( int i = 0; i < this.rows(); i++ ) {
100             returnval.setRowName( this.getRowName( i ), i );
101             for ( int j = 0; j < this.columns(); j++ ) {
102                 if ( i == 0 ) {
103                     returnval.setColumnName( this.getColName( j ), j );
104                 }
105                 returnval.set( i, j, this.get( i, j ) );
106             }
107         }
108         return returnval;
109 
110     }
111 
112     @Override
113     public double get( int x, int y ) {
114         assert data[x] != null;
115         return data[x].get( y );
116     }
117 
118     @Override
119     public Double[] getColObj( int col ) {
120         Double[] result = new Double[rows()];
121         for ( int i = 0; i < rows(); i++ ) {
122             result[i] = new Double( get( i, col ) );
123         }
124         return result;
125     }
126 
127     @Override
128     public DoubleMatrix<R, C> getColRange( int startCol, int endCol ) {
129         super.checkColRange( startCol, endCol );
130 
131         DoubleMatrix<R, C> returnval = new FastRowAccessDoubleMatrix<R, C>( this.rows(), 1 + endCol - startCol );
132         int k = 0;
133         for ( int i = startCol; i <= endCol; i++ ) {
134             C colName = this.getColName( i );
135             if ( colName != null ) {
136                 returnval.setColumnName( colName, i );
137             }
138             for ( int j = 0, m = this.rows(); j < m; j++ ) {
139                 if ( i == startCol ) {
140                     R rowName = this.getRowName( j );
141                     returnval.setRowName( rowName, j );
142                 }
143                 returnval.set( j, k, this.get( j, i ) );
144             }
145             k++;
146         }
147         return returnval;
148     }
149 
150     /*
151      * (non-Javadoc)
152      * 
153      * @see basecode.dataStructure.matrix.DoubleMatrixNamed#getColumn(int)
154      */
155     @Override
156     public double[] getColumn( int col ) {
157         double[] result = new double[rows()];
158         for ( int i = 0; i < rows(); i++ ) {
159             result[i] = get( i, col );
160         }
161         return result;
162     }
163 
164     /*
165      * (non-Javadoc)
166      * 
167      * @see basecode.dataStructure.matrix.DoubleMatrixNamed#getRow(int)
168      */
169 
170     @Override
171     public Double getObject( int row, int col ) {
172         return new Double( get( row, col ) );
173     }
174 
175     @Override
176     public double[] getRow( int i ) {
177         return data[i].elements();
178     }
179 
180     /*
181      * (non-Javadoc)
182      * 
183      * @see basecode.dataStructure.matrix.DoubleMatrixNamed#getRowArrayList(int)
184      */
185     @Override
186     public DoubleArrayList getRowArrayList( int i ) {
187         return data[i];
188     }
189 
190     @Override
191     public Double[] getRowObj( int row ) {
192         Double[] result = new Double[columns()];
193         for ( int i = 0; i < columns(); i++ ) {
194             result[i] = new Double( get( row, i ) );
195         }
196         return result;
197     }
198 
199     /*
200      * (non-Javadoc)
201      * 
202      * @see ubic.basecode.dataStructure.matrix.Matrix2D#getRowRange(int, int)
203      */
204     @Override
205     public DoubleMatrix<R, C> getRowRange( int startRow, int endRow ) {
206         super.checkRowRange( startRow, endRow );
207 
208         DoubleMatrix<R, C> returnval = new FastRowAccessDoubleMatrix<R, C>( endRow + 1 - startRow, this.columns() );
209         int k = 0;
210         for ( int i = startRow; i <= endRow; i++ ) {
211             R rowName = this.getRowName( i );
212             if ( rowName != null ) {
213                 returnval.setRowName( rowName, i );
214             }
215             for ( int j = 0, m = this.columns(); j < m; j++ ) {
216                 if ( i == 0 ) {
217                     C colName = this.getColName( j );
218                     returnval.setColumnName( colName, j );
219                 }
220                 double value = this.get( i, j );
221                 assert k < returnval.rows();
222                 assert j < returnval.columns();
223                 returnval.set( k, j, value );
224 
225             }
226             k++;
227         }
228         return returnval;
229     }
230 
231     @Override
232     public boolean isMissing( int i, int j ) {
233         return Double.isNaN( get( i, j ) );
234     }
235 
236     @Override
237     public int rows() {
238         return data.length;
239     }
240 
241     @Override
242     public void set( int x, int y, Double value ) {
243         assert data != null;
244         assert data[x] != null;
245         assert value != null;
246         assert y >= 0 && y < data[x].size();
247         data[x].set( y, value );
248     }
249 
250     @Override
251     public int size() {
252         return this.data.length * this.data[0].size();
253     }
254 
255     /*
256      * (non-Javadoc)
257      * 
258      * @see ubic.basecode.dataStructure.matrix.DoubleMatrix#subsetColumns(java.util.List)
259      */
260     @Override
261     public DoubleMatrix<R, C> subsetColumns( List<C> columns ) {
262 
263         DoubleMatrix<R, C> returnval = new DenseDoubleMatrix<R, C>( this.rows(), columns.size() );
264         returnval.setRowNames( this.getRowNames() );
265         for ( int i = 0; i < this.rows(); i++ ) {
266             int currentColumn = 0;
267             for ( C c : columns ) {
268                 int j = this.getColIndexByName( c );
269 
270                 returnval.set( i, currentColumn, this.get( i, j ) );
271 
272                 if ( i == 0 ) {
273                     returnval.setColumnName( c, currentColumn );
274                 }
275 
276                 currentColumn++;
277 
278             }
279 
280         }
281         return returnval;
282     }
283 
284     /*
285      * (non-Javadoc)
286      * 
287      * @see ubic.basecode.dataStructure.matrix.DoubleMatrix#subsetRows(java.util.Collection)
288      */
289     @Override
290     public DoubleMatrix<R, C> subsetRows( List<R> rowNames ) {
291         DoubleMatrix<R, C> returnval = new FastRowAccessDoubleMatrix<R, C>( rowNames.size(), this.columns() );
292 
293         int currentRow = 0;
294         for ( R rowName : rowNames ) {
295 
296             if ( !this.containsRowName( rowName ) ) continue;
297 
298             int i = this.getRowIndexByName( rowName );
299             returnval.setRowName( rowName, currentRow );
300             for ( int j = 0; j < this.columns(); j++ ) {
301                 if ( currentRow == 0 ) {
302                     returnval.setColumnName( this.getColName( j ), j );
303                 }
304                 returnval.set( currentRow, j, this.get( i, j ) );
305             }
306             currentRow++;
307         }
308 
309         if ( !returnval.getRowNames().containsAll( rowNames ) ) {
310             throw new IllegalArgumentException( "Invalid rows to select, some are not in the original matrix" );
311         }
312 
313         return returnval;
314     }
315 
316     @Override
317     public DoubleMatrix<C, R> transpose() {
318 
319         DoubleMatrix<C, R> result = new DenseDoubleMatrix<C, R>( this.columns(), this.rows() );
320         result.setRowNames( this.getColNames() );
321         result.setColumnNames( this.getRowNames() );
322 
323         for ( int i = 0; i < this.rows(); i++ ) {
324             for ( int j = 0; j < this.columns(); j++ ) {
325                 result.set( j, i, this.get( i, j ) );
326             }
327         }
328 
329         return result;
330 
331     }
332 
333     @Override
334     public DoubleMatrix1D viewColumn( int column ) {
335         return new DenseDoubleMatrix1D( this.getColumn( column ) );
336     }
337 
338     /*
339      * (non-Javadoc)
340      * 
341      * @see basecode.dataStructure.matrix.DoubleMatrixNamed#viewRow(int)
342      */
343     @Override
344     public DoubleMatrix1D viewRow( int j ) {
345         return new DenseDoubleMatrix1D( data[j].elements() );
346     }
347 }