001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005package org.jblas;
006
007import static org.jblas.util.Functions.min;
008
009/**
010 *
011 */
012public class Singular {
013
014    /**
015     * Compute a singular-value decomposition of A.
016     *
017     * @return A DoubleMatrix[3] array of U, S, V such that A = U * diag(S) * V'
018     */
019    public static DoubleMatrix[] fullSVD(DoubleMatrix A) {
020        int m = A.rows;
021        int n = A.columns;
022
023        DoubleMatrix U = new DoubleMatrix(m, m);
024        DoubleMatrix S = new DoubleMatrix(min(m, n));
025        DoubleMatrix V = new DoubleMatrix(n, n);
026
027        NativeBlas.dgesvd('A', 'A', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, n);
028
029        return new DoubleMatrix[]{U, S, V.transpose()};
030    }
031
032    /**
033     * Compute a singular-value decomposition of A (sparse variant).
034     * Sparse means that the matrices U and V are not square but
035     * only have as many columns (or rows) as possible.
036     * 
037     * @param A
038     * @return A DoubleMatrix[3] array of U, S, V such that A = U * diag(S) * V'
039     */
040    public static DoubleMatrix[] sparseSVD(DoubleMatrix A) {
041        int m = A.rows;
042        int n = A.columns;
043
044        DoubleMatrix U = new DoubleMatrix(m, min(m, n));
045        DoubleMatrix S = new DoubleMatrix(min(m, n));
046        DoubleMatrix V = new DoubleMatrix(min(m, n), n);
047
048        NativeBlas.dgesvd('S', 'S', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, min(m, n));
049
050        return new DoubleMatrix[]{U, S, V.transpose()};
051    }
052
053    public static ComplexDoubleMatrix[] sparseSVD(ComplexDoubleMatrix A) {
054        int m = A.rows;
055        int n = A.columns;
056
057        ComplexDoubleMatrix U = new ComplexDoubleMatrix(m, min(m, n));
058        DoubleMatrix S = new DoubleMatrix(min(m, n));
059        ComplexDoubleMatrix V = new ComplexDoubleMatrix(min(m, n), n);
060
061        double[] rwork = new double[5*min(m,n)];
062
063        NativeBlas.zgesvd('S', 'S', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, min(m, n), rwork, 0);
064
065        return new ComplexDoubleMatrix[]{U, new ComplexDoubleMatrix(S), V.transpose()};
066    }
067
068    /**
069     * Compute the singular values of a matrix.
070     *
071     * @param A DoubleMatrix of dimension m * n
072     * @return A min(m, n) vector of singular values.
073     */
074    public static DoubleMatrix SVDValues(DoubleMatrix A) {
075        int m = A.rows;
076        int n = A.columns;
077        DoubleMatrix S = new DoubleMatrix(min(m, n));
078
079        NativeBlas.dgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, 1);
080
081        return S;
082    }
083
084    /**
085     * Compute the singular values of a complex matrix.
086     *
087     * @param A ComplexDoubleMatrix of dimension m * n
088     * @return A real-valued (!) min(m, n) vector of singular values.
089     */
090    public static DoubleMatrix SVDValues(ComplexDoubleMatrix A) {
091        int m = A.rows;
092        int n = A.columns;
093        DoubleMatrix S = new DoubleMatrix(min(m, n));
094        double[] rwork = new double[5*min(m,n)];
095
096        NativeBlas.zgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, min(m,n), rwork, 0);
097
098        return S;
099    }
100
101    //BEGIN
102  // The code below has been automatically generated.
103  // DO NOT EDIT!
104
105    /**
106     * Compute a singular-value decomposition of A.
107     *
108     * @return A FloatMatrix[3] array of U, S, V such that A = U * diag(S) * V'
109     */
110    public static FloatMatrix[] fullSVD(FloatMatrix A) {
111        int m = A.rows;
112        int n = A.columns;
113
114        FloatMatrix U = new FloatMatrix(m, m);
115        FloatMatrix S = new FloatMatrix(min(m, n));
116        FloatMatrix V = new FloatMatrix(n, n);
117
118        NativeBlas.sgesvd('A', 'A', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, n);
119
120        return new FloatMatrix[]{U, S, V.transpose()};
121    }
122
123    /**
124     * Compute a singular-value decomposition of A (sparse variant).
125     * Sparse means that the matrices U and V are not square but
126     * only have as many columns (or rows) as possible.
127     * 
128     * @param A
129     * @return A FloatMatrix[3] array of U, S, V such that A = U * diag(S) * V'
130     */
131    public static FloatMatrix[] sparseSVD(FloatMatrix A) {
132        int m = A.rows;
133        int n = A.columns;
134
135        FloatMatrix U = new FloatMatrix(m, min(m, n));
136        FloatMatrix S = new FloatMatrix(min(m, n));
137        FloatMatrix V = new FloatMatrix(min(m, n), n);
138
139        NativeBlas.sgesvd('S', 'S', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, min(m, n));
140
141        return new FloatMatrix[]{U, S, V.transpose()};
142    }
143
144    public static ComplexFloatMatrix[] sparseSVD(ComplexFloatMatrix A) {
145        int m = A.rows;
146        int n = A.columns;
147
148        ComplexFloatMatrix U = new ComplexFloatMatrix(m, min(m, n));
149        FloatMatrix S = new FloatMatrix(min(m, n));
150        ComplexFloatMatrix V = new ComplexFloatMatrix(min(m, n), n);
151
152        float[] rwork = new float[5*min(m,n)];
153
154        NativeBlas.cgesvd('S', 'S', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, min(m, n), rwork, 0);
155
156        return new ComplexFloatMatrix[]{U, new ComplexFloatMatrix(S), V.transpose()};
157    }
158
159    /**
160     * Compute the singular values of a matrix.
161     *
162     * @param A FloatMatrix of dimension m * n
163     * @return A min(m, n) vector of singular values.
164     */
165    public static FloatMatrix SVDValues(FloatMatrix A) {
166        int m = A.rows;
167        int n = A.columns;
168        FloatMatrix S = new FloatMatrix(min(m, n));
169
170        NativeBlas.sgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, 1);
171
172        return S;
173    }
174
175    /**
176     * Compute the singular values of a complex matrix.
177     *
178     * @param A ComplexFloatMatrix of dimension m * n
179     * @return A real-valued (!) min(m, n) vector of singular values.
180     */
181    public static FloatMatrix SVDValues(ComplexFloatMatrix A) {
182        int m = A.rows;
183        int n = A.columns;
184        FloatMatrix S = new FloatMatrix(min(m, n));
185        float[] rwork = new float[5*min(m,n)];
186
187        NativeBlas.cgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, min(m,n), rwork, 0);
188
189        return S;
190    }
191
192    //END
193}