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 doublecomplex c_b1 = {0.,0.};
00019 static doublecomplex c_b2 = {1.,0.};
00020
00021 int zget22_(char *transa, char *transe, char *transw,
00022 integer *n, doublecomplex *a, integer *lda, doublecomplex *e, integer
00023 *lde, doublecomplex *w, doublecomplex *work, doublereal *rwork,
00024 doublereal *result)
00025 {
00026
00027 integer a_dim1, a_offset, e_dim1, e_offset, i__1, i__2, i__3, i__4;
00028 doublereal d__1, d__2, d__3, d__4;
00029 doublecomplex z__1, z__2;
00030
00031
00032 double d_imag(doublecomplex *);
00033 void d_cnjg(doublecomplex *, doublecomplex *);
00034
00035
00036 integer j;
00037 doublereal ulp;
00038 integer joff, jcol, jvec;
00039 doublereal unfl;
00040 integer jrow;
00041 doublereal temp1;
00042 extern logical lsame_(char *, char *);
00043 char norma[1];
00044 doublereal anorm;
00045 extern int zgemm_(char *, char *, integer *, integer *,
00046 integer *, doublecomplex *, doublecomplex *, integer *,
00047 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00048 integer *);
00049 char norme[1];
00050 doublereal enorm;
00051 doublecomplex wtemp;
00052 extern doublereal dlamch_(char *), zlange_(char *, integer *,
00053 integer *, doublecomplex *, integer *, doublereal *);
00054 doublereal enrmin, enrmax;
00055 extern int zlaset_(char *, integer *, integer *,
00056 doublecomplex *, doublecomplex *, doublecomplex *, integer *);
00057 integer itrnse;
00058 doublereal errnrm;
00059 integer itrnsw;
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
00153
00154
00155 a_dim1 = *lda;
00156 a_offset = 1 + a_dim1;
00157 a -= a_offset;
00158 e_dim1 = *lde;
00159 e_offset = 1 + e_dim1;
00160 e -= e_offset;
00161 --w;
00162 --work;
00163 --rwork;
00164 --result;
00165
00166
00167 result[1] = 0.;
00168 result[2] = 0.;
00169 if (*n <= 0) {
00170 return 0;
00171 }
00172
00173 unfl = dlamch_("Safe minimum");
00174 ulp = dlamch_("Precision");
00175
00176 itrnse = 0;
00177 itrnsw = 0;
00178 *(unsigned char *)norma = 'O';
00179 *(unsigned char *)norme = 'O';
00180
00181 if (lsame_(transa, "T") || lsame_(transa, "C")) {
00182 *(unsigned char *)norma = 'I';
00183 }
00184
00185 if (lsame_(transe, "T")) {
00186 itrnse = 1;
00187 *(unsigned char *)norme = 'I';
00188 } else if (lsame_(transe, "C")) {
00189 itrnse = 2;
00190 *(unsigned char *)norme = 'I';
00191 }
00192
00193 if (lsame_(transw, "C")) {
00194 itrnsw = 1;
00195 }
00196
00197
00198
00199 enrmin = 1. / ulp;
00200 enrmax = 0.;
00201 if (itrnse == 0) {
00202 i__1 = *n;
00203 for (jvec = 1; jvec <= i__1; ++jvec) {
00204 temp1 = 0.;
00205 i__2 = *n;
00206 for (j = 1; j <= i__2; ++j) {
00207
00208 i__3 = j + jvec * e_dim1;
00209 d__3 = temp1, d__4 = (d__1 = e[i__3].r, abs(d__1)) + (d__2 =
00210 d_imag(&e[j + jvec * e_dim1]), abs(d__2));
00211 temp1 = max(d__3,d__4);
00212
00213 }
00214 enrmin = min(enrmin,temp1);
00215 enrmax = max(enrmax,temp1);
00216
00217 }
00218 } else {
00219 i__1 = *n;
00220 for (jvec = 1; jvec <= i__1; ++jvec) {
00221 rwork[jvec] = 0.;
00222
00223 }
00224
00225 i__1 = *n;
00226 for (j = 1; j <= i__1; ++j) {
00227 i__2 = *n;
00228 for (jvec = 1; jvec <= i__2; ++jvec) {
00229
00230 i__3 = jvec + j * e_dim1;
00231 d__3 = rwork[jvec], d__4 = (d__1 = e[i__3].r, abs(d__1)) + (
00232 d__2 = d_imag(&e[jvec + j * e_dim1]), abs(d__2));
00233 rwork[jvec] = max(d__3,d__4);
00234
00235 }
00236
00237 }
00238
00239 i__1 = *n;
00240 for (jvec = 1; jvec <= i__1; ++jvec) {
00241
00242 d__1 = enrmin, d__2 = rwork[jvec];
00243 enrmin = min(d__1,d__2);
00244
00245 d__1 = enrmax, d__2 = rwork[jvec];
00246 enrmax = max(d__1,d__2);
00247
00248 }
00249 }
00250
00251
00252
00253
00254 d__1 = zlange_(norma, n, n, &a[a_offset], lda, &rwork[1]);
00255 anorm = max(d__1,unfl);
00256
00257
00258
00259
00260 d__1 = zlange_(norme, n, n, &e[e_offset], lde, &rwork[1]);
00261 enorm = max(d__1,ulp);
00262
00263
00264
00265
00266
00267 zlaset_("Full", n, n, &c_b1, &c_b1, &work[1], n);
00268
00269 joff = 0;
00270 i__1 = *n;
00271 for (jcol = 1; jcol <= i__1; ++jcol) {
00272 if (itrnsw == 0) {
00273 i__2 = jcol;
00274 wtemp.r = w[i__2].r, wtemp.i = w[i__2].i;
00275 } else {
00276 d_cnjg(&z__1, &w[jcol]);
00277 wtemp.r = z__1.r, wtemp.i = z__1.i;
00278 }
00279
00280 if (itrnse == 0) {
00281 i__2 = *n;
00282 for (jrow = 1; jrow <= i__2; ++jrow) {
00283 i__3 = joff + jrow;
00284 i__4 = jrow + jcol * e_dim1;
00285 z__1.r = e[i__4].r * wtemp.r - e[i__4].i * wtemp.i, z__1.i =
00286 e[i__4].r * wtemp.i + e[i__4].i * wtemp.r;
00287 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00288
00289 }
00290 } else if (itrnse == 1) {
00291 i__2 = *n;
00292 for (jrow = 1; jrow <= i__2; ++jrow) {
00293 i__3 = joff + jrow;
00294 i__4 = jcol + jrow * e_dim1;
00295 z__1.r = e[i__4].r * wtemp.r - e[i__4].i * wtemp.i, z__1.i =
00296 e[i__4].r * wtemp.i + e[i__4].i * wtemp.r;
00297 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00298
00299 }
00300 } else {
00301 i__2 = *n;
00302 for (jrow = 1; jrow <= i__2; ++jrow) {
00303 i__3 = joff + jrow;
00304 d_cnjg(&z__2, &e[jcol + jrow * e_dim1]);
00305 z__1.r = z__2.r * wtemp.r - z__2.i * wtemp.i, z__1.i = z__2.r
00306 * wtemp.i + z__2.i * wtemp.r;
00307 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00308
00309 }
00310 }
00311 joff += *n;
00312
00313 }
00314
00315 z__1.r = -1., z__1.i = -0.;
00316 zgemm_(transa, transe, n, n, n, &c_b2, &a[a_offset], lda, &e[e_offset],
00317 lde, &z__1, &work[1], n);
00318
00319 errnrm = zlange_("One", n, n, &work[1], n, &rwork[1]) / enorm;
00320
00321
00322
00323 if (anorm > errnrm) {
00324 result[1] = errnrm / anorm / ulp;
00325 } else {
00326 if (anorm < 1.) {
00327 result[1] = min(errnrm,anorm) / anorm / ulp;
00328 } else {
00329
00330 d__1 = errnrm / anorm;
00331 result[1] = min(d__1,1.) / ulp;
00332 }
00333 }
00334
00335
00336
00337
00338 d__3 = (d__1 = enrmax - 1., abs(d__1)), d__4 = (d__2 = enrmin - 1., abs(
00339 d__2));
00340 result[2] = max(d__3,d__4) / ((doublereal) (*n) * ulp);
00341
00342 return 0;
00343
00344
00345
00346 }