001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005package org.jblas; 006 007import org.jblas.exceptions.LapackConvergenceException; 008 009import static org.jblas.util.Functions.min; 010 011/** 012 * 013 */ 014public class Singular { 015 016 /** 017 * Compute a singular-value decomposition of A. 018 * 019 * @return A DoubleMatrix[3] array of U, S, V such that A = U * diag(S) * V' 020 */ 021 public static DoubleMatrix[] fullSVD(DoubleMatrix A) { 022 int m = A.rows; 023 int n = A.columns; 024 025 DoubleMatrix U = new DoubleMatrix(m, m); 026 DoubleMatrix S = new DoubleMatrix(min(m, n)); 027 DoubleMatrix V = new DoubleMatrix(n, n); 028 029 int info = NativeBlas.dgesvd('A', 'A', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, n); 030 031 if (info > 0) { 032 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 033 } 034 035 return new DoubleMatrix[]{U, S, V.transpose()}; 036 } 037 038 /** 039 * Compute a singular-value decomposition of A (sparse variant). 040 * Sparse means that the matrices U and V are not square but 041 * only have as many columns (or rows) as necessary. 042 * 043 * @param A 044 * @return A DoubleMatrix[3] array of U, S, V such that A = U * diag(S) * V' 045 */ 046 public static DoubleMatrix[] sparseSVD(DoubleMatrix A) { 047 int m = A.rows; 048 int n = A.columns; 049 050 DoubleMatrix U = new DoubleMatrix(m, min(m, n)); 051 DoubleMatrix S = new DoubleMatrix(min(m, n)); 052 DoubleMatrix V = new DoubleMatrix(min(m, n), n); 053 054 int info = NativeBlas.dgesvd('S', 'S', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, min(m, n)); 055 056 if (info > 0) { 057 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 058 } 059 060 return new DoubleMatrix[]{U, S, V.transpose()}; 061 } 062 063 /** 064 * Compute a singular-value decomposition of A (sparse variant). 065 * Sparse means that the matrices U and V are not square but only have 066 * as many columns (or rows) as necessary. 067 * 068 * @param A 069 * @return A ComplexDoubleMatrix[3] array of U, S, V such that A = U * diag(S) * V* 070 */ 071 public static ComplexDoubleMatrix[] sparseSVD(ComplexDoubleMatrix A) { 072 int m = A.rows; 073 int n = A.columns; 074 075 ComplexDoubleMatrix U = new ComplexDoubleMatrix(m, min(m, n)); 076 DoubleMatrix S = new DoubleMatrix(min(m, n)); 077 ComplexDoubleMatrix V = new ComplexDoubleMatrix(min(m, n), n); 078 079 double[] rwork = new double[5*min(m,n)]; 080 081 int info = 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); 082 083 if (info > 0) { 084 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 085 } 086 087 return new ComplexDoubleMatrix[]{U, new ComplexDoubleMatrix(S), V.hermitian()}; 088 } 089 090 /** 091 * Compute a singular-value decomposition of A. 092 * 093 * @return A ComplexDoubleMatrix[3] array of U, S, V such that A = U * diag(S) * V' 094 */ 095 public static ComplexDoubleMatrix[] fullSVD(ComplexDoubleMatrix A) { 096 int m = A.rows; 097 int n = A.columns; 098 099 ComplexDoubleMatrix U = new ComplexDoubleMatrix(m, m); 100 DoubleMatrix S = new DoubleMatrix(min(m, n)); 101 ComplexDoubleMatrix V = new ComplexDoubleMatrix(n, n); 102 103 double[] rwork = new double[5*min(m,n)]; 104 105 int info = NativeBlas.zgesvd('A', 'A', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, n, rwork, 0); 106 107 if (info > 0) { 108 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 109 } 110 111 return new ComplexDoubleMatrix[]{U, new ComplexDoubleMatrix(S), V.hermitian()}; 112 } 113 114 /** 115 * Compute the singular values of a matrix. 116 * 117 * @param A DoubleMatrix of dimension m * n 118 * @return A min(m, n) vector of singular values. 119 */ 120 public static DoubleMatrix SVDValues(DoubleMatrix A) { 121 int m = A.rows; 122 int n = A.columns; 123 DoubleMatrix S = new DoubleMatrix(min(m, n)); 124 125 int info = NativeBlas.dgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, 1); 126 127 if (info > 0) { 128 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 129 } 130 131 return S; 132 } 133 134 /** 135 * Compute the singular values of a complex matrix. 136 * 137 * @param A ComplexDoubleMatrix of dimension m * n 138 * @return A real-valued (!) min(m, n) vector of singular values. 139 */ 140 public static DoubleMatrix SVDValues(ComplexDoubleMatrix A) { 141 int m = A.rows; 142 int n = A.columns; 143 DoubleMatrix S = new DoubleMatrix(min(m, n)); 144 double[] rwork = new double[5*min(m,n)]; 145 146 int info = NativeBlas.zgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, min(m,n), rwork, 0); 147 148 if (info > 0) { 149 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 150 } 151 152 return S; 153 } 154 155 //BEGIN 156 // The code below has been automatically generated. 157 // DO NOT EDIT! 158 159 /** 160 * Compute a singular-value decomposition of A. 161 * 162 * @return A FloatMatrix[3] array of U, S, V such that A = U * diag(S) * V' 163 */ 164 public static FloatMatrix[] fullSVD(FloatMatrix A) { 165 int m = A.rows; 166 int n = A.columns; 167 168 FloatMatrix U = new FloatMatrix(m, m); 169 FloatMatrix S = new FloatMatrix(min(m, n)); 170 FloatMatrix V = new FloatMatrix(n, n); 171 172 int info = NativeBlas.sgesvd('A', 'A', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, n); 173 174 if (info > 0) { 175 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 176 } 177 178 return new FloatMatrix[]{U, S, V.transpose()}; 179 } 180 181 /** 182 * Compute a singular-value decomposition of A (sparse variant). 183 * Sparse means that the matrices U and V are not square but 184 * only have as many columns (or rows) as necessary. 185 * 186 * @param A 187 * @return A FloatMatrix[3] array of U, S, V such that A = U * diag(S) * V' 188 */ 189 public static FloatMatrix[] sparseSVD(FloatMatrix A) { 190 int m = A.rows; 191 int n = A.columns; 192 193 FloatMatrix U = new FloatMatrix(m, min(m, n)); 194 FloatMatrix S = new FloatMatrix(min(m, n)); 195 FloatMatrix V = new FloatMatrix(min(m, n), n); 196 197 int info = NativeBlas.sgesvd('S', 'S', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, min(m, n)); 198 199 if (info > 0) { 200 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 201 } 202 203 return new FloatMatrix[]{U, S, V.transpose()}; 204 } 205 206 /** 207 * Compute a singular-value decomposition of A (sparse variant). 208 * Sparse means that the matrices U and V are not square but only have 209 * as many columns (or rows) as necessary. 210 * 211 * @param A 212 * @return A ComplexFloatMatrix[3] array of U, S, V such that A = U * diag(S) * V* 213 */ 214 public static ComplexFloatMatrix[] sparseSVD(ComplexFloatMatrix A) { 215 int m = A.rows; 216 int n = A.columns; 217 218 ComplexFloatMatrix U = new ComplexFloatMatrix(m, min(m, n)); 219 FloatMatrix S = new FloatMatrix(min(m, n)); 220 ComplexFloatMatrix V = new ComplexFloatMatrix(min(m, n), n); 221 222 float[] rwork = new float[5*min(m,n)]; 223 224 int info = 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); 225 226 if (info > 0) { 227 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 228 } 229 230 return new ComplexFloatMatrix[]{U, new ComplexFloatMatrix(S), V.hermitian()}; 231 } 232 233 /** 234 * Compute a singular-value decomposition of A. 235 * 236 * @return A ComplexFloatMatrix[3] array of U, S, V such that A = U * diag(S) * V' 237 */ 238 public static ComplexFloatMatrix[] fullSVD(ComplexFloatMatrix A) { 239 int m = A.rows; 240 int n = A.columns; 241 242 ComplexFloatMatrix U = new ComplexFloatMatrix(m, m); 243 FloatMatrix S = new FloatMatrix(min(m, n)); 244 ComplexFloatMatrix V = new ComplexFloatMatrix(n, n); 245 246 float[] rwork = new float[5*min(m,n)]; 247 248 int info = NativeBlas.cgesvd('A', 'A', m, n, A.dup().data, 0, m, S.data, 0, U.data, 0, m, V.data, 0, n, rwork, 0); 249 250 if (info > 0) { 251 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 252 } 253 254 return new ComplexFloatMatrix[]{U, new ComplexFloatMatrix(S), V.hermitian()}; 255 } 256 257 /** 258 * Compute the singular values of a matrix. 259 * 260 * @param A FloatMatrix of dimension m * n 261 * @return A min(m, n) vector of singular values. 262 */ 263 public static FloatMatrix SVDValues(FloatMatrix A) { 264 int m = A.rows; 265 int n = A.columns; 266 FloatMatrix S = new FloatMatrix(min(m, n)); 267 268 int info = NativeBlas.sgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, 1); 269 270 if (info > 0) { 271 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 272 } 273 274 return S; 275 } 276 277 /** 278 * Compute the singular values of a complex matrix. 279 * 280 * @param A ComplexFloatMatrix of dimension m * n 281 * @return A real-valued (!) min(m, n) vector of singular values. 282 */ 283 public static FloatMatrix SVDValues(ComplexFloatMatrix A) { 284 int m = A.rows; 285 int n = A.columns; 286 FloatMatrix S = new FloatMatrix(min(m, n)); 287 float[] rwork = new float[5*min(m,n)]; 288 289 int info = NativeBlas.cgesvd('N', 'N', m, n, A.dup().data, 0, m, S.data, 0, null, 0, 1, null, 0, min(m,n), rwork, 0); 290 291 if (info > 0) { 292 throw new LapackConvergenceException("GESVD", info + " superdiagonals of an intermediate bidiagonal form failed to converge."); 293 } 294 295 return S; 296 } 297 298 //END 299}