diff options
-rw-r--r-- | packages/base/src/Internal/C/lapack-aux.c | 49 | ||||
-rw-r--r-- | packages/base/src/Internal/LAPACK.hs | 47 |
2 files changed, 41 insertions, 55 deletions
diff --git a/packages/base/src/Internal/C/lapack-aux.c b/packages/base/src/Internal/C/lapack-aux.c index 80e5720..1018126 100644 --- a/packages/base/src/Internal/C/lapack-aux.c +++ b/packages/base/src/Internal/C/lapack-aux.c | |||
@@ -114,12 +114,12 @@ for(k=0; k<(M##r * M##c); k++) { \ | |||
114 | //////////////////////////////////////////////////////////////////////////////// | 114 | //////////////////////////////////////////////////////////////////////////////// |
115 | //////////////////// real svd /////////////////////////////////////////////////// | 115 | //////////////////// real svd /////////////////////////////////////////////////// |
116 | 116 | ||
117 | /* Subroutine */ int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n, | 117 | int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n, |
118 | doublereal *a, integer *lda, doublereal *s, doublereal *u, integer * | 118 | doublereal *a, integer *lda, doublereal *s, doublereal *u, integer * |
119 | ldu, doublereal *vt, integer *ldvt, doublereal *work, integer *lwork, | 119 | ldu, doublereal *vt, integer *ldvt, doublereal *work, integer *lwork, |
120 | integer *info); | 120 | integer *info); |
121 | 121 | ||
122 | int svd_l_R(KODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { | 122 | int svd_l_R(ODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { |
123 | integer m = ar; | 123 | integer m = ar; |
124 | integer n = ac; | 124 | integer n = ac; |
125 | integer q = MIN(m,n); | 125 | integer q = MIN(m,n); |
@@ -145,15 +145,12 @@ int svd_l_R(KODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { | |||
145 | } | 145 | } |
146 | } | 146 | } |
147 | DEBUGMSG("svd_l_R"); | 147 | DEBUGMSG("svd_l_R"); |
148 | double *B = (double*)malloc(m*n*sizeof(double)); | ||
149 | CHECK(!B,MEM); | ||
150 | memcpy(B,ap,m*n*sizeof(double)); | ||
151 | integer lwork = -1; | 148 | integer lwork = -1; |
152 | integer res; | 149 | integer res; |
153 | // ask for optimal lwork | 150 | // ask for optimal lwork |
154 | double ans; | 151 | double ans; |
155 | dgesvd_ (jobu,jobvt, | 152 | dgesvd_ (jobu,jobvt, |
156 | &m,&n,B,&m, | 153 | &m,&n,ap,&m, |
157 | sp, | 154 | sp, |
158 | up,&m, | 155 | up,&m, |
159 | vp,&ldvt, | 156 | vp,&ldvt, |
@@ -163,7 +160,7 @@ int svd_l_R(KODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { | |||
163 | double * work = (double*)malloc(lwork*sizeof(double)); | 160 | double * work = (double*)malloc(lwork*sizeof(double)); |
164 | CHECK(!work,MEM); | 161 | CHECK(!work,MEM); |
165 | dgesvd_ (jobu,jobvt, | 162 | dgesvd_ (jobu,jobvt, |
166 | &m,&n,B,&m, | 163 | &m,&n,ap,&m, |
167 | sp, | 164 | sp, |
168 | up,&m, | 165 | up,&m, |
169 | vp,&ldvt, | 166 | vp,&ldvt, |
@@ -171,18 +168,17 @@ int svd_l_R(KODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { | |||
171 | &res); | 168 | &res); |
172 | CHECK(res,res); | 169 | CHECK(res,res); |
173 | free(work); | 170 | free(work); |
174 | free(B); | ||
175 | OK | 171 | OK |
176 | } | 172 | } |
177 | 173 | ||
178 | // (alternative version) | 174 | // (alternative version) |
179 | 175 | ||
180 | /* Subroutine */ int dgesdd_(char *jobz, integer *m, integer *n, doublereal * | 176 | int dgesdd_(char *jobz, integer *m, integer *n, doublereal * |
181 | a, integer *lda, doublereal *s, doublereal *u, integer *ldu, | 177 | a, integer *lda, doublereal *s, doublereal *u, integer *ldu, |
182 | doublereal *vt, integer *ldvt, doublereal *work, integer *lwork, | 178 | doublereal *vt, integer *ldvt, doublereal *work, integer *lwork, |
183 | integer *iwork, integer *info); | 179 | integer *iwork, integer *info); |
184 | 180 | ||
185 | int svd_l_Rdd(KODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { | 181 | int svd_l_Rdd(ODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { |
186 | integer m = ar; | 182 | integer m = ar; |
187 | integer n = ac; | 183 | integer n = ac; |
188 | integer q = MIN(m,n); | 184 | integer q = MIN(m,n); |
@@ -202,37 +198,31 @@ int svd_l_Rdd(KODMAT(a),ODMAT(u), DVEC(s),ODMAT(v)) { | |||
202 | } | 198 | } |
203 | } | 199 | } |
204 | DEBUGMSG("svd_l_Rdd"); | 200 | DEBUGMSG("svd_l_Rdd"); |
205 | double *B = (double*)malloc(m*n*sizeof(double)); | ||
206 | CHECK(!B,MEM); | ||
207 | memcpy(B,ap,m*n*sizeof(double)); | ||
208 | integer* iwk = (integer*) malloc(8*q*sizeof(integer)); | 201 | integer* iwk = (integer*) malloc(8*q*sizeof(integer)); |
209 | CHECK(!iwk,MEM); | 202 | CHECK(!iwk,MEM); |
210 | integer lwk = -1; | 203 | integer lwk = -1; |
211 | integer res; | 204 | integer res; |
212 | // ask for optimal lwk | 205 | // ask for optimal lwk |
213 | double ans; | 206 | double ans; |
214 | dgesdd_ (jobz,&m,&n,B,&m,sp,up,&m,vp,&ldvt,&ans,&lwk,iwk,&res); | 207 | dgesdd_ (jobz,&m,&n,ap,&m,sp,up,&m,vp,&ldvt,&ans,&lwk,iwk,&res); |
215 | lwk = ans; | 208 | lwk = ans; |
216 | double * workv = (double*)malloc(lwk*sizeof(double)); | 209 | double * workv = (double*)malloc(lwk*sizeof(double)); |
217 | CHECK(!workv,MEM); | 210 | CHECK(!workv,MEM); |
218 | dgesdd_ (jobz,&m,&n,B,&m,sp,up,&m,vp,&ldvt,workv,&lwk,iwk,&res); | 211 | dgesdd_ (jobz,&m,&n,ap,&m,sp,up,&m,vp,&ldvt,workv,&lwk,iwk,&res); |
219 | CHECK(res,res); | 212 | CHECK(res,res); |
220 | free(iwk); | 213 | free(iwk); |
221 | free(workv); | 214 | free(workv); |
222 | free(B); | ||
223 | OK | 215 | OK |
224 | } | 216 | } |
225 | 217 | ||
226 | //////////////////// complex svd //////////////////////////////////// | 218 | //////////////////// complex svd //////////////////////////////////// |
227 | 219 | ||
228 | // not in clapack.h | ||
229 | |||
230 | int zgesvd_(char *jobu, char *jobvt, integer *m, integer *n, | 220 | int zgesvd_(char *jobu, char *jobvt, integer *m, integer *n, |
231 | doublecomplex *a, integer *lda, doublereal *s, doublecomplex *u, | 221 | doublecomplex *a, integer *lda, doublereal *s, doublecomplex *u, |
232 | integer *ldu, doublecomplex *vt, integer *ldvt, doublecomplex *work, | 222 | integer *ldu, doublecomplex *vt, integer *ldvt, doublecomplex *work, |
233 | integer *lwork, doublereal *rwork, integer *info); | 223 | integer *lwork, doublereal *rwork, integer *info); |
234 | 224 | ||
235 | int svd_l_C(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | 225 | int svd_l_C(OCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { |
236 | integer m = ar; | 226 | integer m = ar; |
237 | integer n = ac; | 227 | integer n = ac; |
238 | integer q = MIN(m,n); | 228 | integer q = MIN(m,n); |
@@ -257,10 +247,7 @@ int svd_l_C(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | |||
257 | ldvt = q; | 247 | ldvt = q; |
258 | } | 248 | } |
259 | }DEBUGMSG("svd_l_C"); | 249 | }DEBUGMSG("svd_l_C"); |
260 | doublecomplex *B = (doublecomplex*)malloc(m*n*sizeof(doublecomplex)); | 250 | |
261 | CHECK(!B,MEM); | ||
262 | memcpy(B,ap,m*n*sizeof(doublecomplex)); | ||
263 | |||
264 | double *rwork = (double*) malloc(5*q*sizeof(double)); | 251 | double *rwork = (double*) malloc(5*q*sizeof(double)); |
265 | CHECK(!rwork,MEM); | 252 | CHECK(!rwork,MEM); |
266 | integer lwork = -1; | 253 | integer lwork = -1; |
@@ -268,7 +255,7 @@ int svd_l_C(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | |||
268 | // ask for optimal lwork | 255 | // ask for optimal lwork |
269 | doublecomplex ans; | 256 | doublecomplex ans; |
270 | zgesvd_ (jobu,jobvt, | 257 | zgesvd_ (jobu,jobvt, |
271 | &m,&n,B,&m, | 258 | &m,&n,ap,&m, |
272 | sp, | 259 | sp, |
273 | up,&m, | 260 | up,&m, |
274 | vp,&ldvt, | 261 | vp,&ldvt, |
@@ -279,7 +266,7 @@ int svd_l_C(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | |||
279 | doublecomplex * work = (doublecomplex*)malloc(lwork*sizeof(doublecomplex)); | 266 | doublecomplex * work = (doublecomplex*)malloc(lwork*sizeof(doublecomplex)); |
280 | CHECK(!work,MEM); | 267 | CHECK(!work,MEM); |
281 | zgesvd_ (jobu,jobvt, | 268 | zgesvd_ (jobu,jobvt, |
282 | &m,&n,B,&m, | 269 | &m,&n,ap,&m, |
283 | sp, | 270 | sp, |
284 | up,&m, | 271 | up,&m, |
285 | vp,&ldvt, | 272 | vp,&ldvt, |
@@ -289,7 +276,6 @@ int svd_l_C(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | |||
289 | CHECK(res,res); | 276 | CHECK(res,res); |
290 | free(work); | 277 | free(work); |
291 | free(rwork); | 278 | free(rwork); |
292 | free(B); | ||
293 | OK | 279 | OK |
294 | } | 280 | } |
295 | 281 | ||
@@ -298,8 +284,7 @@ int zgesdd_ (char *jobz, integer *m, integer *n, | |||
298 | integer *ldu, doublecomplex *vt, integer *ldvt, doublecomplex *work, | 284 | integer *ldu, doublecomplex *vt, integer *ldvt, doublecomplex *work, |
299 | integer *lwork, doublereal *rwork, integer* iwork, integer *info); | 285 | integer *lwork, doublereal *rwork, integer* iwork, integer *info); |
300 | 286 | ||
301 | int svd_l_Cdd(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | 287 | int svd_l_Cdd(OCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { |
302 | //printf("entro\n"); | ||
303 | integer m = ar; | 288 | integer m = ar; |
304 | integer n = ac; | 289 | integer n = ac; |
305 | integer q = MIN(m,n); | 290 | integer q = MIN(m,n); |
@@ -319,9 +304,6 @@ int svd_l_Cdd(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | |||
319 | } | 304 | } |
320 | } | 305 | } |
321 | DEBUGMSG("svd_l_Cdd"); | 306 | DEBUGMSG("svd_l_Cdd"); |
322 | doublecomplex *B = (doublecomplex*)malloc(m*n*sizeof(doublecomplex)); | ||
323 | CHECK(!B,MEM); | ||
324 | memcpy(B,ap,m*n*sizeof(doublecomplex)); | ||
325 | integer* iwk = (integer*) malloc(8*q*sizeof(integer)); | 307 | integer* iwk = (integer*) malloc(8*q*sizeof(integer)); |
326 | CHECK(!iwk,MEM); | 308 | CHECK(!iwk,MEM); |
327 | int lrwk; | 309 | int lrwk; |
@@ -337,18 +319,17 @@ int svd_l_Cdd(KOCMAT(a),OCMAT(u), DVEC(s),OCMAT(v)) { | |||
337 | integer res; | 319 | integer res; |
338 | // ask for optimal lwk | 320 | // ask for optimal lwk |
339 | doublecomplex ans; | 321 | doublecomplex ans; |
340 | zgesdd_ (jobz,&m,&n,B,&m,sp,up,&m,vp,&ldvt,&ans,&lwk,rwk,iwk,&res); | 322 | zgesdd_ (jobz,&m,&n,ap,&m,sp,up,&m,vp,&ldvt,&ans,&lwk,rwk,iwk,&res); |
341 | lwk = ans.r; | 323 | lwk = ans.r; |
342 | //printf("lwk = %ld\n",lwk); | 324 | //printf("lwk = %ld\n",lwk); |
343 | doublecomplex * workv = (doublecomplex*)malloc(lwk*sizeof(doublecomplex)); | 325 | doublecomplex * workv = (doublecomplex*)malloc(lwk*sizeof(doublecomplex)); |
344 | CHECK(!workv,MEM); | 326 | CHECK(!workv,MEM); |
345 | zgesdd_ (jobz,&m,&n,B,&m,sp,up,&m,vp,&ldvt,workv,&lwk,rwk,iwk,&res); | 327 | zgesdd_ (jobz,&m,&n,ap,&m,sp,up,&m,vp,&ldvt,workv,&lwk,rwk,iwk,&res); |
346 | //printf("res = %ld\n",res); | 328 | //printf("res = %ld\n",res); |
347 | CHECK(res,res); | 329 | CHECK(res,res); |
348 | free(workv); // printf("freed workv\n"); | 330 | free(workv); // printf("freed workv\n"); |
349 | free(rwk); // printf("freed rwk\n"); | 331 | free(rwk); // printf("freed rwk\n"); |
350 | free(iwk); // printf("freed iwk\n"); | 332 | free(iwk); // printf("freed iwk\n"); |
351 | free(B); // printf("freed B, salgo\n"); | ||
352 | OK | 333 | OK |
353 | } | 334 | } |
354 | 335 | ||
diff --git a/packages/base/src/Internal/LAPACK.hs b/packages/base/src/Internal/LAPACK.hs index 124e353..c91cddd 100644 --- a/packages/base/src/Internal/LAPACK.hs +++ b/packages/base/src/Internal/LAPACK.hs | |||
@@ -102,25 +102,26 @@ foreign import ccall unsafe "svd_l_Cdd" zgesdd :: TSVD C | |||
102 | 102 | ||
103 | -- | Full SVD of a real matrix using LAPACK's /dgesvd/. | 103 | -- | Full SVD of a real matrix using LAPACK's /dgesvd/. |
104 | svdR :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) | 104 | svdR :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) |
105 | svdR = svdAux dgesvd "svdR" . fmat | 105 | svdR = svdAux dgesvd "svdR" |
106 | 106 | ||
107 | -- | Full SVD of a real matrix using LAPACK's /dgesdd/. | 107 | -- | Full SVD of a real matrix using LAPACK's /dgesdd/. |
108 | svdRd :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) | 108 | svdRd :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) |
109 | svdRd = svdAux dgesdd "svdRdd" . fmat | 109 | svdRd = svdAux dgesdd "svdRdd" |
110 | 110 | ||
111 | -- | Full SVD of a complex matrix using LAPACK's /zgesvd/. | 111 | -- | Full SVD of a complex matrix using LAPACK's /zgesvd/. |
112 | svdC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) | 112 | svdC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) |
113 | svdC = svdAux zgesvd "svdC" . fmat | 113 | svdC = svdAux zgesvd "svdC" |
114 | 114 | ||
115 | -- | Full SVD of a complex matrix using LAPACK's /zgesdd/. | 115 | -- | Full SVD of a complex matrix using LAPACK's /zgesdd/. |
116 | svdCd :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) | 116 | svdCd :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) |
117 | svdCd = svdAux zgesdd "svdCdd" . fmat | 117 | svdCd = svdAux zgesdd "svdCdd" |
118 | 118 | ||
119 | svdAux f st x = unsafePerformIO $ do | 119 | svdAux f st x = unsafePerformIO $ do |
120 | a <- copy ColumnMajor x | ||
120 | u <- createMatrix ColumnMajor r r | 121 | u <- createMatrix ColumnMajor r r |
121 | s <- createVector (min r c) | 122 | s <- createVector (min r c) |
122 | v <- createMatrix ColumnMajor c c | 123 | v <- createMatrix ColumnMajor c c |
123 | f # x # u # s # v #| st | 124 | f # a # u # s # v #| st |
124 | return (u,s,v) | 125 | return (u,s,v) |
125 | where | 126 | where |
126 | r = rows x | 127 | r = rows x |
@@ -129,25 +130,26 @@ svdAux f st x = unsafePerformIO $ do | |||
129 | 130 | ||
130 | -- | Thin SVD of a real matrix, using LAPACK's /dgesvd/ with jobu == jobvt == \'S\'. | 131 | -- | Thin SVD of a real matrix, using LAPACK's /dgesvd/ with jobu == jobvt == \'S\'. |
131 | thinSVDR :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) | 132 | thinSVDR :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) |
132 | thinSVDR = thinSVDAux dgesvd "thinSVDR" . fmat | 133 | thinSVDR = thinSVDAux dgesvd "thinSVDR" |
133 | 134 | ||
134 | -- | Thin SVD of a complex matrix, using LAPACK's /zgesvd/ with jobu == jobvt == \'S\'. | 135 | -- | Thin SVD of a complex matrix, using LAPACK's /zgesvd/ with jobu == jobvt == \'S\'. |
135 | thinSVDC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) | 136 | thinSVDC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) |
136 | thinSVDC = thinSVDAux zgesvd "thinSVDC" . fmat | 137 | thinSVDC = thinSVDAux zgesvd "thinSVDC" |
137 | 138 | ||
138 | -- | Thin SVD of a real matrix, using LAPACK's /dgesdd/ with jobz == \'S\'. | 139 | -- | Thin SVD of a real matrix, using LAPACK's /dgesdd/ with jobz == \'S\'. |
139 | thinSVDRd :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) | 140 | thinSVDRd :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) |
140 | thinSVDRd = thinSVDAux dgesdd "thinSVDRdd" . fmat | 141 | thinSVDRd = thinSVDAux dgesdd "thinSVDRdd" |
141 | 142 | ||
142 | -- | Thin SVD of a complex matrix, using LAPACK's /zgesdd/ with jobz == \'S\'. | 143 | -- | Thin SVD of a complex matrix, using LAPACK's /zgesdd/ with jobz == \'S\'. |
143 | thinSVDCd :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) | 144 | thinSVDCd :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double)) |
144 | thinSVDCd = thinSVDAux zgesdd "thinSVDCdd" . fmat | 145 | thinSVDCd = thinSVDAux zgesdd "thinSVDCdd" |
145 | 146 | ||
146 | thinSVDAux f st x = unsafePerformIO $ do | 147 | thinSVDAux f st x = unsafePerformIO $ do |
148 | a <- copy ColumnMajor x | ||
147 | u <- createMatrix ColumnMajor r q | 149 | u <- createMatrix ColumnMajor r q |
148 | s <- createVector q | 150 | s <- createVector q |
149 | v <- createMatrix ColumnMajor q c | 151 | v <- createMatrix ColumnMajor q c |
150 | f # x # u # s # v #| st | 152 | f # a # u # s # v #| st |
151 | return (u,s,v) | 153 | return (u,s,v) |
152 | where | 154 | where |
153 | r = rows x | 155 | r = rows x |
@@ -157,23 +159,24 @@ thinSVDAux f st x = unsafePerformIO $ do | |||
157 | 159 | ||
158 | -- | Singular values of a real matrix, using LAPACK's /dgesvd/ with jobu == jobvt == \'N\'. | 160 | -- | Singular values of a real matrix, using LAPACK's /dgesvd/ with jobu == jobvt == \'N\'. |
159 | svR :: Matrix Double -> Vector Double | 161 | svR :: Matrix Double -> Vector Double |
160 | svR = svAux dgesvd "svR" . fmat | 162 | svR = svAux dgesvd "svR" |
161 | 163 | ||
162 | -- | Singular values of a complex matrix, using LAPACK's /zgesvd/ with jobu == jobvt == \'N\'. | 164 | -- | Singular values of a complex matrix, using LAPACK's /zgesvd/ with jobu == jobvt == \'N\'. |
163 | svC :: Matrix (Complex Double) -> Vector Double | 165 | svC :: Matrix (Complex Double) -> Vector Double |
164 | svC = svAux zgesvd "svC" . fmat | 166 | svC = svAux zgesvd "svC" |
165 | 167 | ||
166 | -- | Singular values of a real matrix, using LAPACK's /dgesdd/ with jobz == \'N\'. | 168 | -- | Singular values of a real matrix, using LAPACK's /dgesdd/ with jobz == \'N\'. |
167 | svRd :: Matrix Double -> Vector Double | 169 | svRd :: Matrix Double -> Vector Double |
168 | svRd = svAux dgesdd "svRd" . fmat | 170 | svRd = svAux dgesdd "svRd" |
169 | 171 | ||
170 | -- | Singular values of a complex matrix, using LAPACK's /zgesdd/ with jobz == \'N\'. | 172 | -- | Singular values of a complex matrix, using LAPACK's /zgesdd/ with jobz == \'N\'. |
171 | svCd :: Matrix (Complex Double) -> Vector Double | 173 | svCd :: Matrix (Complex Double) -> Vector Double |
172 | svCd = svAux zgesdd "svCd" . fmat | 174 | svCd = svAux zgesdd "svCd" |
173 | 175 | ||
174 | svAux f st x = unsafePerformIO $ do | 176 | svAux f st x = unsafePerformIO $ do |
177 | a <- copy ColumnMajor x | ||
175 | s <- createVector q | 178 | s <- createVector q |
176 | g # x # s #| st | 179 | g # a # s #| st |
177 | return s | 180 | return s |
178 | where | 181 | where |
179 | r = rows x | 182 | r = rows x |
@@ -184,16 +187,17 @@ svAux f st x = unsafePerformIO $ do | |||
184 | 187 | ||
185 | -- | Singular values and all right singular vectors of a real matrix, using LAPACK's /dgesvd/ with jobu == \'N\' and jobvt == \'A\'. | 188 | -- | Singular values and all right singular vectors of a real matrix, using LAPACK's /dgesvd/ with jobu == \'N\' and jobvt == \'A\'. |
186 | rightSVR :: Matrix Double -> (Vector Double, Matrix Double) | 189 | rightSVR :: Matrix Double -> (Vector Double, Matrix Double) |
187 | rightSVR = rightSVAux dgesvd "rightSVR" . fmat | 190 | rightSVR = rightSVAux dgesvd "rightSVR" |
188 | 191 | ||
189 | -- | Singular values and all right singular vectors of a complex matrix, using LAPACK's /zgesvd/ with jobu == \'N\' and jobvt == \'A\'. | 192 | -- | Singular values and all right singular vectors of a complex matrix, using LAPACK's /zgesvd/ with jobu == \'N\' and jobvt == \'A\'. |
190 | rightSVC :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double)) | 193 | rightSVC :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double)) |
191 | rightSVC = rightSVAux zgesvd "rightSVC" . fmat | 194 | rightSVC = rightSVAux zgesvd "rightSVC" |
192 | 195 | ||
193 | rightSVAux f st x = unsafePerformIO $ do | 196 | rightSVAux f st x = unsafePerformIO $ do |
197 | a <- copy ColumnMajor x | ||
194 | s <- createVector q | 198 | s <- createVector q |
195 | v <- createMatrix ColumnMajor c c | 199 | v <- createMatrix ColumnMajor c c |
196 | g # x # s # v #| st | 200 | g # a # s # v #| st |
197 | return (s,v) | 201 | return (s,v) |
198 | where | 202 | where |
199 | r = rows x | 203 | r = rows x |
@@ -204,16 +208,17 @@ rightSVAux f st x = unsafePerformIO $ do | |||
204 | 208 | ||
205 | -- | Singular values and all left singular vectors of a real matrix, using LAPACK's /dgesvd/ with jobu == \'A\' and jobvt == \'N\'. | 209 | -- | Singular values and all left singular vectors of a real matrix, using LAPACK's /dgesvd/ with jobu == \'A\' and jobvt == \'N\'. |
206 | leftSVR :: Matrix Double -> (Matrix Double, Vector Double) | 210 | leftSVR :: Matrix Double -> (Matrix Double, Vector Double) |
207 | leftSVR = leftSVAux dgesvd "leftSVR" . fmat | 211 | leftSVR = leftSVAux dgesvd "leftSVR" |
208 | 212 | ||
209 | -- | Singular values and all left singular vectors of a complex matrix, using LAPACK's /zgesvd/ with jobu == \'A\' and jobvt == \'N\'. | 213 | -- | Singular values and all left singular vectors of a complex matrix, using LAPACK's /zgesvd/ with jobu == \'A\' and jobvt == \'N\'. |
210 | leftSVC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double) | 214 | leftSVC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double) |
211 | leftSVC = leftSVAux zgesvd "leftSVC" . fmat | 215 | leftSVC = leftSVAux zgesvd "leftSVC" |
212 | 216 | ||
213 | leftSVAux f st x = unsafePerformIO $ do | 217 | leftSVAux f st x = unsafePerformIO $ do |
218 | a <- copy ColumnMajor x | ||
214 | u <- createMatrix ColumnMajor r r | 219 | u <- createMatrix ColumnMajor r r |
215 | s <- createVector q | 220 | s <- createVector q |
216 | g # x # u # s #| st | 221 | g # a # u # s #| st |
217 | return (u,s) | 222 | return (u,s) |
218 | where | 223 | where |
219 | r = rows x | 224 | r = rows x |