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__2 = 2;
00021 static integer c__1 = 1;
00022
00023 int zlaed0_(integer *qsiz, integer *n, doublereal *d__,
00024 doublereal *e, doublecomplex *q, integer *ldq, doublecomplex *qstore,
00025 integer *ldqs, doublereal *rwork, integer *iwork, integer *info)
00026 {
00027
00028 integer q_dim1, q_offset, qstore_dim1, qstore_offset, i__1, i__2;
00029 doublereal d__1;
00030
00031
00032 double log(doublereal);
00033 integer pow_ii(integer *, integer *);
00034
00035
00036 integer i__, j, k, ll, iq, lgn, msd2, smm1, spm1, spm2;
00037 doublereal temp;
00038 integer curr, iperm;
00039 extern int dcopy_(integer *, doublereal *, integer *,
00040 doublereal *, integer *);
00041 integer indxq, iwrem, iqptr, tlvls;
00042 extern int zcopy_(integer *, doublecomplex *, integer *,
00043 doublecomplex *, integer *), zlaed7_(integer *, integer *,
00044 integer *, integer *, integer *, integer *, doublereal *,
00045 doublecomplex *, integer *, doublereal *, integer *, doublereal *,
00046 integer *, integer *, integer *, integer *, integer *,
00047 doublereal *, doublecomplex *, doublereal *, integer *, integer *)
00048 ;
00049 integer igivcl;
00050 extern int xerbla_(char *, integer *);
00051 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00052 integer *, integer *);
00053 extern int zlacrm_(integer *, integer *, doublecomplex *,
00054 integer *, doublereal *, integer *, doublecomplex *, integer *,
00055 doublereal *);
00056 integer igivnm, submat, curprb, subpbs, igivpt;
00057 extern int dsteqr_(char *, integer *, doublereal *,
00058 doublereal *, doublereal *, integer *, doublereal *, integer *);
00059 integer curlvl, matsiz, iprmpt, smlsiz;
00060
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 --d__;
00153 --e;
00154 q_dim1 = *ldq;
00155 q_offset = 1 + q_dim1;
00156 q -= q_offset;
00157 qstore_dim1 = *ldqs;
00158 qstore_offset = 1 + qstore_dim1;
00159 qstore -= qstore_offset;
00160 --rwork;
00161 --iwork;
00162
00163
00164 *info = 0;
00165
00166
00167
00168
00169
00170 if (*qsiz < max(0,*n)) {
00171 *info = -1;
00172 } else if (*n < 0) {
00173 *info = -2;
00174 } else if (*ldq < max(1,*n)) {
00175 *info = -6;
00176 } else if (*ldqs < max(1,*n)) {
00177 *info = -8;
00178 }
00179 if (*info != 0) {
00180 i__1 = -(*info);
00181 xerbla_("ZLAED0", &i__1);
00182 return 0;
00183 }
00184
00185
00186
00187 if (*n == 0) {
00188 return 0;
00189 }
00190
00191 smlsiz = ilaenv_(&c__9, "ZLAED0", " ", &c__0, &c__0, &c__0, &c__0);
00192
00193
00194
00195
00196 iwork[1] = *n;
00197 subpbs = 1;
00198 tlvls = 0;
00199 L10:
00200 if (iwork[subpbs] > smlsiz) {
00201 for (j = subpbs; j >= 1; --j) {
00202 iwork[j * 2] = (iwork[j] + 1) / 2;
00203 iwork[(j << 1) - 1] = iwork[j] / 2;
00204
00205 }
00206 ++tlvls;
00207 subpbs <<= 1;
00208 goto L10;
00209 }
00210 i__1 = subpbs;
00211 for (j = 2; j <= i__1; ++j) {
00212 iwork[j] += iwork[j - 1];
00213
00214 }
00215
00216
00217
00218
00219 spm1 = subpbs - 1;
00220 i__1 = spm1;
00221 for (i__ = 1; i__ <= i__1; ++i__) {
00222 submat = iwork[i__] + 1;
00223 smm1 = submat - 1;
00224 d__[smm1] -= (d__1 = e[smm1], abs(d__1));
00225 d__[submat] -= (d__1 = e[smm1], abs(d__1));
00226
00227 }
00228
00229 indxq = (*n << 2) + 3;
00230
00231
00232
00233
00234 temp = log((doublereal) (*n)) / log(2.);
00235 lgn = (integer) temp;
00236 if (pow_ii(&c__2, &lgn) < *n) {
00237 ++lgn;
00238 }
00239 if (pow_ii(&c__2, &lgn) < *n) {
00240 ++lgn;
00241 }
00242 iprmpt = indxq + *n + 1;
00243 iperm = iprmpt + *n * lgn;
00244 iqptr = iperm + *n * lgn;
00245 igivpt = iqptr + *n + 2;
00246 igivcl = igivpt + *n * lgn;
00247
00248 igivnm = 1;
00249 iq = igivnm + (*n << 1) * lgn;
00250
00251 i__1 = *n;
00252 iwrem = iq + i__1 * i__1 + 1;
00253
00254 i__1 = subpbs;
00255 for (i__ = 0; i__ <= i__1; ++i__) {
00256 iwork[iprmpt + i__] = 1;
00257 iwork[igivpt + i__] = 1;
00258
00259 }
00260 iwork[iqptr] = 1;
00261
00262
00263
00264
00265 curr = 0;
00266 i__1 = spm1;
00267 for (i__ = 0; i__ <= i__1; ++i__) {
00268 if (i__ == 0) {
00269 submat = 1;
00270 matsiz = iwork[1];
00271 } else {
00272 submat = iwork[i__] + 1;
00273 matsiz = iwork[i__ + 1] - iwork[i__];
00274 }
00275 ll = iq - 1 + iwork[iqptr + curr];
00276 dsteqr_("I", &matsiz, &d__[submat], &e[submat], &rwork[ll], &matsiz, &
00277 rwork[1], info);
00278 zlacrm_(qsiz, &matsiz, &q[submat * q_dim1 + 1], ldq, &rwork[ll], &
00279 matsiz, &qstore[submat * qstore_dim1 + 1], ldqs, &rwork[iwrem]
00280 );
00281
00282 i__2 = matsiz;
00283 iwork[iqptr + curr + 1] = iwork[iqptr + curr] + i__2 * i__2;
00284 ++curr;
00285 if (*info > 0) {
00286 *info = submat * (*n + 1) + submat + matsiz - 1;
00287 return 0;
00288 }
00289 k = 1;
00290 i__2 = iwork[i__ + 1];
00291 for (j = submat; j <= i__2; ++j) {
00292 iwork[indxq + j] = k;
00293 ++k;
00294
00295 }
00296
00297 }
00298
00299
00300
00301
00302
00303
00304 curlvl = 1;
00305 L80:
00306 if (subpbs > 1) {
00307 spm2 = subpbs - 2;
00308 i__1 = spm2;
00309 for (i__ = 0; i__ <= i__1; i__ += 2) {
00310 if (i__ == 0) {
00311 submat = 1;
00312 matsiz = iwork[2];
00313 msd2 = iwork[1];
00314 curprb = 0;
00315 } else {
00316 submat = iwork[i__] + 1;
00317 matsiz = iwork[i__ + 2] - iwork[i__];
00318 msd2 = matsiz / 2;
00319 ++curprb;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329 zlaed7_(&matsiz, &msd2, qsiz, &tlvls, &curlvl, &curprb, &d__[
00330 submat], &qstore[submat * qstore_dim1 + 1], ldqs, &e[
00331 submat + msd2 - 1], &iwork[indxq + submat], &rwork[iq], &
00332 iwork[iqptr], &iwork[iprmpt], &iwork[iperm], &iwork[
00333 igivpt], &iwork[igivcl], &rwork[igivnm], &q[submat *
00334 q_dim1 + 1], &rwork[iwrem], &iwork[subpbs + 1], info);
00335 if (*info > 0) {
00336 *info = submat * (*n + 1) + submat + matsiz - 1;
00337 return 0;
00338 }
00339 iwork[i__ / 2 + 1] = iwork[i__ + 2];
00340
00341 }
00342 subpbs /= 2;
00343 ++curlvl;
00344 goto L80;
00345 }
00346
00347
00348
00349
00350
00351
00352 i__1 = *n;
00353 for (i__ = 1; i__ <= i__1; ++i__) {
00354 j = iwork[indxq + i__];
00355 rwork[i__] = d__[j];
00356 zcopy_(qsiz, &qstore[j * qstore_dim1 + 1], &c__1, &q[i__ * q_dim1 + 1]
00357 , &c__1);
00358
00359 }
00360 dcopy_(n, &rwork[1], &c__1, &d__[1], &c__1);
00361
00362 return 0;
00363
00364
00365
00366 }