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__9 = 9;
00019 static integer c__0 = 0;
00020 static integer c__6 = 6;
00021 static integer c_n1 = -1;
00022 static integer c__1 = 1;
00023 static real c_b81 = 0.f;
00024
00025 int sgelsd_(integer *m, integer *n, integer *nrhs, real *a,
00026 integer *lda, real *b, integer *ldb, real *s, real *rcond, integer *
00027 rank, real *work, integer *lwork, integer *iwork, integer *info)
00028 {
00029
00030 integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3, i__4;
00031
00032
00033 double log(doublereal);
00034
00035
00036 integer ie, il, mm;
00037 real eps, anrm, bnrm;
00038 integer itau, nlvl, iascl, ibscl;
00039 real sfmin;
00040 integer minmn, maxmn, itaup, itauq, mnthr, nwork;
00041 extern int slabad_(real *, real *), sgebrd_(integer *,
00042 integer *, real *, integer *, real *, real *, real *, real *,
00043 real *, integer *, integer *);
00044 extern doublereal slamch_(char *), slange_(char *, integer *,
00045 integer *, real *, integer *, real *);
00046 extern int xerbla_(char *, integer *);
00047 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00048 integer *, integer *);
00049 real bignum;
00050 extern int sgelqf_(integer *, integer *, real *, integer
00051 *, real *, real *, integer *, integer *), slalsd_(char *, integer
00052 *, integer *, integer *, real *, real *, real *, integer *, real *
00053 , integer *, real *, integer *, integer *), slascl_(char *
00054 , integer *, integer *, real *, real *, integer *, integer *,
00055 real *, integer *, integer *);
00056 integer wlalsd;
00057 extern int sgeqrf_(integer *, integer *, real *, integer
00058 *, real *, real *, integer *, integer *), slacpy_(char *, integer
00059 *, integer *, real *, integer *, real *, integer *),
00060 slaset_(char *, integer *, integer *, real *, real *, real *,
00061 integer *);
00062 integer ldwork;
00063 extern int sormbr_(char *, char *, char *, integer *,
00064 integer *, integer *, real *, integer *, real *, real *, integer *
00065 , real *, integer *, integer *);
00066 integer liwork, minwrk, maxwrk;
00067 real smlnum;
00068 extern int sormlq_(char *, char *, integer *, integer *,
00069 integer *, real *, integer *, real *, real *, integer *, real *,
00070 integer *, integer *);
00071 logical lquery;
00072 integer smlsiz;
00073 extern int sormqr_(char *, char *, integer *, integer *,
00074 integer *, real *, integer *, real *, real *, integer *, real *,
00075 integer *, integer *);
00076
00077
00078
00079
00080
00081
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
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 a_dim1 = *lda;
00224 a_offset = 1 + a_dim1;
00225 a -= a_offset;
00226 b_dim1 = *ldb;
00227 b_offset = 1 + b_dim1;
00228 b -= b_offset;
00229 --s;
00230 --work;
00231 --iwork;
00232
00233
00234 *info = 0;
00235 minmn = min(*m,*n);
00236 maxmn = max(*m,*n);
00237 lquery = *lwork == -1;
00238 if (*m < 0) {
00239 *info = -1;
00240 } else if (*n < 0) {
00241 *info = -2;
00242 } else if (*nrhs < 0) {
00243 *info = -3;
00244 } else if (*lda < max(1,*m)) {
00245 *info = -5;
00246 } else if (*ldb < max(1,maxmn)) {
00247 *info = -7;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257 if (*info == 0) {
00258 minwrk = 1;
00259 maxwrk = 1;
00260 liwork = 1;
00261 if (minmn > 0) {
00262 smlsiz = ilaenv_(&c__9, "SGELSD", " ", &c__0, &c__0, &c__0, &c__0);
00263 mnthr = ilaenv_(&c__6, "SGELSD", " ", m, n, nrhs, &c_n1);
00264
00265 i__1 = (integer) (log((real) minmn / (real) (smlsiz + 1)) / log(
00266 2.f)) + 1;
00267 nlvl = max(i__1,0);
00268 liwork = minmn * 3 * nlvl + minmn * 11;
00269 mm = *m;
00270 if (*m >= *n && *m >= mnthr) {
00271
00272
00273
00274
00275 mm = *n;
00276
00277 i__1 = maxwrk, i__2 = *n + *n * ilaenv_(&c__1, "SGEQRF",
00278 " ", m, n, &c_n1, &c_n1);
00279 maxwrk = max(i__1,i__2);
00280
00281 i__1 = maxwrk, i__2 = *n + *nrhs * ilaenv_(&c__1, "SORMQR",
00282 "LT", m, nrhs, n, &c_n1);
00283 maxwrk = max(i__1,i__2);
00284 }
00285 if (*m >= *n) {
00286
00287
00288
00289
00290 i__1 = maxwrk, i__2 = *n * 3 + (mm + *n) * ilaenv_(&c__1,
00291 "SGEBRD", " ", &mm, n, &c_n1, &c_n1);
00292 maxwrk = max(i__1,i__2);
00293
00294 i__1 = maxwrk, i__2 = *n * 3 + *nrhs * ilaenv_(&c__1, "SORMBR"
00295 , "QLT", &mm, nrhs, n, &c_n1);
00296 maxwrk = max(i__1,i__2);
00297
00298 i__1 = maxwrk, i__2 = *n * 3 + (*n - 1) * ilaenv_(&c__1,
00299 "SORMBR", "PLN", n, nrhs, n, &c_n1);
00300 maxwrk = max(i__1,i__2);
00301
00302 i__1 = smlsiz + 1;
00303 wlalsd = *n * 9 + (*n << 1) * smlsiz + (*n << 3) * nlvl + *n *
00304 *nrhs + i__1 * i__1;
00305
00306 i__1 = maxwrk, i__2 = *n * 3 + wlalsd;
00307 maxwrk = max(i__1,i__2);
00308
00309 i__1 = *n * 3 + mm, i__2 = *n * 3 + *nrhs, i__1 = max(i__1,
00310 i__2), i__2 = *n * 3 + wlalsd;
00311 minwrk = max(i__1,i__2);
00312 }
00313 if (*n > *m) {
00314
00315 i__1 = smlsiz + 1;
00316 wlalsd = *m * 9 + (*m << 1) * smlsiz + (*m << 3) * nlvl + *m *
00317 *nrhs + i__1 * i__1;
00318 if (*n >= mnthr) {
00319
00320
00321
00322
00323 maxwrk = *m + *m * ilaenv_(&c__1, "SGELQF", " ", m, n, &
00324 c_n1, &c_n1);
00325
00326 i__1 = maxwrk, i__2 = *m * *m + (*m << 2) + (*m << 1) *
00327 ilaenv_(&c__1, "SGEBRD", " ", m, m, &c_n1, &c_n1);
00328 maxwrk = max(i__1,i__2);
00329
00330 i__1 = maxwrk, i__2 = *m * *m + (*m << 2) + *nrhs *
00331 ilaenv_(&c__1, "SORMBR", "QLT", m, nrhs, m, &c_n1);
00332 maxwrk = max(i__1,i__2);
00333
00334 i__1 = maxwrk, i__2 = *m * *m + (*m << 2) + (*m - 1) *
00335 ilaenv_(&c__1, "SORMBR", "PLN", m, nrhs, m, &c_n1);
00336 maxwrk = max(i__1,i__2);
00337 if (*nrhs > 1) {
00338
00339 i__1 = maxwrk, i__2 = *m * *m + *m + *m * *nrhs;
00340 maxwrk = max(i__1,i__2);
00341 } else {
00342
00343 i__1 = maxwrk, i__2 = *m * *m + (*m << 1);
00344 maxwrk = max(i__1,i__2);
00345 }
00346
00347 i__1 = maxwrk, i__2 = *m + *nrhs * ilaenv_(&c__1, "SORMLQ"
00348 , "LT", n, nrhs, m, &c_n1);
00349 maxwrk = max(i__1,i__2);
00350
00351 i__1 = maxwrk, i__2 = *m * *m + (*m << 2) + wlalsd;
00352 maxwrk = max(i__1,i__2);
00353
00354
00355
00356
00357 i__3 = *m, i__4 = (*m << 1) - 4, i__3 = max(i__3,i__4),
00358 i__3 = max(i__3,*nrhs), i__4 = *n - *m * 3;
00359 i__1 = maxwrk, i__2 = (*m << 2) + *m * *m + max(i__3,i__4)
00360 ;
00361 maxwrk = max(i__1,i__2);
00362 } else {
00363
00364
00365
00366 maxwrk = *m * 3 + (*n + *m) * ilaenv_(&c__1, "SGEBRD",
00367 " ", m, n, &c_n1, &c_n1);
00368
00369 i__1 = maxwrk, i__2 = *m * 3 + *nrhs * ilaenv_(&c__1,
00370 "SORMBR", "QLT", m, nrhs, n, &c_n1);
00371 maxwrk = max(i__1,i__2);
00372
00373 i__1 = maxwrk, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORM"
00374 "BR", "PLN", n, nrhs, m, &c_n1);
00375 maxwrk = max(i__1,i__2);
00376
00377 i__1 = maxwrk, i__2 = *m * 3 + wlalsd;
00378 maxwrk = max(i__1,i__2);
00379 }
00380
00381 i__1 = *m * 3 + *nrhs, i__2 = *m * 3 + *m, i__1 = max(i__1,
00382 i__2), i__2 = *m * 3 + wlalsd;
00383 minwrk = max(i__1,i__2);
00384 }
00385 }
00386 minwrk = min(minwrk,maxwrk);
00387 work[1] = (real) maxwrk;
00388 iwork[1] = liwork;
00389
00390 if (*lwork < minwrk && ! lquery) {
00391 *info = -12;
00392 }
00393 }
00394
00395 if (*info != 0) {
00396 i__1 = -(*info);
00397 xerbla_("SGELSD", &i__1);
00398 return 0;
00399 } else if (lquery) {
00400 return 0;
00401 }
00402
00403
00404
00405 if (*m == 0 || *n == 0) {
00406 *rank = 0;
00407 return 0;
00408 }
00409
00410
00411
00412 eps = slamch_("P");
00413 sfmin = slamch_("S");
00414 smlnum = sfmin / eps;
00415 bignum = 1.f / smlnum;
00416 slabad_(&smlnum, &bignum);
00417
00418
00419
00420 anrm = slange_("M", m, n, &a[a_offset], lda, &work[1]);
00421 iascl = 0;
00422 if (anrm > 0.f && anrm < smlnum) {
00423
00424
00425
00426 slascl_("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda,
00427 info);
00428 iascl = 1;
00429 } else if (anrm > bignum) {
00430
00431
00432
00433 slascl_("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda,
00434 info);
00435 iascl = 2;
00436 } else if (anrm == 0.f) {
00437
00438
00439
00440 i__1 = max(*m,*n);
00441 slaset_("F", &i__1, nrhs, &c_b81, &c_b81, &b[b_offset], ldb);
00442 slaset_("F", &minmn, &c__1, &c_b81, &c_b81, &s[1], &c__1);
00443 *rank = 0;
00444 goto L10;
00445 }
00446
00447
00448
00449 bnrm = slange_("M", m, nrhs, &b[b_offset], ldb, &work[1]);
00450 ibscl = 0;
00451 if (bnrm > 0.f && bnrm < smlnum) {
00452
00453
00454
00455 slascl_("G", &c__0, &c__0, &bnrm, &smlnum, m, nrhs, &b[b_offset], ldb,
00456 info);
00457 ibscl = 1;
00458 } else if (bnrm > bignum) {
00459
00460
00461
00462 slascl_("G", &c__0, &c__0, &bnrm, &bignum, m, nrhs, &b[b_offset], ldb,
00463 info);
00464 ibscl = 2;
00465 }
00466
00467
00468
00469 if (*m < *n) {
00470 i__1 = *n - *m;
00471 slaset_("F", &i__1, nrhs, &c_b81, &c_b81, &b[*m + 1 + b_dim1], ldb);
00472 }
00473
00474
00475
00476 if (*m >= *n) {
00477
00478
00479
00480 mm = *m;
00481 if (*m >= mnthr) {
00482
00483
00484
00485 mm = *n;
00486 itau = 1;
00487 nwork = itau + *n;
00488
00489
00490
00491
00492 i__1 = *lwork - nwork + 1;
00493 sgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &i__1,
00494 info);
00495
00496
00497
00498
00499 i__1 = *lwork - nwork + 1;
00500 sormqr_("L", "T", m, nrhs, n, &a[a_offset], lda, &work[itau], &b[
00501 b_offset], ldb, &work[nwork], &i__1, info);
00502
00503
00504
00505 if (*n > 1) {
00506 i__1 = *n - 1;
00507 i__2 = *n - 1;
00508 slaset_("L", &i__1, &i__2, &c_b81, &c_b81, &a[a_dim1 + 2],
00509 lda);
00510 }
00511 }
00512
00513 ie = 1;
00514 itauq = ie + *n;
00515 itaup = itauq + *n;
00516 nwork = itaup + *n;
00517
00518
00519
00520
00521 i__1 = *lwork - nwork + 1;
00522 sgebrd_(&mm, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
00523 work[itaup], &work[nwork], &i__1, info);
00524
00525
00526
00527
00528 i__1 = *lwork - nwork + 1;
00529 sormbr_("Q", "L", "T", &mm, nrhs, n, &a[a_offset], lda, &work[itauq],
00530 &b[b_offset], ldb, &work[nwork], &i__1, info);
00531
00532
00533
00534 slalsd_("U", &smlsiz, n, nrhs, &s[1], &work[ie], &b[b_offset], ldb,
00535 rcond, rank, &work[nwork], &iwork[1], info);
00536 if (*info != 0) {
00537 goto L10;
00538 }
00539
00540
00541
00542 i__1 = *lwork - nwork + 1;
00543 sormbr_("P", "L", "N", n, nrhs, n, &a[a_offset], lda, &work[itaup], &
00544 b[b_offset], ldb, &work[nwork], &i__1, info);
00545
00546 } else {
00547
00548 i__1 = *m, i__2 = (*m << 1) - 4, i__1 = max(i__1,i__2), i__1 = max(
00549 i__1,*nrhs), i__2 = *n - *m * 3, i__1 = max(i__1,i__2);
00550 if (*n >= mnthr && *lwork >= (*m << 2) + *m * *m + max(i__1,wlalsd)) {
00551
00552
00553
00554
00555 ldwork = *m;
00556
00557
00558 i__3 = *m, i__4 = (*m << 1) - 4, i__3 = max(i__3,i__4), i__3 =
00559 max(i__3,*nrhs), i__4 = *n - *m * 3;
00560 i__1 = (*m << 2) + *m * *lda + max(i__3,i__4), i__2 = *m * *lda +
00561 *m + *m * *nrhs, i__1 = max(i__1,i__2), i__2 = (*m << 2)
00562 + *m * *lda + wlalsd;
00563 if (*lwork >= max(i__1,i__2)) {
00564 ldwork = *lda;
00565 }
00566 itau = 1;
00567 nwork = *m + 1;
00568
00569
00570
00571
00572 i__1 = *lwork - nwork + 1;
00573 sgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &i__1,
00574 info);
00575 il = nwork;
00576
00577
00578
00579 slacpy_("L", m, m, &a[a_offset], lda, &work[il], &ldwork);
00580 i__1 = *m - 1;
00581 i__2 = *m - 1;
00582 slaset_("U", &i__1, &i__2, &c_b81, &c_b81, &work[il + ldwork], &
00583 ldwork);
00584 ie = il + ldwork * *m;
00585 itauq = ie + *m;
00586 itaup = itauq + *m;
00587 nwork = itaup + *m;
00588
00589
00590
00591
00592 i__1 = *lwork - nwork + 1;
00593 sgebrd_(m, m, &work[il], &ldwork, &s[1], &work[ie], &work[itauq],
00594 &work[itaup], &work[nwork], &i__1, info);
00595
00596
00597
00598
00599 i__1 = *lwork - nwork + 1;
00600 sormbr_("Q", "L", "T", m, nrhs, m, &work[il], &ldwork, &work[
00601 itauq], &b[b_offset], ldb, &work[nwork], &i__1, info);
00602
00603
00604
00605 slalsd_("U", &smlsiz, m, nrhs, &s[1], &work[ie], &b[b_offset],
00606 ldb, rcond, rank, &work[nwork], &iwork[1], info);
00607 if (*info != 0) {
00608 goto L10;
00609 }
00610
00611
00612
00613 i__1 = *lwork - nwork + 1;
00614 sormbr_("P", "L", "N", m, nrhs, m, &work[il], &ldwork, &work[
00615 itaup], &b[b_offset], ldb, &work[nwork], &i__1, info);
00616
00617
00618
00619 i__1 = *n - *m;
00620 slaset_("F", &i__1, nrhs, &c_b81, &c_b81, &b[*m + 1 + b_dim1],
00621 ldb);
00622 nwork = itau + *m;
00623
00624
00625
00626
00627 i__1 = *lwork - nwork + 1;
00628 sormlq_("L", "T", n, nrhs, m, &a[a_offset], lda, &work[itau], &b[
00629 b_offset], ldb, &work[nwork], &i__1, info);
00630
00631 } else {
00632
00633
00634
00635 ie = 1;
00636 itauq = ie + *m;
00637 itaup = itauq + *m;
00638 nwork = itaup + *m;
00639
00640
00641
00642
00643 i__1 = *lwork - nwork + 1;
00644 sgebrd_(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
00645 work[itaup], &work[nwork], &i__1, info);
00646
00647
00648
00649
00650 i__1 = *lwork - nwork + 1;
00651 sormbr_("Q", "L", "T", m, nrhs, n, &a[a_offset], lda, &work[itauq]
00652 , &b[b_offset], ldb, &work[nwork], &i__1, info);
00653
00654
00655
00656 slalsd_("L", &smlsiz, m, nrhs, &s[1], &work[ie], &b[b_offset],
00657 ldb, rcond, rank, &work[nwork], &iwork[1], info);
00658 if (*info != 0) {
00659 goto L10;
00660 }
00661
00662
00663
00664 i__1 = *lwork - nwork + 1;
00665 sormbr_("P", "L", "N", n, nrhs, m, &a[a_offset], lda, &work[itaup]
00666 , &b[b_offset], ldb, &work[nwork], &i__1, info);
00667
00668 }
00669 }
00670
00671
00672
00673 if (iascl == 1) {
00674 slascl_("G", &c__0, &c__0, &anrm, &smlnum, n, nrhs, &b[b_offset], ldb,
00675 info);
00676 slascl_("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
00677 minmn, info);
00678 } else if (iascl == 2) {
00679 slascl_("G", &c__0, &c__0, &anrm, &bignum, n, nrhs, &b[b_offset], ldb,
00680 info);
00681 slascl_("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
00682 minmn, info);
00683 }
00684 if (ibscl == 1) {
00685 slascl_("G", &c__0, &c__0, &smlnum, &bnrm, n, nrhs, &b[b_offset], ldb,
00686 info);
00687 } else if (ibscl == 2) {
00688 slascl_("G", &c__0, &c__0, &bignum, &bnrm, n, nrhs, &b[b_offset], ldb,
00689 info);
00690 }
00691
00692 L10:
00693 work[1] = (real) maxwrk;
00694 iwork[1] = liwork;
00695 return 0;
00696
00697
00698
00699 }