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 }