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 }