/*
 * The baseCode project
 * 
 * Copyright (c) 2008 University of British Columbia
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package ubic.basecode.math;

import java.util.List;

import cern.colt.matrix.DoubleMatrix2D;
import cern.colt.matrix.impl.DenseDoubleMatrix2D;
import ubic.basecode.dataStructure.matrix.DenseDoubleMatrix;
import ubic.basecode.dataStructure.matrix.DoubleMatrix;

/**
 * SVD for DoubleMatrix.
 * 
 * @author paul
 * @version $Id$
 */
public class SingularValueDecomposition<R, C> {

    private cern.colt.matrix.linalg.SingularValueDecomposition svd;
    private List<C> columnNames;
    private List<R> rowNames;
    private DoubleMatrix<C, C> cMatrix;

    private DoubleMatrix<R, C> uMatrix;

    private DenseDoubleMatrix<R, C> vMatrix;

    /**
     * @param matrix
     */
    public SingularValueDecomposition( DoubleMatrix<R, C> matrix ) {
        double[][] mat = matrix.getRawMatrix();
        DoubleMatrix2D dm = new DenseDoubleMatrix2D( mat );
        this.rowNames = matrix.getRowNames();
        this.columnNames = matrix.getColNames();
        this.svd = new cern.colt.matrix.linalg.SingularValueDecomposition( dm );

        this.uMatrix = new DenseDoubleMatrix<R, C>( svd.getU().toArray() );
        uMatrix.setRowNames( this.rowNames );
        uMatrix.setColumnNames( this.columnNames ); // not really

        this.vMatrix = new DenseDoubleMatrix<R, C>( svd.getV().toArray() );
        vMatrix.setRowNames( this.rowNames );
        vMatrix.setColumnNames( this.columnNames );

        this.cMatrix = new DenseDoubleMatrix<C, C>( svd.getS().toArray() );
        cMatrix.setRowNames( this.columnNames ); // not really
        cMatrix.setColumnNames( this.columnNames );
    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#cond()
     */
    public double cond() {
        return svd.cond();
    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#getS()
     */
    public DoubleMatrix<C, C> getS() {
        return this.cMatrix;
    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#getSingularValues()
     */
    public double[] getSingularValues() {
        return svd.getSingularValues();
    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#getU()
     */
    public DoubleMatrix<R, C> getU() {
        return this.uMatrix;

    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#getV()
     */
    public DoubleMatrix<R, C> getV() {
        return this.vMatrix;
    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#norm2()
     */
    public double norm2() {
        return svd.norm2();
    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#rank()
     */
    public int rank() {
        return svd.rank();
    }

    /**
     * @return
     * @see cern.colt.matrix.linalg.SingularValueDecomposition#toString()
     */
    public String toString() {
        return svd.toString();
    }

}

@@ -674,16 +674,44 @@
 .math;%0A%0A
+import java.util.ArrayList;%0A
 import j
@@ -1180,24 +1180,25 @@
 %3E rowNames;%0A
+%0A
     private 
@@ -1214,15 +1214,27 @@
 rix%3C
-C, C%3E c
+Integer, Integer%3E s
 Matr
@@ -1266,17 +1266,23 @@
 trix%3CR, 
-C
+Integer
 %3E uMatri
@@ -1297,21 +1297,16 @@
 private 
-Dense
 DoubleMa
@@ -1306,25 +1306,31 @@
 oubleMatrix%3C
-R
+Integer
 , C%3E vMatrix
@@ -1719,24 +1719,190 @@
 ion( dm );%0A%0A
+        List%3CInteger%3E componentIds = new ArrayList%3CInteger%3E();%0A        for ( int i = 0; i %3C columnNames.size(); i++ ) %7B%0A            componentIds.add( i );%0A        %7D%0A%0A
         this
@@ -1929,33 +1929,39 @@
 DoubleMatrix%3CR, 
-C
+Integer
 %3E( svd.getU().to
@@ -2053,41 +2053,23 @@
 es( 
-this.columnNames ); // not really
+componentIds );
 %0A%0A  
@@ -2107,25 +2107,31 @@
 oubleMatrix%3C
-R
+Integer
 , C%3E( svd.ge
@@ -2173,36 +2173,35 @@
 etRowNames( 
-this.rowName
+componentId
 s );%0A       
@@ -2255,25 +2255,25 @@
        this.
-c
+s
 Matrix = new
@@ -2291,20 +2291,32 @@
 eMatrix%3C
-C, C
+Integer, Integer
 %3E( svd.g
@@ -2334,33 +2334,33 @@
 ay() );%0A        
-c
+s
 Matrix.setRowNam
@@ -2367,41 +2367,23 @@
 es( 
-this.columnNames ); // not really
+componentIds );
 %0A   
@@ -2387,17 +2387,17 @@
         
-c
+s
 Matrix.s
@@ -2407,39 +2407,35 @@
 olumnNames( 
-this.columnName
+componentId
 s );%0A    %7D%0A%0A
@@ -2725,12 +2725,24 @@
 rix%3C
-C, C
+Integer, Integer
 %3E ge
@@ -2768,17 +2768,17 @@
 rn this.
-c
+s
 Matrix;%0A
@@ -3111,25 +3111,31 @@
 leMatrix%3CR, 
-C
+Integer
 %3E getU() %7B%0A 
@@ -3291,25 +3291,31 @@
 oubleMatrix%3C
-R
+Integer
 , C%3E getV() 

integrate into LinkAnalysis CLI options bug 1350: SVD for Expression matrices http://www.bioinformatics.ubc.ca/pavlidis/lab/bugzilla/show_bug.cgi?id=1350