00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016 int dlaln2_(logical *ltrans, integer *na, integer *nw,
00017 doublereal *smin, doublereal *ca, doublereal *a, integer *lda,
00018 doublereal *d1, doublereal *d2, doublereal *b, integer *ldb,
00019 doublereal *wr, doublereal *wi, doublereal *x, integer *ldx,
00020 doublereal *scale, doublereal *xnorm, integer *info)
00021 {
00022
00023
00024 static logical zswap[4] = { FALSE_,FALSE_,TRUE_,TRUE_ };
00025 static logical rswap[4] = { FALSE_,TRUE_,FALSE_,TRUE_ };
00026 static integer ipivot[16] = { 1,2,3,4,2,1,4,3,3,4,1,2,
00027 4,3,2,1 };
00028
00029
00030 integer a_dim1, a_offset, b_dim1, b_offset, x_dim1, x_offset;
00031 doublereal d__1, d__2, d__3, d__4, d__5, d__6;
00032 static doublereal equiv_0[4], equiv_1[4];
00033
00034
00035 integer j;
00036 #define ci (equiv_0)
00037 #define cr (equiv_1)
00038 doublereal bi1, bi2, br1, br2, xi1, xi2, xr1, xr2, ci21, ci22, cr21, cr22,
00039 li21, csi, ui11, lr21, ui12, ui22;
00040 #define civ (equiv_0)
00041 doublereal csr, ur11, ur12, ur22;
00042 #define crv (equiv_1)
00043 doublereal bbnd, cmax, ui11r, ui12s, temp, ur11r, ur12s, u22abs;
00044 integer icmax;
00045 doublereal bnorm, cnorm, smini;
00046 extern doublereal dlamch_(char *);
00047 extern int dladiv_(doublereal *, doublereal *,
00048 doublereal *, doublereal *, doublereal *, doublereal *);
00049 doublereal bignum, smlnum;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
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
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 a_dim1 = *lda;
00194 a_offset = 1 + a_dim1;
00195 a -= a_offset;
00196 b_dim1 = *ldb;
00197 b_offset = 1 + b_dim1;
00198 b -= b_offset;
00199 x_dim1 = *ldx;
00200 x_offset = 1 + x_dim1;
00201 x -= x_offset;
00202
00203
00204
00205
00206
00207
00208
00209 smlnum = 2. * dlamch_("Safe minimum");
00210 bignum = 1. / smlnum;
00211 smini = max(*smin,smlnum);
00212
00213
00214
00215 *info = 0;
00216
00217
00218
00219 *scale = 1.;
00220
00221 if (*na == 1) {
00222
00223
00224
00225 if (*nw == 1) {
00226
00227
00228
00229
00230
00231 csr = *ca * a[a_dim1 + 1] - *wr * *d1;
00232 cnorm = abs(csr);
00233
00234
00235
00236 if (cnorm < smini) {
00237 csr = smini;
00238 cnorm = smini;
00239 *info = 1;
00240 }
00241
00242
00243
00244 bnorm = (d__1 = b[b_dim1 + 1], abs(d__1));
00245 if (cnorm < 1. && bnorm > 1.) {
00246 if (bnorm > bignum * cnorm) {
00247 *scale = 1. / bnorm;
00248 }
00249 }
00250
00251
00252
00253 x[x_dim1 + 1] = b[b_dim1 + 1] * *scale / csr;
00254 *xnorm = (d__1 = x[x_dim1 + 1], abs(d__1));
00255 } else {
00256
00257
00258
00259
00260
00261 csr = *ca * a[a_dim1 + 1] - *wr * *d1;
00262 csi = -(*wi) * *d1;
00263 cnorm = abs(csr) + abs(csi);
00264
00265
00266
00267 if (cnorm < smini) {
00268 csr = smini;
00269 csi = 0.;
00270 cnorm = smini;
00271 *info = 1;
00272 }
00273
00274
00275
00276 bnorm = (d__1 = b[b_dim1 + 1], abs(d__1)) + (d__2 = b[(b_dim1 <<
00277 1) + 1], abs(d__2));
00278 if (cnorm < 1. && bnorm > 1.) {
00279 if (bnorm > bignum * cnorm) {
00280 *scale = 1. / bnorm;
00281 }
00282 }
00283
00284
00285
00286 d__1 = *scale * b[b_dim1 + 1];
00287 d__2 = *scale * b[(b_dim1 << 1) + 1];
00288 dladiv_(&d__1, &d__2, &csr, &csi, &x[x_dim1 + 1], &x[(x_dim1 << 1)
00289 + 1]);
00290 *xnorm = (d__1 = x[x_dim1 + 1], abs(d__1)) + (d__2 = x[(x_dim1 <<
00291 1) + 1], abs(d__2));
00292 }
00293
00294 } else {
00295
00296
00297
00298
00299
00300 cr[0] = *ca * a[a_dim1 + 1] - *wr * *d1;
00301 cr[3] = *ca * a[(a_dim1 << 1) + 2] - *wr * *d2;
00302 if (*ltrans) {
00303 cr[2] = *ca * a[a_dim1 + 2];
00304 cr[1] = *ca * a[(a_dim1 << 1) + 1];
00305 } else {
00306 cr[1] = *ca * a[a_dim1 + 2];
00307 cr[2] = *ca * a[(a_dim1 << 1) + 1];
00308 }
00309
00310 if (*nw == 1) {
00311
00312
00313
00314
00315
00316 cmax = 0.;
00317 icmax = 0;
00318
00319 for (j = 1; j <= 4; ++j) {
00320 if ((d__1 = crv[j - 1], abs(d__1)) > cmax) {
00321 cmax = (d__1 = crv[j - 1], abs(d__1));
00322 icmax = j;
00323 }
00324
00325 }
00326
00327
00328
00329 if (cmax < smini) {
00330
00331 d__3 = (d__1 = b[b_dim1 + 1], abs(d__1)), d__4 = (d__2 = b[
00332 b_dim1 + 2], abs(d__2));
00333 bnorm = max(d__3,d__4);
00334 if (smini < 1. && bnorm > 1.) {
00335 if (bnorm > bignum * smini) {
00336 *scale = 1. / bnorm;
00337 }
00338 }
00339 temp = *scale / smini;
00340 x[x_dim1 + 1] = temp * b[b_dim1 + 1];
00341 x[x_dim1 + 2] = temp * b[b_dim1 + 2];
00342 *xnorm = temp * bnorm;
00343 *info = 1;
00344 return 0;
00345 }
00346
00347
00348
00349 ur11 = crv[icmax - 1];
00350 cr21 = crv[ipivot[(icmax << 2) - 3] - 1];
00351 ur12 = crv[ipivot[(icmax << 2) - 2] - 1];
00352 cr22 = crv[ipivot[(icmax << 2) - 1] - 1];
00353 ur11r = 1. / ur11;
00354 lr21 = ur11r * cr21;
00355 ur22 = cr22 - ur12 * lr21;
00356
00357
00358
00359 if (abs(ur22) < smini) {
00360 ur22 = smini;
00361 *info = 1;
00362 }
00363 if (rswap[icmax - 1]) {
00364 br1 = b[b_dim1 + 2];
00365 br2 = b[b_dim1 + 1];
00366 } else {
00367 br1 = b[b_dim1 + 1];
00368 br2 = b[b_dim1 + 2];
00369 }
00370 br2 -= lr21 * br1;
00371
00372 d__2 = (d__1 = br1 * (ur22 * ur11r), abs(d__1)), d__3 = abs(br2);
00373 bbnd = max(d__2,d__3);
00374 if (bbnd > 1. && abs(ur22) < 1.) {
00375 if (bbnd >= bignum * abs(ur22)) {
00376 *scale = 1. / bbnd;
00377 }
00378 }
00379
00380 xr2 = br2 * *scale / ur22;
00381 xr1 = *scale * br1 * ur11r - xr2 * (ur11r * ur12);
00382 if (zswap[icmax - 1]) {
00383 x[x_dim1 + 1] = xr2;
00384 x[x_dim1 + 2] = xr1;
00385 } else {
00386 x[x_dim1 + 1] = xr1;
00387 x[x_dim1 + 2] = xr2;
00388 }
00389
00390 d__1 = abs(xr1), d__2 = abs(xr2);
00391 *xnorm = max(d__1,d__2);
00392
00393
00394
00395 if (*xnorm > 1. && cmax > 1.) {
00396 if (*xnorm > bignum / cmax) {
00397 temp = cmax / bignum;
00398 x[x_dim1 + 1] = temp * x[x_dim1 + 1];
00399 x[x_dim1 + 2] = temp * x[x_dim1 + 2];
00400 *xnorm = temp * *xnorm;
00401 *scale = temp * *scale;
00402 }
00403 }
00404 } else {
00405
00406
00407
00408
00409
00410 ci[0] = -(*wi) * *d1;
00411 ci[1] = 0.;
00412 ci[2] = 0.;
00413 ci[3] = -(*wi) * *d2;
00414 cmax = 0.;
00415 icmax = 0;
00416
00417 for (j = 1; j <= 4; ++j) {
00418 if ((d__1 = crv[j - 1], abs(d__1)) + (d__2 = civ[j - 1], abs(
00419 d__2)) > cmax) {
00420 cmax = (d__1 = crv[j - 1], abs(d__1)) + (d__2 = civ[j - 1]
00421 , abs(d__2));
00422 icmax = j;
00423 }
00424
00425 }
00426
00427
00428
00429 if (cmax < smini) {
00430
00431 d__5 = (d__1 = b[b_dim1 + 1], abs(d__1)) + (d__2 = b[(b_dim1
00432 << 1) + 1], abs(d__2)), d__6 = (d__3 = b[b_dim1 + 2],
00433 abs(d__3)) + (d__4 = b[(b_dim1 << 1) + 2], abs(d__4));
00434 bnorm = max(d__5,d__6);
00435 if (smini < 1. && bnorm > 1.) {
00436 if (bnorm > bignum * smini) {
00437 *scale = 1. / bnorm;
00438 }
00439 }
00440 temp = *scale / smini;
00441 x[x_dim1 + 1] = temp * b[b_dim1 + 1];
00442 x[x_dim1 + 2] = temp * b[b_dim1 + 2];
00443 x[(x_dim1 << 1) + 1] = temp * b[(b_dim1 << 1) + 1];
00444 x[(x_dim1 << 1) + 2] = temp * b[(b_dim1 << 1) + 2];
00445 *xnorm = temp * bnorm;
00446 *info = 1;
00447 return 0;
00448 }
00449
00450
00451
00452 ur11 = crv[icmax - 1];
00453 ui11 = civ[icmax - 1];
00454 cr21 = crv[ipivot[(icmax << 2) - 3] - 1];
00455 ci21 = civ[ipivot[(icmax << 2) - 3] - 1];
00456 ur12 = crv[ipivot[(icmax << 2) - 2] - 1];
00457 ui12 = civ[ipivot[(icmax << 2) - 2] - 1];
00458 cr22 = crv[ipivot[(icmax << 2) - 1] - 1];
00459 ci22 = civ[ipivot[(icmax << 2) - 1] - 1];
00460 if (icmax == 1 || icmax == 4) {
00461
00462
00463
00464 if (abs(ur11) > abs(ui11)) {
00465 temp = ui11 / ur11;
00466
00467 d__1 = temp;
00468 ur11r = 1. / (ur11 * (d__1 * d__1 + 1.));
00469 ui11r = -temp * ur11r;
00470 } else {
00471 temp = ur11 / ui11;
00472
00473 d__1 = temp;
00474 ui11r = -1. / (ui11 * (d__1 * d__1 + 1.));
00475 ur11r = -temp * ui11r;
00476 }
00477 lr21 = cr21 * ur11r;
00478 li21 = cr21 * ui11r;
00479 ur12s = ur12 * ur11r;
00480 ui12s = ur12 * ui11r;
00481 ur22 = cr22 - ur12 * lr21;
00482 ui22 = ci22 - ur12 * li21;
00483 } else {
00484
00485
00486
00487 ur11r = 1. / ur11;
00488 ui11r = 0.;
00489 lr21 = cr21 * ur11r;
00490 li21 = ci21 * ur11r;
00491 ur12s = ur12 * ur11r;
00492 ui12s = ui12 * ur11r;
00493 ur22 = cr22 - ur12 * lr21 + ui12 * li21;
00494 ui22 = -ur12 * li21 - ui12 * lr21;
00495 }
00496 u22abs = abs(ur22) + abs(ui22);
00497
00498
00499
00500 if (u22abs < smini) {
00501 ur22 = smini;
00502 ui22 = 0.;
00503 *info = 1;
00504 }
00505 if (rswap[icmax - 1]) {
00506 br2 = b[b_dim1 + 1];
00507 br1 = b[b_dim1 + 2];
00508 bi2 = b[(b_dim1 << 1) + 1];
00509 bi1 = b[(b_dim1 << 1) + 2];
00510 } else {
00511 br1 = b[b_dim1 + 1];
00512 br2 = b[b_dim1 + 2];
00513 bi1 = b[(b_dim1 << 1) + 1];
00514 bi2 = b[(b_dim1 << 1) + 2];
00515 }
00516 br2 = br2 - lr21 * br1 + li21 * bi1;
00517 bi2 = bi2 - li21 * br1 - lr21 * bi1;
00518
00519 d__1 = (abs(br1) + abs(bi1)) * (u22abs * (abs(ur11r) + abs(ui11r))
00520 ), d__2 = abs(br2) + abs(bi2);
00521 bbnd = max(d__1,d__2);
00522 if (bbnd > 1. && u22abs < 1.) {
00523 if (bbnd >= bignum * u22abs) {
00524 *scale = 1. / bbnd;
00525 br1 = *scale * br1;
00526 bi1 = *scale * bi1;
00527 br2 = *scale * br2;
00528 bi2 = *scale * bi2;
00529 }
00530 }
00531
00532 dladiv_(&br2, &bi2, &ur22, &ui22, &xr2, &xi2);
00533 xr1 = ur11r * br1 - ui11r * bi1 - ur12s * xr2 + ui12s * xi2;
00534 xi1 = ui11r * br1 + ur11r * bi1 - ui12s * xr2 - ur12s * xi2;
00535 if (zswap[icmax - 1]) {
00536 x[x_dim1 + 1] = xr2;
00537 x[x_dim1 + 2] = xr1;
00538 x[(x_dim1 << 1) + 1] = xi2;
00539 x[(x_dim1 << 1) + 2] = xi1;
00540 } else {
00541 x[x_dim1 + 1] = xr1;
00542 x[x_dim1 + 2] = xr2;
00543 x[(x_dim1 << 1) + 1] = xi1;
00544 x[(x_dim1 << 1) + 2] = xi2;
00545 }
00546
00547 d__1 = abs(xr1) + abs(xi1), d__2 = abs(xr2) + abs(xi2);
00548 *xnorm = max(d__1,d__2);
00549
00550
00551
00552 if (*xnorm > 1. && cmax > 1.) {
00553 if (*xnorm > bignum / cmax) {
00554 temp = cmax / bignum;
00555 x[x_dim1 + 1] = temp * x[x_dim1 + 1];
00556 x[x_dim1 + 2] = temp * x[x_dim1 + 2];
00557 x[(x_dim1 << 1) + 1] = temp * x[(x_dim1 << 1) + 1];
00558 x[(x_dim1 << 1) + 2] = temp * x[(x_dim1 << 1) + 2];
00559 *xnorm = temp * *xnorm;
00560 *scale = temp * *scale;
00561 }
00562 }
00563 }
00564 }
00565
00566 return 0;
00567
00568
00569
00570 }
00571
00572 #undef crv
00573 #undef civ
00574 #undef cr
00575 #undef ci