00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
00017
00018 static integer c__1 = 1;
00019 static real c_b6 = 0.f;
00020 static integer c__0 = 0;
00021 static real c_b11 = 1.f;
00022
00023 int slalsd_(char *uplo, integer *smlsiz, integer *n, integer
00024 *nrhs, real *d__, real *e, real *b, integer *ldb, real *rcond,
00025 integer *rank, real *work, integer *iwork, integer *info)
00026 {
00027
00028 integer b_dim1, b_offset, i__1, i__2;
00029 real r__1;
00030
00031
00032 double log(doublereal), r_sign(real *, real *);
00033
00034
00035 integer c__, i__, j, k;
00036 real r__;
00037 integer s, u, z__;
00038 real cs;
00039 integer bx;
00040 real sn;
00041 integer st, vt, nm1, st1;
00042 real eps;
00043 integer iwk;
00044 real tol;
00045 integer difl, difr;
00046 real rcnd;
00047 integer perm, nsub, nlvl, sqre, bxst;
00048 extern int srot_(integer *, real *, integer *, real *,
00049 integer *, real *, real *), sgemm_(char *, char *, integer *,
00050 integer *, integer *, real *, real *, integer *, real *, integer *
00051 , real *, real *, integer *);
00052 integer poles, sizei, nsize;
00053 extern int scopy_(integer *, real *, integer *, real *,
00054 integer *);
00055 integer nwork, icmpq1, icmpq2;
00056 extern doublereal slamch_(char *);
00057 extern int slasda_(integer *, integer *, integer *,
00058 integer *, real *, real *, real *, integer *, real *, integer *,
00059 real *, real *, real *, real *, integer *, integer *, integer *,
00060 integer *, real *, real *, real *, real *, integer *, integer *),
00061 xerbla_(char *, integer *), slalsa_(integer *, integer *,
00062 integer *, integer *, real *, integer *, real *, integer *, real *
00063 , integer *, real *, integer *, real *, real *, real *, real *,
00064 integer *, integer *, integer *, integer *, real *, real *, real *
00065 , real *, integer *, integer *), slascl_(char *, integer *,
00066 integer *, real *, real *, integer *, integer *, real *, integer *
00067 , integer *);
00068 integer givcol;
00069 extern integer isamax_(integer *, real *, integer *);
00070 extern int slasdq_(char *, integer *, integer *, integer
00071 *, integer *, integer *, real *, real *, real *, integer *, real *
00072 , integer *, real *, integer *, real *, integer *),
00073 slacpy_(char *, integer *, integer *, real *, integer *, real *,
00074 integer *), slartg_(real *, real *, real *, real *, real *
00075 ), slaset_(char *, integer *, integer *, real *, real *, real *,
00076 integer *);
00077 real orgnrm;
00078 integer givnum;
00079 extern doublereal slanst_(char *, integer *, real *, real *);
00080 extern int slasrt_(char *, integer *, real *, integer *);
00081 integer givptr, smlszp;
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 --d__;
00201 --e;
00202 b_dim1 = *ldb;
00203 b_offset = 1 + b_dim1;
00204 b -= b_offset;
00205 --work;
00206 --iwork;
00207
00208
00209 *info = 0;
00210
00211 if (*n < 0) {
00212 *info = -3;
00213 } else if (*nrhs < 1) {
00214 *info = -4;
00215 } else if (*ldb < 1 || *ldb < *n) {
00216 *info = -8;
00217 }
00218 if (*info != 0) {
00219 i__1 = -(*info);
00220 xerbla_("SLALSD", &i__1);
00221 return 0;
00222 }
00223
00224 eps = slamch_("Epsilon");
00225
00226
00227
00228 if (*rcond <= 0.f || *rcond >= 1.f) {
00229 rcnd = eps;
00230 } else {
00231 rcnd = *rcond;
00232 }
00233
00234 *rank = 0;
00235
00236
00237
00238 if (*n == 0) {
00239 return 0;
00240 } else if (*n == 1) {
00241 if (d__[1] == 0.f) {
00242 slaset_("A", &c__1, nrhs, &c_b6, &c_b6, &b[b_offset], ldb);
00243 } else {
00244 *rank = 1;
00245 slascl_("G", &c__0, &c__0, &d__[1], &c_b11, &c__1, nrhs, &b[
00246 b_offset], ldb, info);
00247 d__[1] = dabs(d__[1]);
00248 }
00249 return 0;
00250 }
00251
00252
00253
00254 if (*(unsigned char *)uplo == 'L') {
00255 i__1 = *n - 1;
00256 for (i__ = 1; i__ <= i__1; ++i__) {
00257 slartg_(&d__[i__], &e[i__], &cs, &sn, &r__);
00258 d__[i__] = r__;
00259 e[i__] = sn * d__[i__ + 1];
00260 d__[i__ + 1] = cs * d__[i__ + 1];
00261 if (*nrhs == 1) {
00262 srot_(&c__1, &b[i__ + b_dim1], &c__1, &b[i__ + 1 + b_dim1], &
00263 c__1, &cs, &sn);
00264 } else {
00265 work[(i__ << 1) - 1] = cs;
00266 work[i__ * 2] = sn;
00267 }
00268
00269 }
00270 if (*nrhs > 1) {
00271 i__1 = *nrhs;
00272 for (i__ = 1; i__ <= i__1; ++i__) {
00273 i__2 = *n - 1;
00274 for (j = 1; j <= i__2; ++j) {
00275 cs = work[(j << 1) - 1];
00276 sn = work[j * 2];
00277 srot_(&c__1, &b[j + i__ * b_dim1], &c__1, &b[j + 1 + i__ *
00278 b_dim1], &c__1, &cs, &sn);
00279
00280 }
00281
00282 }
00283 }
00284 }
00285
00286
00287
00288 nm1 = *n - 1;
00289 orgnrm = slanst_("M", n, &d__[1], &e[1]);
00290 if (orgnrm == 0.f) {
00291 slaset_("A", n, nrhs, &c_b6, &c_b6, &b[b_offset], ldb);
00292 return 0;
00293 }
00294
00295 slascl_("G", &c__0, &c__0, &orgnrm, &c_b11, n, &c__1, &d__[1], n, info);
00296 slascl_("G", &c__0, &c__0, &orgnrm, &c_b11, &nm1, &c__1, &e[1], &nm1,
00297 info);
00298
00299
00300
00301
00302 if (*n <= *smlsiz) {
00303 nwork = *n * *n + 1;
00304 slaset_("A", n, n, &c_b6, &c_b11, &work[1], n);
00305 slasdq_("U", &c__0, n, n, &c__0, nrhs, &d__[1], &e[1], &work[1], n, &
00306 work[1], n, &b[b_offset], ldb, &work[nwork], info);
00307 if (*info != 0) {
00308 return 0;
00309 }
00310 tol = rcnd * (r__1 = d__[isamax_(n, &d__[1], &c__1)], dabs(r__1));
00311 i__1 = *n;
00312 for (i__ = 1; i__ <= i__1; ++i__) {
00313 if (d__[i__] <= tol) {
00314 slaset_("A", &c__1, nrhs, &c_b6, &c_b6, &b[i__ + b_dim1], ldb);
00315 } else {
00316 slascl_("G", &c__0, &c__0, &d__[i__], &c_b11, &c__1, nrhs, &b[
00317 i__ + b_dim1], ldb, info);
00318 ++(*rank);
00319 }
00320
00321 }
00322 sgemm_("T", "N", n, nrhs, n, &c_b11, &work[1], n, &b[b_offset], ldb, &
00323 c_b6, &work[nwork], n);
00324 slacpy_("A", n, nrhs, &work[nwork], n, &b[b_offset], ldb);
00325
00326
00327
00328 slascl_("G", &c__0, &c__0, &c_b11, &orgnrm, n, &c__1, &d__[1], n,
00329 info);
00330 slasrt_("D", n, &d__[1], info);
00331 slascl_("G", &c__0, &c__0, &orgnrm, &c_b11, n, nrhs, &b[b_offset],
00332 ldb, info);
00333
00334 return 0;
00335 }
00336
00337
00338
00339 nlvl = (integer) (log((real) (*n) / (real) (*smlsiz + 1)) / log(2.f)) + 1;
00340
00341 smlszp = *smlsiz + 1;
00342
00343 u = 1;
00344 vt = *smlsiz * *n + 1;
00345 difl = vt + smlszp * *n;
00346 difr = difl + nlvl * *n;
00347 z__ = difr + (nlvl * *n << 1);
00348 c__ = z__ + nlvl * *n;
00349 s = c__ + *n;
00350 poles = s + *n;
00351 givnum = poles + (nlvl << 1) * *n;
00352 bx = givnum + (nlvl << 1) * *n;
00353 nwork = bx + *n * *nrhs;
00354
00355 sizei = *n + 1;
00356 k = sizei + *n;
00357 givptr = k + *n;
00358 perm = givptr + *n;
00359 givcol = perm + nlvl * *n;
00360 iwk = givcol + (nlvl * *n << 1);
00361
00362 st = 1;
00363 sqre = 0;
00364 icmpq1 = 1;
00365 icmpq2 = 0;
00366 nsub = 0;
00367
00368 i__1 = *n;
00369 for (i__ = 1; i__ <= i__1; ++i__) {
00370 if ((r__1 = d__[i__], dabs(r__1)) < eps) {
00371 d__[i__] = r_sign(&eps, &d__[i__]);
00372 }
00373
00374 }
00375
00376 i__1 = nm1;
00377 for (i__ = 1; i__ <= i__1; ++i__) {
00378 if ((r__1 = e[i__], dabs(r__1)) < eps || i__ == nm1) {
00379 ++nsub;
00380 iwork[nsub] = st;
00381
00382
00383
00384
00385 if (i__ < nm1) {
00386
00387
00388
00389 nsize = i__ - st + 1;
00390 iwork[sizei + nsub - 1] = nsize;
00391 } else if ((r__1 = e[i__], dabs(r__1)) >= eps) {
00392
00393
00394
00395 nsize = *n - st + 1;
00396 iwork[sizei + nsub - 1] = nsize;
00397 } else {
00398
00399
00400
00401
00402
00403 nsize = i__ - st + 1;
00404 iwork[sizei + nsub - 1] = nsize;
00405 ++nsub;
00406 iwork[nsub] = *n;
00407 iwork[sizei + nsub - 1] = 1;
00408 scopy_(nrhs, &b[*n + b_dim1], ldb, &work[bx + nm1], n);
00409 }
00410 st1 = st - 1;
00411 if (nsize == 1) {
00412
00413
00414
00415
00416 scopy_(nrhs, &b[st + b_dim1], ldb, &work[bx + st1], n);
00417 } else if (nsize <= *smlsiz) {
00418
00419
00420
00421 slaset_("A", &nsize, &nsize, &c_b6, &c_b11, &work[vt + st1],
00422 n);
00423 slasdq_("U", &c__0, &nsize, &nsize, &c__0, nrhs, &d__[st], &e[
00424 st], &work[vt + st1], n, &work[nwork], n, &b[st +
00425 b_dim1], ldb, &work[nwork], info);
00426 if (*info != 0) {
00427 return 0;
00428 }
00429 slacpy_("A", &nsize, nrhs, &b[st + b_dim1], ldb, &work[bx +
00430 st1], n);
00431 } else {
00432
00433
00434
00435 slasda_(&icmpq1, smlsiz, &nsize, &sqre, &d__[st], &e[st], &
00436 work[u + st1], n, &work[vt + st1], &iwork[k + st1], &
00437 work[difl + st1], &work[difr + st1], &work[z__ + st1],
00438 &work[poles + st1], &iwork[givptr + st1], &iwork[
00439 givcol + st1], n, &iwork[perm + st1], &work[givnum +
00440 st1], &work[c__ + st1], &work[s + st1], &work[nwork],
00441 &iwork[iwk], info);
00442 if (*info != 0) {
00443 return 0;
00444 }
00445 bxst = bx + st1;
00446 slalsa_(&icmpq2, smlsiz, &nsize, nrhs, &b[st + b_dim1], ldb, &
00447 work[bxst], n, &work[u + st1], n, &work[vt + st1], &
00448 iwork[k + st1], &work[difl + st1], &work[difr + st1],
00449 &work[z__ + st1], &work[poles + st1], &iwork[givptr +
00450 st1], &iwork[givcol + st1], n, &iwork[perm + st1], &
00451 work[givnum + st1], &work[c__ + st1], &work[s + st1],
00452 &work[nwork], &iwork[iwk], info);
00453 if (*info != 0) {
00454 return 0;
00455 }
00456 }
00457 st = i__ + 1;
00458 }
00459
00460 }
00461
00462
00463
00464 tol = rcnd * (r__1 = d__[isamax_(n, &d__[1], &c__1)], dabs(r__1));
00465
00466 i__1 = *n;
00467 for (i__ = 1; i__ <= i__1; ++i__) {
00468
00469
00470
00471
00472 if ((r__1 = d__[i__], dabs(r__1)) <= tol) {
00473 slaset_("A", &c__1, nrhs, &c_b6, &c_b6, &work[bx + i__ - 1], n);
00474 } else {
00475 ++(*rank);
00476 slascl_("G", &c__0, &c__0, &d__[i__], &c_b11, &c__1, nrhs, &work[
00477 bx + i__ - 1], n, info);
00478 }
00479 d__[i__] = (r__1 = d__[i__], dabs(r__1));
00480
00481 }
00482
00483
00484
00485 icmpq2 = 1;
00486 i__1 = nsub;
00487 for (i__ = 1; i__ <= i__1; ++i__) {
00488 st = iwork[i__];
00489 st1 = st - 1;
00490 nsize = iwork[sizei + i__ - 1];
00491 bxst = bx + st1;
00492 if (nsize == 1) {
00493 scopy_(nrhs, &work[bxst], n, &b[st + b_dim1], ldb);
00494 } else if (nsize <= *smlsiz) {
00495 sgemm_("T", "N", &nsize, nrhs, &nsize, &c_b11, &work[vt + st1], n,
00496 &work[bxst], n, &c_b6, &b[st + b_dim1], ldb);
00497 } else {
00498 slalsa_(&icmpq2, smlsiz, &nsize, nrhs, &work[bxst], n, &b[st +
00499 b_dim1], ldb, &work[u + st1], n, &work[vt + st1], &iwork[
00500 k + st1], &work[difl + st1], &work[difr + st1], &work[z__
00501 + st1], &work[poles + st1], &iwork[givptr + st1], &iwork[
00502 givcol + st1], n, &iwork[perm + st1], &work[givnum + st1],
00503 &work[c__ + st1], &work[s + st1], &work[nwork], &iwork[
00504 iwk], info);
00505 if (*info != 0) {
00506 return 0;
00507 }
00508 }
00509
00510 }
00511
00512
00513
00514 slascl_("G", &c__0, &c__0, &c_b11, &orgnrm, n, &c__1, &d__[1], n, info);
00515 slasrt_("D", n, &d__[1], info);
00516 slascl_("G", &c__0, &c__0, &orgnrm, &c_b11, n, nrhs, &b[b_offset], ldb,
00517 info);
00518
00519 return 0;
00520
00521
00522
00523 }