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  import cern.colt.matrix.DoubleMatrix2D;
26  import cern.colt.matrix.impl.AbstractMatrix2D;
27  import cern.colt.matrix.impl.DenseDoubleMatrix2D;
28  
29  /**
30   * A dense matrix of doubles that knows about row and column names.
31   * 
32   * @author Paul Pavlidis
33   * 
34   */
35  public class DenseDoubleMatrix<R, C> extends DoubleMatrix<R, C> {
36  
37      private static final long serialVersionUID = -239226762166912931L;
38      private DoubleMatrix2D matrix;
39  
40      /**
41       * @param T double[][]
42       */
43      public DenseDoubleMatrix( double T[][] ) {
44          super();
45          matrix = new DenseDoubleMatrix2D( T );
46      }
47  
48      /**
49       * @param rows int
50       * @param cols int
51       */
52      public DenseDoubleMatrix( int rows, int cols ) {
53          super();
54          matrix = new DenseDoubleMatrix2D( rows, cols );
55      }
56  
57      /**
58       * @return double[][]
59       */
60      @Override
61      public double[][] asArray() {
62          return matrix.toArray();
63      }
64  
65      @Override
66      public int columns() {
67          return matrix.columns();
68      }
69  
70      /**
71       * @return basecode.dataStructure.DenseDoubleMatrix2DNamed
72       */
73      @Override
74      public DoubleMatrix<R, C> copy() {
75          DoubleMatrix<R, C> returnval = new DenseDoubleMatrix<R, C>( this.rows(), this.columns() );
76          for ( int i = 0, n = this.rows(); i < n; i++ ) {
77              R rowName = this.getRowName( i );
78              // Fine, if you don't want row names
79              if ( rowName != null )
80                  returnval.setRowName( rowName, i );
81              for ( int j = 0, m = this.columns(); j < m; j++ ) {
82                  if ( i == 0 ) {
83                      C colName = this.getColName( j );
84                      if ( colName != null )
85                          returnval.setColumnName( colName, j );
86                  }
87                  returnval.set( i, j, this.get( i, j ) );
88              }
89          }
90          return returnval;
91      }
92  
93      /**
94       * @param row int
95       * @param column int
96       * @return
97       * @see DoubleMatrix2D#get(int, int)
98       */
99      @Override
100     public double get( int row, int column ) {
101         return matrix.getQuick( row, column );
102     }
103 
104     /**
105      * Return a copy of a given column.
106      * 
107      * @param col int
108      * @return double[]
109      */
110     public double[] getColByName( C s ) {
111         int col = getColIndexByName( s );
112         double[] result = new double[rows()];
113         for ( int i = 0; i < rows(); i++ ) {
114             result[i] = get( i, col );
115         }
116         return result;
117     }
118 
119     @Override
120     public Double[] getColObj( int col ) {
121         Double[] result = new Double[rows()];
122         for ( int i = 0; i < rows(); i++ ) {
123             result[i] = new Double( get( i, col ) );
124         }
125         return result;
126     }
127 
128     @Override
129     public DoubleMatrix<R, C> getColRange( int startCol, int endCol ) {
130         super.checkColRange( startCol, endCol );
131 
132         DoubleMatrix<R, C> returnval = new DenseDoubleMatrix<R, C>( this.rows(), 1 + endCol - startCol );
133         int k = 0;
134         for ( int i = startCol; i <= endCol; i++ ) {
135             C colName = this.getColName( i );
136             if ( colName != null ) {
137                 returnval.addColumnName( colName );
138             }
139             for ( int j = 0, m = this.rows(); j < m; j++ ) {
140                 if ( i == startCol ) {
141                     R rowName = this.getRowName( j );
142                     if ( rowName != null ) returnval.addRowName( rowName );
143                 }
144                 returnval.set( j, k, this.get( j, i ) );
145             }
146             k++;
147         }
148         return returnval;
149     }
150 
151     /*
152      * (non-Javadoc)
153      * 
154      * @see basecode.dataStructure.matrix.DoubleMatrixNamed#getColumn(int)
155      */
156     @Override
157     public double[] getColumn( int col ) {
158         double[] result = new double[rows()];
159         for ( int i = 0; i < rows(); i++ ) {
160             result[i] = get( i, col );
161         }
162         return result;
163     }
164 
165     /**
166      * Converts to a String that can be read by read.table in R, using default parameters
167      * 
168      * @return java.lang.String
169      */
170     /*
171      * public String toRReadTableString() { Format nf = new Format( "%.4g" ); StringBuffer result = new StringBuffer(
172      * this.rows() * this.columns() ); if ( this.hasColNames() ) { for ( int i = 0; i < this.columns(); i++ ) {
173      * result.append( "\"" + this.getColName( i ) +"\" "); System.out.println("\"" + this.getColName( i ) +"\" "); }
174      * result.append( "\n" ); } for ( int i = 0; i < this.rows(); i++ ) { if ( this.hasRowNames() ) { result.append("\""
175      * + this.getRowName( i ) + "\"" ); } for ( int j = 0; j < this.columns(); j++ ) { if ( Double.isNaN( this.get( i, j
176      * ) ) ) { result.append( " NA" ); } else { result.append( " " + nf.format( this.get( i, j ) ) ); } } result.append(
177      * "\n" ); } return result.toString(); }
178      */
179 
180     @Override
181     public Double getObject( int row, int col ) {
182         return new Double( get( row, col ) );
183     }
184 
185     /**
186      * Return a reference to a specific row.
187      * 
188      * @param row int
189      * @return double[]
190      */
191     @Override
192     public double[] getRow( int row ) {
193         return viewRow( row ).toArray();
194     }
195 
196     /*
197      * (non-Javadoc)
198      * 
199      * @see basecode.dataStructure.matrix.AbstractNamedDoubleMatrix#getRowArrayList(int)
200      */
201     @Override
202     public DoubleArrayList getRowArrayList( int i ) {
203         return new DoubleArrayList( getRow( i ) );
204     }
205 
206     /**
207      * Return a reference to a specific row.
208      * 
209      * @param s String
210      * @return double[]
211      */
212     @Override
213     public double[] getRowByName( R s ) {
214         return getRow( getRowIndexByName( s ) );
215     }
216 
217     @Override
218     public Double[] getRowObj( int row ) {
219         Double[] result = new Double[columns()];
220         for ( int i = 0; i < columns(); i++ ) {
221             result[i] = new Double( get( row, i ) );
222         }
223         return result;
224     }
225 
226     /*
227      * (non-Javadoc)
228      * 
229      * @see ubic.basecode.dataStructure.matrix.Matrix2D#getRowRange(int, int)
230      */
231     @Override
232     public DoubleMatrix<R, C> getRowRange( int startRow, int endRow ) {
233         super.checkRowRange( startRow, endRow );
234 
235         DoubleMatrix<R, C> returnval = new DenseDoubleMatrix<R, C>( 1 + endRow - startRow, this.columns() );
236         int k = 0;
237         for ( int i = startRow; i <= endRow; i++ ) {
238             R rowName = this.getRowName( i );
239             if ( rowName != null ) {
240                 returnval.setRowName( rowName, i );
241             }
242             for ( int j = 0, m = this.columns(); j < m; j++ ) {
243                 if ( i == startRow ) {
244                     C colName = this.getColName( j );
245                     returnval.setColumnName( colName, j );
246                 }
247                 returnval.set( k, j, this.get( i, j ) );
248             }
249             k++;
250         }
251         return returnval;
252     }
253 
254     @Override
255     public boolean isMissing( int i, int j ) {
256         return Double.isNaN( get( i, j ) );
257     }
258 
259     @Override
260     public int rows() {
261         return matrix.rows();
262     }
263 
264     @Override
265     public void set( int row, int column, Double value ) {
266         matrix.set( row, column, value );
267     }
268 
269     /**
270      * @return int
271      * @see AbstractMatrix2D#size()
272      */
273     @Override
274     public int size() {
275         return matrix.size();
276     }
277 
278     /*
279      * (non-Javadoc)
280      * 
281      * @see ubic.basecode.dataStructure.matrix.DoubleMatrix#subsetColumns(java.util.List)
282      */
283     @Override
284     public DoubleMatrix<R, C> subsetColumns( List<C> columns ) {
285 
286         DoubleMatrix<R, C> returnval = new DenseDoubleMatrix<R, C>( this.rows(), columns.size() );
287         returnval.setRowNames( this.getRowNames() );
288         for ( int i = 0; i < this.rows(); i++ ) {
289             int currentColumn = 0;
290             for ( C c : columns ) {
291                 int j = this.getColIndexByName( c );
292 
293                 returnval.set( i, currentColumn, this.get( i, j ) );
294 
295                 if ( i == 0 ) {
296                     returnval.setColumnName( c, currentColumn );
297                 }
298 
299                 currentColumn++;
300 
301             }
302 
303         }
304         return returnval;
305     }
306 
307     @Override
308     public DoubleMatrix<R, C> subsetRows( List<R> rowNames ) {
309 
310         DoubleMatrix<R, C> returnval = new DenseDoubleMatrix<R, C>( rowNames.size(), this.columns() );
311 
312         int currentRow = 0;
313         for ( R rowName : rowNames ) {
314 
315             if ( !this.containsRowName( rowName ) ) continue;
316 
317             int i = this.getRowIndexByName( rowName );
318 
319             returnval.setRowName( rowName, currentRow );
320             for ( int j = 0, m = this.columns(); j < m; j++ ) {
321                 if ( currentRow == 0 ) {
322                     C colName = this.getColName( j );
323                     returnval.setColumnName( colName, j );
324                 }
325                 returnval.set( currentRow, j, this.get( i, j ) );
326             }
327             currentRow++;
328         }
329 
330         if ( !returnval.getRowNames().containsAll( rowNames ) ) {
331             throw new IllegalArgumentException( "Invalid rows to select, some are not in the original matrix" );
332         }
333 
334         return returnval;
335 
336     }
337 
338     @Override
339     public DoubleMatrix<C, R> transpose() {
340 
341         DoubleMatrix<C, R> result = new DenseDoubleMatrix<C, R>( this.columns(), this.rows() );
342         if ( this.getColNames().size() > 0 ) {
343             result.setRowNames( this.getColNames() );
344         }
345         if ( this.getRowNames().size() > 0 ) {
346             result.setColumnNames( this.getRowNames() );
347         }
348 
349         for ( int i = 0; i < this.rows(); i++ ) {
350             for ( int j = 0; j < this.columns(); j++ ) {
351                 result.set( j, i, this.get( i, j ) );
352             }
353         }
354 
355         return result;
356 
357     }
358 
359     /**
360      * @param column int
361      * @return cern.colt.matrix.DoubleMatrix1D
362      */
363     @Override
364     public DoubleMatrix1D viewColumn( int column ) {
365         return matrix.viewColumn( column );
366     }
367 
368     /**
369      * @param row int
370      * @return DoubleMatrix1D
371      * @see DenseDoubleMatrix#viewRow(int)
372      */
373     @Override
374     public DoubleMatrix1D viewRow( int row ) {
375         return matrix.viewRow( row );
376     }
377 
378 }