00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016 int slaln2_(logical *ltrans, integer *na, integer *nw, real *
00017 smin, real *ca, real *a, integer *lda, real *d1, real *d2, real *b,
00018 integer *ldb, real *wr, real *wi, real *x, integer *ldx, real *scale,
00019 real *xnorm, integer *info)
00020 {
00021
00022
00023 static logical cswap[4] = { FALSE_,FALSE_,TRUE_,TRUE_ };
00024 static logical rswap[4] = { FALSE_,TRUE_,FALSE_,TRUE_ };
00025 static integer ipivot[16] = { 1,2,3,4,2,1,4,3,3,4,1,2,
00026 4,3,2,1 };
00027
00028
00029 integer a_dim1, a_offset, b_dim1, b_offset, x_dim1, x_offset;
00030 real r__1, r__2, r__3, r__4, r__5, r__6;
00031 static real equiv_0[4], equiv_1[4];
00032
00033
00034 integer j;
00035 #define ci (equiv_0)
00036 #define cr (equiv_1)
00037 real bi1, bi2, br1, br2, xi1, xi2, xr1, xr2, ci21, ci22, cr21, cr22, li21,
00038 csi, ui11, lr21, ui12, ui22;
00039 #define civ (equiv_0)
00040 real csr, ur11, ur12, ur22;
00041 #define crv (equiv_1)
00042 real bbnd, cmax, ui11r, ui12s, temp, ur11r, ur12s, u22abs;
00043 integer icmax;
00044 real bnorm, cnorm, smini;
00045 extern doublereal slamch_(char *);
00046 real bignum;
00047 extern int sladiv_(real *, real *, real *, real *, real *
00048 , real *);
00049 real 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.f * slamch_("Safe minimum");
00210 bignum = 1.f / smlnum;
00211 smini = dmax(*smin,smlnum);
00212
00213
00214
00215 *info = 0;
00216
00217
00218
00219 *scale = 1.f;
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 = dabs(csr);
00233
00234
00235
00236 if (cnorm < smini) {
00237 csr = smini;
00238 cnorm = smini;
00239 *info = 1;
00240 }
00241
00242
00243
00244 bnorm = (r__1 = b[b_dim1 + 1], dabs(r__1));
00245 if (cnorm < 1.f && bnorm > 1.f) {
00246 if (bnorm > bignum * cnorm) {
00247 *scale = 1.f / bnorm;
00248 }
00249 }
00250
00251
00252
00253 x[x_dim1 + 1] = b[b_dim1 + 1] * *scale / csr;
00254 *xnorm = (r__1 = x[x_dim1 + 1], dabs(r__1));
00255 } else {
00256
00257
00258
00259
00260
00261 csr = *ca * a[a_dim1 + 1] - *wr * *d1;
00262 csi = -(*wi) * *d1;
00263 cnorm = dabs(csr) + dabs(csi);
00264
00265
00266
00267 if (cnorm < smini) {
00268 csr = smini;
00269 csi = 0.f;
00270 cnorm = smini;
00271 *info = 1;
00272 }
00273
00274
00275
00276 bnorm = (r__1 = b[b_dim1 + 1], dabs(r__1)) + (r__2 = b[(b_dim1 <<
00277 1) + 1], dabs(r__2));
00278 if (cnorm < 1.f && bnorm > 1.f) {
00279 if (bnorm > bignum * cnorm) {
00280 *scale = 1.f / bnorm;
00281 }
00282 }
00283
00284
00285
00286 r__1 = *scale * b[b_dim1 + 1];
00287 r__2 = *scale * b[(b_dim1 << 1) + 1];
00288 sladiv_(&r__1, &r__2, &csr, &csi, &x[x_dim1 + 1], &x[(x_dim1 << 1)
00289 + 1]);
00290 *xnorm = (r__1 = x[x_dim1 + 1], dabs(r__1)) + (r__2 = x[(x_dim1 <<
00291 1) + 1], dabs(r__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.f;
00317 icmax = 0;
00318
00319 for (j = 1; j <= 4; ++j) {
00320 if ((r__1 = crv[j - 1], dabs(r__1)) > cmax) {
00321 cmax = (r__1 = crv[j - 1], dabs(r__1));
00322 icmax = j;
00323 }
00324
00325 }
00326
00327
00328
00329 if (cmax < smini) {
00330
00331 r__3 = (r__1 = b[b_dim1 + 1], dabs(r__1)), r__4 = (r__2 = b[
00332 b_dim1 + 2], dabs(r__2));
00333 bnorm = dmax(r__3,r__4);
00334 if (smini < 1.f && bnorm > 1.f) {
00335 if (bnorm > bignum * smini) {
00336 *scale = 1.f / 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.f / ur11;
00354 lr21 = ur11r * cr21;
00355 ur22 = cr22 - ur12 * lr21;
00356
00357
00358
00359 if (dabs(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 r__2 = (r__1 = br1 * (ur22 * ur11r), dabs(r__1)), r__3 = dabs(br2)
00373 ;
00374 bbnd = dmax(r__2,r__3);
00375 if (bbnd > 1.f && dabs(ur22) < 1.f) {
00376 if (bbnd >= bignum * dabs(ur22)) {
00377 *scale = 1.f / bbnd;
00378 }
00379 }
00380
00381 xr2 = br2 * *scale / ur22;
00382 xr1 = *scale * br1 * ur11r - xr2 * (ur11r * ur12);
00383 if (cswap[icmax - 1]) {
00384 x[x_dim1 + 1] = xr2;
00385 x[x_dim1 + 2] = xr1;
00386 } else {
00387 x[x_dim1 + 1] = xr1;
00388 x[x_dim1 + 2] = xr2;
00389 }
00390
00391 r__1 = dabs(xr1), r__2 = dabs(xr2);
00392 *xnorm = dmax(r__1,r__2);
00393
00394
00395
00396 if (*xnorm > 1.f && cmax > 1.f) {
00397 if (*xnorm > bignum / cmax) {
00398 temp = cmax / bignum;
00399 x[x_dim1 + 1] = temp * x[x_dim1 + 1];
00400 x[x_dim1 + 2] = temp * x[x_dim1 + 2];
00401 *xnorm = temp * *xnorm;
00402 *scale = temp * *scale;
00403 }
00404 }
00405 } else {
00406
00407
00408
00409
00410
00411 ci[0] = -(*wi) * *d1;
00412 ci[1] = 0.f;
00413 ci[2] = 0.f;
00414 ci[3] = -(*wi) * *d2;
00415 cmax = 0.f;
00416 icmax = 0;
00417
00418 for (j = 1; j <= 4; ++j) {
00419 if ((r__1 = crv[j - 1], dabs(r__1)) + (r__2 = civ[j - 1],
00420 dabs(r__2)) > cmax) {
00421 cmax = (r__1 = crv[j - 1], dabs(r__1)) + (r__2 = civ[j -
00422 1], dabs(r__2));
00423 icmax = j;
00424 }
00425
00426 }
00427
00428
00429
00430 if (cmax < smini) {
00431
00432 r__5 = (r__1 = b[b_dim1 + 1], dabs(r__1)) + (r__2 = b[(b_dim1
00433 << 1) + 1], dabs(r__2)), r__6 = (r__3 = b[b_dim1 + 2],
00434 dabs(r__3)) + (r__4 = b[(b_dim1 << 1) + 2], dabs(
00435 r__4));
00436 bnorm = dmax(r__5,r__6);
00437 if (smini < 1.f && bnorm > 1.f) {
00438 if (bnorm > bignum * smini) {
00439 *scale = 1.f / bnorm;
00440 }
00441 }
00442 temp = *scale / smini;
00443 x[x_dim1 + 1] = temp * b[b_dim1 + 1];
00444 x[x_dim1 + 2] = temp * b[b_dim1 + 2];
00445 x[(x_dim1 << 1) + 1] = temp * b[(b_dim1 << 1) + 1];
00446 x[(x_dim1 << 1) + 2] = temp * b[(b_dim1 << 1) + 2];
00447 *xnorm = temp * bnorm;
00448 *info = 1;
00449 return 0;
00450 }
00451
00452
00453
00454 ur11 = crv[icmax - 1];
00455 ui11 = civ[icmax - 1];
00456 cr21 = crv[ipivot[(icmax << 2) - 3] - 1];
00457 ci21 = civ[ipivot[(icmax << 2) - 3] - 1];
00458 ur12 = crv[ipivot[(icmax << 2) - 2] - 1];
00459 ui12 = civ[ipivot[(icmax << 2) - 2] - 1];
00460 cr22 = crv[ipivot[(icmax << 2) - 1] - 1];
00461 ci22 = civ[ipivot[(icmax << 2) - 1] - 1];
00462 if (icmax == 1 || icmax == 4) {
00463
00464
00465
00466 if (dabs(ur11) > dabs(ui11)) {
00467 temp = ui11 / ur11;
00468
00469 r__1 = temp;
00470 ur11r = 1.f / (ur11 * (r__1 * r__1 + 1.f));
00471 ui11r = -temp * ur11r;
00472 } else {
00473 temp = ur11 / ui11;
00474
00475 r__1 = temp;
00476 ui11r = -1.f / (ui11 * (r__1 * r__1 + 1.f));
00477 ur11r = -temp * ui11r;
00478 }
00479 lr21 = cr21 * ur11r;
00480 li21 = cr21 * ui11r;
00481 ur12s = ur12 * ur11r;
00482 ui12s = ur12 * ui11r;
00483 ur22 = cr22 - ur12 * lr21;
00484 ui22 = ci22 - ur12 * li21;
00485 } else {
00486
00487
00488
00489 ur11r = 1.f / ur11;
00490 ui11r = 0.f;
00491 lr21 = cr21 * ur11r;
00492 li21 = ci21 * ur11r;
00493 ur12s = ur12 * ur11r;
00494 ui12s = ui12 * ur11r;
00495 ur22 = cr22 - ur12 * lr21 + ui12 * li21;
00496 ui22 = -ur12 * li21 - ui12 * lr21;
00497 }
00498 u22abs = dabs(ur22) + dabs(ui22);
00499
00500
00501
00502 if (u22abs < smini) {
00503 ur22 = smini;
00504 ui22 = 0.f;
00505 *info = 1;
00506 }
00507 if (rswap[icmax - 1]) {
00508 br2 = b[b_dim1 + 1];
00509 br1 = b[b_dim1 + 2];
00510 bi2 = b[(b_dim1 << 1) + 1];
00511 bi1 = b[(b_dim1 << 1) + 2];
00512 } else {
00513 br1 = b[b_dim1 + 1];
00514 br2 = b[b_dim1 + 2];
00515 bi1 = b[(b_dim1 << 1) + 1];
00516 bi2 = b[(b_dim1 << 1) + 2];
00517 }
00518 br2 = br2 - lr21 * br1 + li21 * bi1;
00519 bi2 = bi2 - li21 * br1 - lr21 * bi1;
00520
00521 r__1 = (dabs(br1) + dabs(bi1)) * (u22abs * (dabs(ur11r) + dabs(
00522 ui11r))), r__2 = dabs(br2) + dabs(bi2);
00523 bbnd = dmax(r__1,r__2);
00524 if (bbnd > 1.f && u22abs < 1.f) {
00525 if (bbnd >= bignum * u22abs) {
00526 *scale = 1.f / bbnd;
00527 br1 = *scale * br1;
00528 bi1 = *scale * bi1;
00529 br2 = *scale * br2;
00530 bi2 = *scale * bi2;
00531 }
00532 }
00533
00534 sladiv_(&br2, &bi2, &ur22, &ui22, &xr2, &xi2);
00535 xr1 = ur11r * br1 - ui11r * bi1 - ur12s * xr2 + ui12s * xi2;
00536 xi1 = ui11r * br1 + ur11r * bi1 - ui12s * xr2 - ur12s * xi2;
00537 if (cswap[icmax - 1]) {
00538 x[x_dim1 + 1] = xr2;
00539 x[x_dim1 + 2] = xr1;
00540 x[(x_dim1 << 1) + 1] = xi2;
00541 x[(x_dim1 << 1) + 2] = xi1;
00542 } else {
00543 x[x_dim1 + 1] = xr1;
00544 x[x_dim1 + 2] = xr2;
00545 x[(x_dim1 << 1) + 1] = xi1;
00546 x[(x_dim1 << 1) + 2] = xi2;
00547 }
00548
00549 r__1 = dabs(xr1) + dabs(xi1), r__2 = dabs(xr2) + dabs(xi2);
00550 *xnorm = dmax(r__1,r__2);
00551
00552
00553
00554 if (*xnorm > 1.f && cmax > 1.f) {
00555 if (*xnorm > bignum / cmax) {
00556 temp = cmax / bignum;
00557 x[x_dim1 + 1] = temp * x[x_dim1 + 1];
00558 x[x_dim1 + 2] = temp * x[x_dim1 + 2];
00559 x[(x_dim1 << 1) + 1] = temp * x[(x_dim1 << 1) + 1];
00560 x[(x_dim1 << 1) + 2] = temp * x[(x_dim1 << 1) + 2];
00561 *xnorm = temp * *xnorm;
00562 *scale = temp * *scale;
00563 }
00564 }
00565 }
00566 }
00567
00568 return 0;
00569
00570
00571
00572 }
00573
00574 #undef crv
00575 #undef civ
00576 #undef cr
00577 #undef ci