summaryrefslogtreecommitdiff
path: root/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2009-12-28 15:47:26 +0000
committerAlberto Ruiz <aruiz@um.es>2009-12-28 15:47:26 +0000
commitb2715e91d7aef5cee1b64b641b8f173167a7145a (patch)
treef97b82cfa435441f52153ccdfad5e1fa119f14dc /lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
parent107478b2288b0904159599be94089230c7cd3edf (diff)
additional svd functions
Diffstat (limited to 'lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c')
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c159
1 files changed, 129 insertions, 30 deletions
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
index f18bbed..db94cc6 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
+++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
@@ -48,7 +48,27 @@ int svd_l_R(KDMAT(a),DMAT(u), DVEC(s),DMAT(v)) {
48 integer m = ar; 48 integer m = ar;
49 integer n = ac; 49 integer n = ac;
50 integer q = MIN(m,n); 50 integer q = MIN(m,n);
51 REQUIRES(ur==m && uc==m && sn==q && vr==n && vc==n,BAD_SIZE); 51 REQUIRES(sn==q,BAD_SIZE);
52 REQUIRES(up==NULL || ur==m && (uc==m || uc==q),BAD_SIZE);
53 char* jobu = "A";
54 if (up==NULL) {
55 jobu = "N";
56 } else {
57 if (uc==q) {
58 jobu = "S";
59 }
60 }
61 REQUIRES(vp==NULL || vc==n && (vr==n || vr==q),BAD_SIZE);
62 char* jobvt = "A";
63 integer ldvt = n;
64 if (vp==NULL) {
65 jobvt = "N";
66 } else {
67 if (vr==q) {
68 jobvt = "S";
69 ldvt = q;
70 }
71 }
52 DEBUGMSG("svd_l_R"); 72 DEBUGMSG("svd_l_R");
53 double *B = (double*)malloc(m*n*sizeof(double)); 73 double *B = (double*)malloc(m*n*sizeof(double));
54 CHECK(!B,MEM); 74 CHECK(!B,MEM);
@@ -57,25 +77,21 @@ int svd_l_R(KDMAT(a),DMAT(u), DVEC(s),DMAT(v)) {
57 integer res; 77 integer res;
58 // ask for optimal lwork 78 // ask for optimal lwork
59 double ans; 79 double ans;
60 //printf("ask zgesvd\n"); 80 dgesvd_ (jobu,jobvt,
61 char* job = "A";
62 dgesvd_ (job,job,
63 &m,&n,B,&m, 81 &m,&n,B,&m,
64 sp, 82 sp,
65 up,&m, 83 up,&m,
66 vp,&n, 84 vp,&ldvt,
67 &ans, &lwork, 85 &ans, &lwork,
68 &res); 86 &res);
69 lwork = ceil(ans); 87 lwork = ceil(ans);
70 //printf("ans = %d\n",lwork);
71 double * work = (double*)malloc(lwork*sizeof(double)); 88 double * work = (double*)malloc(lwork*sizeof(double));
72 CHECK(!work,MEM); 89 CHECK(!work,MEM);
73 //printf("dgesdd\n"); 90 dgesvd_ (jobu,jobvt,
74 dgesvd_ (job,job,
75 &m,&n,B,&m, 91 &m,&n,B,&m,
76 sp, 92 sp,
77 up,&m, 93 up,&m,
78 vp,&n, 94 vp,&ldvt,
79 work, &lwork, 95 work, &lwork,
80 &res); 96 &res);
81 CHECK(res,res); 97 CHECK(res,res);
@@ -90,25 +106,36 @@ int svd_l_Rdd(KDMAT(a),DMAT(u), DVEC(s),DMAT(v)) {
90 integer m = ar; 106 integer m = ar;
91 integer n = ac; 107 integer n = ac;
92 integer q = MIN(m,n); 108 integer q = MIN(m,n);
93 REQUIRES(ur==m && uc==m && sn==q && vr==n && vc==n,BAD_SIZE); 109 REQUIRES(sn==q,BAD_SIZE);
110 REQUIRES(up == NULL && vp == NULL
111 || ur==m && vc==n
112 && (uc == q && vr == q
113 || uc == m && vc==n),BAD_SIZE);
114 char* jobz = "A";
115 integer ldvt = n;
116 if (up==NULL) {
117 jobz = "N";
118 } else {
119 if (uc==q && vr == q) {
120 jobz = "S";
121 ldvt = q;
122 }
123 }
94 DEBUGMSG("svd_l_Rdd"); 124 DEBUGMSG("svd_l_Rdd");
95 double *B = (double*)malloc(m*n*sizeof(double)); 125 double *B = (double*)malloc(m*n*sizeof(double));
96 CHECK(!B,MEM); 126 CHECK(!B,MEM);
97 memcpy(B,ap,m*n*sizeof(double)); 127 memcpy(B,ap,m*n*sizeof(double));
98 integer* iwk = (integer*) malloc(8*q*sizeof(int)); 128 integer* iwk = (integer*) malloc(8*q*sizeof(integer));
99 CHECK(!iwk,MEM); 129 CHECK(!iwk,MEM);
100 integer lwk = -1; 130 integer lwk = -1;
101 integer res; 131 integer res;
102 // ask for optimal lwk 132 // ask for optimal lwk
103 double ans; 133 double ans;
104 //printf("ask dgesdd\n"); 134 dgesdd_ (jobz,&m,&n,B,&m,sp,up,&m,vp,&ldvt,&ans,&lwk,iwk,&res);
105 dgesdd_ ("A",&m,&n,B,&m,sp,up,&m,vp,&n,&ans,&lwk,iwk,&res); 135 lwk = ans;
106 lwk = 2*ceil(ans); // ????? otherwise 50x100 rejects lwk
107 //printf("lwk = %d\n",lwk);
108 double * workv = (double*)malloc(lwk*sizeof(double)); 136 double * workv = (double*)malloc(lwk*sizeof(double));
109 CHECK(!workv,MEM); 137 CHECK(!workv,MEM);
110 //printf("dgesdd\n"); 138 dgesdd_ (jobz,&m,&n,B,&m,sp,up,&m,vp,&ldvt,workv,&lwk,iwk,&res);
111 dgesdd_ ("A",&m,&n,B,&m,sp,up,&m,vp,&n,workv,&lwk,iwk,&res);
112 CHECK(res,res); 139 CHECK(res,res);
113 free(iwk); 140 free(iwk);
114 free(workv); 141 free(workv);
@@ -120,17 +147,36 @@ int svd_l_Rdd(KDMAT(a),DMAT(u), DVEC(s),DMAT(v)) {
120 147
121// not in clapack.h 148// not in clapack.h
122 149
123int zgesvd_(char *jobu, char *jobvt, integer *m, integer *n, 150int zgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
124 doublecomplex *a, integer *lda, doublereal *s, doublecomplex *u, 151 doublecomplex *a, integer *lda, doublereal *s, doublecomplex *u,
125 integer *ldu, doublecomplex *vt, integer *ldvt, doublecomplex *work, 152 integer *ldu, doublecomplex *vt, integer *ldvt, doublecomplex *work,
126 integer *lwork, doublereal *rwork, integer *info); 153 integer *lwork, doublereal *rwork, integer *info);
127 154
128int svd_l_C(KCMAT(a),CMAT(u), DVEC(s),CMAT(v)) { 155int svd_l_C(KCMAT(a),CMAT(u), DVEC(s),CMAT(v)) {
129 integer m = ar; 156 integer m = ar;
130 integer n = ac; 157 integer n = ac;
131 integer q = MIN(m,n); 158 integer q = MIN(m,n);
132 REQUIRES(ur==m && uc==m && sn==q && vr==n && vc==n,BAD_SIZE); 159 REQUIRES(sn==q,BAD_SIZE);
133 DEBUGMSG("svd_l_C"); 160 REQUIRES(up==NULL || ur==m && (uc==m || uc==q),BAD_SIZE);
161 char* jobu = "A";
162 if (up==NULL) {
163 jobu = "N";
164 } else {
165 if (uc==q) {
166 jobu = "S";
167 }
168 }
169 REQUIRES(vp==NULL || vc==n && (vr==n || vr==q),BAD_SIZE);
170 char* jobvt = "A";
171 integer ldvt = n;
172 if (vp==NULL) {
173 jobvt = "N";
174 } else {
175 if (vr==q) {
176 jobvt = "S";
177 ldvt = q;
178 }
179 }DEBUGMSG("svd_l_C");
134 double *B = (double*)malloc(2*m*n*sizeof(double)); 180 double *B = (double*)malloc(2*m*n*sizeof(double));
135 CHECK(!B,MEM); 181 CHECK(!B,MEM);
136 memcpy(B,ap,m*n*2*sizeof(double)); 182 memcpy(B,ap,m*n*2*sizeof(double));
@@ -141,26 +187,22 @@ int svd_l_C(KCMAT(a),CMAT(u), DVEC(s),CMAT(v)) {
141 integer res; 187 integer res;
142 // ask for optimal lwork 188 // ask for optimal lwork
143 doublecomplex ans; 189 doublecomplex ans;
144 //printf("ask zgesvd\n"); 190 zgesvd_ (jobu,jobvt,
145 char* job = "A";
146 zgesvd_ (job,job,
147 &m,&n,(doublecomplex*)B,&m, 191 &m,&n,(doublecomplex*)B,&m,
148 sp, 192 sp,
149 (doublecomplex*)up,&m, 193 (doublecomplex*)up,&m,
150 (doublecomplex*)vp,&n, 194 (doublecomplex*)vp,&ldvt,
151 &ans, &lwork, 195 &ans, &lwork,
152 rwork, 196 rwork,
153 &res); 197 &res);
154 lwork = ceil(ans.r); 198 lwork = ceil(ans.r);
155 //printf("ans = %d\n",lwork);
156 doublecomplex * work = (doublecomplex*)malloc(lwork*2*sizeof(double)); 199 doublecomplex * work = (doublecomplex*)malloc(lwork*2*sizeof(double));
157 CHECK(!work,MEM); 200 CHECK(!work,MEM);
158 //printf("zgesvd\n"); 201 zgesvd_ (jobu,jobvt,
159 zgesvd_ (job,job,
160 &m,&n,(doublecomplex*)B,&m, 202 &m,&n,(doublecomplex*)B,&m,
161 sp, 203 sp,
162 (doublecomplex*)up,&m, 204 (doublecomplex*)up,&m,
163 (doublecomplex*)vp,&n, 205 (doublecomplex*)vp,&ldvt,
164 work, &lwork, 206 work, &lwork,
165 rwork, 207 rwork,
166 &res); 208 &res);
@@ -171,7 +213,64 @@ int svd_l_C(KCMAT(a),CMAT(u), DVEC(s),CMAT(v)) {
171 OK 213 OK
172} 214}
173 215
216int zgesdd_ (char *jobz, integer *m, integer *n,
217 doublecomplex *a, integer *lda, doublereal *s, doublecomplex *u,
218 integer *ldu, doublecomplex *vt, integer *ldvt, doublecomplex *work,
219 integer *lwork, doublereal *rwork, integer* iwork, integer *info);
174 220
221int svd_l_Cdd(KCMAT(a),CMAT(u), DVEC(s),CMAT(v)) {
222 //printf("entro\n");
223 integer m = ar;
224 integer n = ac;
225 integer q = MIN(m,n);
226 REQUIRES(sn==q,BAD_SIZE);
227 REQUIRES(up == NULL && vp == NULL
228 || ur==m && vc==n
229 && (uc == q && vr == q
230 || uc == m && vc==n),BAD_SIZE);
231 char* jobz = "A";
232 integer ldvt = n;
233 if (up==NULL) {
234 jobz = "N";
235 } else {
236 if (uc==q && vr == q) {
237 jobz = "S";
238 ldvt = q;
239 }
240 }
241 DEBUGMSG("svd_l_Cdd");
242 doublecomplex *B = (doublecomplex*)malloc(m*n*sizeof(doublecomplex));
243 CHECK(!B,MEM);
244 memcpy(B,ap,m*n*sizeof(doublecomplex));
245 integer* iwk = (integer*) malloc(8*q*sizeof(integer));
246 CHECK(!iwk,MEM);
247 int lrwk;
248 if (0 && *jobz == 'N') {
249 lrwk = 5*q; // does not work, crash at free below
250 } else {
251 lrwk = 5*q*q + 7*q;
252 }
253 double *rwk = (double*)malloc(lrwk*sizeof(double));;
254 CHECK(!rwk,MEM);
255 //printf("%s %ld %d\n",jobz,q,lrwk);
256 integer lwk = -1;
257 integer res;
258 // ask for optimal lwk
259 doublecomplex ans;
260 zgesdd_ (jobz,&m,&n,B,&m,sp,(doublecomplex*)up,&m,(doublecomplex*)vp,&ldvt,&ans,&lwk,rwk,iwk,&res);
261 lwk = ans.r;
262 //printf("lwk = %ld\n",lwk);
263 doublecomplex * workv = (doublecomplex*)malloc(lwk*sizeof(doublecomplex));
264 CHECK(!workv,MEM);
265 zgesdd_ (jobz,&m,&n,B,&m,sp,(doublecomplex*)up,&m,(doublecomplex*)vp,&ldvt,workv,&lwk,rwk,iwk,&res);
266 //printf("res = %ld\n",res);
267 CHECK(res,res);
268 free(workv); // printf("freed workv\n");
269 free(rwk); // printf("freed rwk\n");
270 free(iwk); // printf("freed iwk\n");
271 free(B); // printf("freed B, salgo\n");
272 OK
273}
175 274
176//////////////////// general complex eigensystem //////////// 275//////////////////// general complex eigensystem ////////////
177 276