001    /*
002     * To change this template, choose Tools | Templates
003     * and open the template in the editor.
004     */
005    package org.jblas;
006    
007    import static org.jblas.util.Functions.min;
008    
009    /**
010     *
011     */
012    public 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    }