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__0 = 0;
00019 static real c_b11 = 0.f;
00020 static real c_b12 = 1.f;
00021 static integer c__1 = 1;
00022 static integer c__2 = 2;
00023
00024 int slasda_(integer *icompq, integer *smlsiz, integer *n,
00025 integer *sqre, real *d__, real *e, real *u, integer *ldu, real *vt,
00026 integer *k, real *difl, real *difr, real *z__, real *poles, integer *
00027 givptr, integer *givcol, integer *ldgcol, integer *perm, real *givnum,
00028 real *c__, real *s, real *work, integer *iwork, integer *info)
00029 {
00030
00031 integer givcol_dim1, givcol_offset, perm_dim1, perm_offset, difl_dim1,
00032 difl_offset, difr_dim1, difr_offset, givnum_dim1, givnum_offset,
00033 poles_dim1, poles_offset, u_dim1, u_offset, vt_dim1, vt_offset,
00034 z_dim1, z_offset, i__1, i__2;
00035
00036
00037 integer pow_ii(integer *, integer *);
00038
00039
00040 integer i__, j, m, i1, ic, lf, nd, ll, nl, vf, nr, vl, im1, ncc, nlf, nrf,
00041 vfi, iwk, vli, lvl, nru, ndb1, nlp1, lvl2, nrp1;
00042 real beta;
00043 integer idxq, nlvl;
00044 real alpha;
00045 integer inode, ndiml, ndimr, idxqi, itemp, sqrei;
00046 extern int scopy_(integer *, real *, integer *, real *,
00047 integer *), slasd6_(integer *, integer *, integer *, integer *,
00048 real *, real *, real *, real *, real *, integer *, integer *,
00049 integer *, integer *, integer *, real *, integer *, real *, real *
00050 , real *, real *, integer *, real *, real *, real *, integer *,
00051 integer *);
00052 integer nwork1, nwork2;
00053 extern int xerbla_(char *, integer *), slasdq_(
00054 char *, integer *, integer *, integer *, integer *, integer *,
00055 real *, real *, real *, integer *, real *, integer *, real *,
00056 integer *, real *, integer *), slasdt_(integer *, integer
00057 *, integer *, integer *, integer *, integer *, integer *),
00058 slaset_(char *, integer *, integer *, real *, real *, real *,
00059 integer *);
00060 integer smlszp;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
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
00224
00225
00226
00227
00228
00229
00230
00231
00232 --d__;
00233 --e;
00234 givnum_dim1 = *ldu;
00235 givnum_offset = 1 + givnum_dim1;
00236 givnum -= givnum_offset;
00237 poles_dim1 = *ldu;
00238 poles_offset = 1 + poles_dim1;
00239 poles -= poles_offset;
00240 z_dim1 = *ldu;
00241 z_offset = 1 + z_dim1;
00242 z__ -= z_offset;
00243 difr_dim1 = *ldu;
00244 difr_offset = 1 + difr_dim1;
00245 difr -= difr_offset;
00246 difl_dim1 = *ldu;
00247 difl_offset = 1 + difl_dim1;
00248 difl -= difl_offset;
00249 vt_dim1 = *ldu;
00250 vt_offset = 1 + vt_dim1;
00251 vt -= vt_offset;
00252 u_dim1 = *ldu;
00253 u_offset = 1 + u_dim1;
00254 u -= u_offset;
00255 --k;
00256 --givptr;
00257 perm_dim1 = *ldgcol;
00258 perm_offset = 1 + perm_dim1;
00259 perm -= perm_offset;
00260 givcol_dim1 = *ldgcol;
00261 givcol_offset = 1 + givcol_dim1;
00262 givcol -= givcol_offset;
00263 --c__;
00264 --s;
00265 --work;
00266 --iwork;
00267
00268
00269 *info = 0;
00270
00271 if (*icompq < 0 || *icompq > 1) {
00272 *info = -1;
00273 } else if (*smlsiz < 3) {
00274 *info = -2;
00275 } else if (*n < 0) {
00276 *info = -3;
00277 } else if (*sqre < 0 || *sqre > 1) {
00278 *info = -4;
00279 } else if (*ldu < *n + *sqre) {
00280 *info = -8;
00281 } else if (*ldgcol < *n) {
00282 *info = -17;
00283 }
00284 if (*info != 0) {
00285 i__1 = -(*info);
00286 xerbla_("SLASDA", &i__1);
00287 return 0;
00288 }
00289
00290 m = *n + *sqre;
00291
00292
00293
00294 if (*n <= *smlsiz) {
00295 if (*icompq == 0) {
00296 slasdq_("U", sqre, n, &c__0, &c__0, &c__0, &d__[1], &e[1], &vt[
00297 vt_offset], ldu, &u[u_offset], ldu, &u[u_offset], ldu, &
00298 work[1], info);
00299 } else {
00300 slasdq_("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset]
00301 , ldu, &u[u_offset], ldu, &u[u_offset], ldu, &work[1],
00302 info);
00303 }
00304 return 0;
00305 }
00306
00307
00308
00309 inode = 1;
00310 ndiml = inode + *n;
00311 ndimr = ndiml + *n;
00312 idxq = ndimr + *n;
00313 iwk = idxq + *n;
00314
00315 ncc = 0;
00316 nru = 0;
00317
00318 smlszp = *smlsiz + 1;
00319 vf = 1;
00320 vl = vf + m;
00321 nwork1 = vl + m;
00322 nwork2 = nwork1 + smlszp * smlszp;
00323
00324 slasdt_(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr],
00325 smlsiz);
00326
00327
00328
00329
00330 ndb1 = (nd + 1) / 2;
00331 i__1 = nd;
00332 for (i__ = ndb1; i__ <= i__1; ++i__) {
00333
00334
00335
00336
00337
00338
00339
00340 i1 = i__ - 1;
00341 ic = iwork[inode + i1];
00342 nl = iwork[ndiml + i1];
00343 nlp1 = nl + 1;
00344 nr = iwork[ndimr + i1];
00345 nlf = ic - nl;
00346 nrf = ic + 1;
00347 idxqi = idxq + nlf - 2;
00348 vfi = vf + nlf - 1;
00349 vli = vl + nlf - 1;
00350 sqrei = 1;
00351 if (*icompq == 0) {
00352 slaset_("A", &nlp1, &nlp1, &c_b11, &c_b12, &work[nwork1], &smlszp);
00353 slasdq_("U", &sqrei, &nl, &nlp1, &nru, &ncc, &d__[nlf], &e[nlf], &
00354 work[nwork1], &smlszp, &work[nwork2], &nl, &work[nwork2],
00355 &nl, &work[nwork2], info);
00356 itemp = nwork1 + nl * smlszp;
00357 scopy_(&nlp1, &work[nwork1], &c__1, &work[vfi], &c__1);
00358 scopy_(&nlp1, &work[itemp], &c__1, &work[vli], &c__1);
00359 } else {
00360 slaset_("A", &nl, &nl, &c_b11, &c_b12, &u[nlf + u_dim1], ldu);
00361 slaset_("A", &nlp1, &nlp1, &c_b11, &c_b12, &vt[nlf + vt_dim1],
00362 ldu);
00363 slasdq_("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &
00364 vt[nlf + vt_dim1], ldu, &u[nlf + u_dim1], ldu, &u[nlf +
00365 u_dim1], ldu, &work[nwork1], info);
00366 scopy_(&nlp1, &vt[nlf + vt_dim1], &c__1, &work[vfi], &c__1);
00367 scopy_(&nlp1, &vt[nlf + nlp1 * vt_dim1], &c__1, &work[vli], &c__1)
00368 ;
00369 }
00370 if (*info != 0) {
00371 return 0;
00372 }
00373 i__2 = nl;
00374 for (j = 1; j <= i__2; ++j) {
00375 iwork[idxqi + j] = j;
00376
00377 }
00378 if (i__ == nd && *sqre == 0) {
00379 sqrei = 0;
00380 } else {
00381 sqrei = 1;
00382 }
00383 idxqi += nlp1;
00384 vfi += nlp1;
00385 vli += nlp1;
00386 nrp1 = nr + sqrei;
00387 if (*icompq == 0) {
00388 slaset_("A", &nrp1, &nrp1, &c_b11, &c_b12, &work[nwork1], &smlszp);
00389 slasdq_("U", &sqrei, &nr, &nrp1, &nru, &ncc, &d__[nrf], &e[nrf], &
00390 work[nwork1], &smlszp, &work[nwork2], &nr, &work[nwork2],
00391 &nr, &work[nwork2], info);
00392 itemp = nwork1 + (nrp1 - 1) * smlszp;
00393 scopy_(&nrp1, &work[nwork1], &c__1, &work[vfi], &c__1);
00394 scopy_(&nrp1, &work[itemp], &c__1, &work[vli], &c__1);
00395 } else {
00396 slaset_("A", &nr, &nr, &c_b11, &c_b12, &u[nrf + u_dim1], ldu);
00397 slaset_("A", &nrp1, &nrp1, &c_b11, &c_b12, &vt[nrf + vt_dim1],
00398 ldu);
00399 slasdq_("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &
00400 vt[nrf + vt_dim1], ldu, &u[nrf + u_dim1], ldu, &u[nrf +
00401 u_dim1], ldu, &work[nwork1], info);
00402 scopy_(&nrp1, &vt[nrf + vt_dim1], &c__1, &work[vfi], &c__1);
00403 scopy_(&nrp1, &vt[nrf + nrp1 * vt_dim1], &c__1, &work[vli], &c__1)
00404 ;
00405 }
00406 if (*info != 0) {
00407 return 0;
00408 }
00409 i__2 = nr;
00410 for (j = 1; j <= i__2; ++j) {
00411 iwork[idxqi + j] = j;
00412
00413 }
00414
00415 }
00416
00417
00418
00419 j = pow_ii(&c__2, &nlvl);
00420 for (lvl = nlvl; lvl >= 1; --lvl) {
00421 lvl2 = (lvl << 1) - 1;
00422
00423
00424
00425
00426 if (lvl == 1) {
00427 lf = 1;
00428 ll = 1;
00429 } else {
00430 i__1 = lvl - 1;
00431 lf = pow_ii(&c__2, &i__1);
00432 ll = (lf << 1) - 1;
00433 }
00434 i__1 = ll;
00435 for (i__ = lf; i__ <= i__1; ++i__) {
00436 im1 = i__ - 1;
00437 ic = iwork[inode + im1];
00438 nl = iwork[ndiml + im1];
00439 nr = iwork[ndimr + im1];
00440 nlf = ic - nl;
00441 nrf = ic + 1;
00442 if (i__ == ll) {
00443 sqrei = *sqre;
00444 } else {
00445 sqrei = 1;
00446 }
00447 vfi = vf + nlf - 1;
00448 vli = vl + nlf - 1;
00449 idxqi = idxq + nlf - 1;
00450 alpha = d__[ic];
00451 beta = e[ic];
00452 if (*icompq == 0) {
00453 slasd6_(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
00454 work[vli], &alpha, &beta, &iwork[idxqi], &perm[
00455 perm_offset], &givptr[1], &givcol[givcol_offset],
00456 ldgcol, &givnum[givnum_offset], ldu, &poles[
00457 poles_offset], &difl[difl_offset], &difr[difr_offset],
00458 &z__[z_offset], &k[1], &c__[1], &s[1], &work[nwork1],
00459 &iwork[iwk], info);
00460 } else {
00461 --j;
00462 slasd6_(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
00463 work[vli], &alpha, &beta, &iwork[idxqi], &perm[nlf +
00464 lvl * perm_dim1], &givptr[j], &givcol[nlf + lvl2 *
00465 givcol_dim1], ldgcol, &givnum[nlf + lvl2 *
00466 givnum_dim1], ldu, &poles[nlf + lvl2 * poles_dim1], &
00467 difl[nlf + lvl * difl_dim1], &difr[nlf + lvl2 *
00468 difr_dim1], &z__[nlf + lvl * z_dim1], &k[j], &c__[j],
00469 &s[j], &work[nwork1], &iwork[iwk], info);
00470 }
00471 if (*info != 0) {
00472 return 0;
00473 }
00474
00475 }
00476
00477 }
00478
00479 return 0;
00480
00481
00482
00483 }