4 namespace linear_algebra {
6 using namespace fem::major_types;
38 double return_value = fem::double0;
44 double a = 4.0e0 / 3.0e0;
48 eps = fem::dabs(c - 1.0e0);
52 return_value = eps * fem::dabs(x);
101 arr_ref<double, 2>
z) {
111 double s = fem::double0;
112 double r = fem::double0;
113 double rho = fem::double0;
114 double t = fem::double0;
119 double u1 = fem::double0;
120 double u2 = fem::double0;
121 double v1 = fem::double0;
122 double v2 = fem::double0;
129 FEM_DO_SAFE ( j, 1, n ) {
130 FEM_DO_SAFE ( i, 1, n ) {
142 FEM_DO_SAFE ( l, 1, nm1 ) {
146 FEM_DO_SAFE ( i, l1, n ) {
147 s += fem::dabs(
b(i, l));
153 s += fem::dabs(
b(l, l));
156 FEM_DO_SAFE ( i, l, n ) {
157 b(i, l) =
b(i, l) /
s;
158 r += fem::pow2(
b(i, l));
161 r = fem::dsign(fem::dsqrt(r),
b(l, l));
165 FEM_DO_SAFE ( j, l1, n ) {
168 FEM_DO_SAFE ( i, l, n ) {
169 t +=
b(i, l) *
b(i, j);
174 FEM_DO_SAFE ( i, l, n ) {
175 b(i, j) += t *
b(i, l);
180 FEM_DO_SAFE ( j, 1, n ) {
183 FEM_DO_SAFE ( i, l, n ) {
184 t +=
b(i, l) *
a(i, j);
189 FEM_DO_SAFE ( i, l, n ) {
190 a(i, j) += t *
b(i, l);
197 FEM_DO_SAFE ( i, l1, n ) {
210 FEM_DO_SAFE ( k, 1, nm2 ) {
213 FEM_DO_SAFE ( lb, 1, nk1 ) {
217 s = fem::dabs(
a(l, k)) + fem::dabs(
a(l1, k));
223 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2), u1);
228 FEM_DO_SAFE ( j, k, n ) {
229 t =
a(l, j) + u2 *
a(l1, j);
236 FEM_DO_SAFE ( j, l, n ) {
237 t =
b(l, j) + u2 *
b(l1, j);
242 s = fem::dabs(
b(l1, l1)) + fem::dabs(
b(l1, l));
248 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2), u1);
253 FEM_DO_SAFE ( i, 1, l1 ) {
254 t =
b(i, l1) + u2 *
b(i, l);
261 FEM_DO_SAFE ( i, 1, n ) {
262 t =
a(i, l1) + u2 *
a(i, l);
271 FEM_DO_SAFE ( i, 1, n ) {
272 t =
z(i, l1) + u2 *
z(i, l);
347 arr_ref<double, 2>
a,
348 arr_ref<double, 2>
b,
351 arr_ref<double, 2>
z,
360 double ani = fem::double0;
361 double bni = fem::double0;
363 double ep = fem::double0;
364 double epsa = fem::double0;
365 double epsb = fem::double0;
366 int lor1 = fem::int0;
367 int enorn = fem::int0;
372 int enm2 = fem::int0;
379 double b11 = fem::double0;
380 double s = fem::double0;
381 double u1 = fem::double0;
382 double u2 = fem::double0;
383 double r = fem::double0;
384 double v1 = fem::double0;
385 double v2 = fem::double0;
386 double t = fem::double0;
387 double a11 = fem::double0;
388 double a21 = fem::double0;
389 double b22 = fem::double0;
390 double b33 = fem::double0;
391 double b44 = fem::double0;
392 double a33 = fem::double0;
393 double a34 = fem::double0;
394 double a43 = fem::double0;
395 double a44 = fem::double0;
396 double b34 = fem::double0;
397 double sh = fem::double0;
398 double a1 = fem::double0;
399 double a2 = fem::double0;
400 double a12 = fem::double0;
401 double a22 = fem::double0;
402 double b12 = fem::double0;
403 double a3 = fem::double0;
405 bool notlas = fem::bool0;
409 double u3 = fem::double0;
410 double v3 = fem::double0;
414 double anorm = 0.0e0;
415 double bnorm = 0.0e0;
417 FEM_DO_SAFE ( i, 1, n ) {
420 ani = fem::dabs(
a(i, i - 1));
424 FEM_DO_SAFE ( j, i, n ) {
425 ani += fem::dabs(
a(i, j));
426 bni += fem::dabs(
b(i, j));
437 if ( anorm == 0.0e0 ) {
440 if ( bnorm == 0.0e0 ) {
473 FEM_DO_SAFE ( ll, 1, en ) {
479 if ( fem::dabs(
a(l, lm1)) <= epsa ) {
498 if ( fem::dabs(b11) > epsb ) {
502 s = fem::dabs(
a(l, l)) + fem::dabs(
a(l1, l));
505 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2), u1);
510 FEM_DO_SAFE ( j, l, enorn ) {
511 t =
a(l, j) + u2 *
a(l1, j);
514 t =
b(l, j) + u2 *
b(l1, j);
520 a(l, lm1) = -
a(l, lm1);
527 a21 =
a(l1, l) / b11;
540 if ( fem::dabs(b22) < epsb ) {
544 if ( fem::dabs(b33) < epsb ) {
548 if ( fem::dabs(b44) < epsb ) {
551 a33 =
a(na, na) / b33;
552 a34 =
a(na, en) / b44;
553 a43 =
a(en, na) / b33;
554 a44 =
a(en, en) / b44;
555 b34 =
b(na, en) / b44;
556 t = 0.5e0 * (a43 * b34 - a33 - a44);
557 r = t * t + a34 * a43 - a33 * a44;
566 if ( fem::dabs(s - a44) < fem::dabs(sh - a44) ) {
572 FEM_DO_SAFE ( ll, ld, enm2 ) {
580 if ( fem::dabs(
b(l, l)) > epsb ) {
581 t = t - sh *
b(l, l);
583 if ( fem::dabs(
a(l, lm1)) <= fem::dabs(t /
a(l1, l)) * epsa ) {
592 a(l, lm1) = -
a(l, lm1);
597 a12 =
a(l, l1) / b22;
598 a22 =
a(l1, l1) / b22;
599 b12 =
b(l, l1) / b22;
600 a1 = ((a33 - a11) * (a44 - a11) - a34 * a43 + a43 * b34 * a11) /
601 a21 + a12 - a11 * b12;
602 a2 = (a22 - a11) - a21 * b12 - (a33 - a11) - (a44 - a11) + a43 * b34;
603 a3 =
a(l1 + 1, l1) / b22;
617 FEM_DO_SAFE ( k, l, na ) {
618 notlas = k != na && ish == 2;
621 km1 = fem::max0(k - 1, l);
622 ll = fem::min0(en, k1 + ish);
633 s = fem::dabs(a1) + fem::dabs(a2);
639 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2), u1);
644 FEM_DO_SAFE ( j, km1, enorn ) {
645 t =
a(k, j) + u2 *
a(k1, j);
648 t =
b(k, j) + u2 *
b(k1, j);
666 s = fem::dabs(a1) + fem::dabs(a2) + fem::dabs(a3);
673 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2 + u3 * u3), u1);
680 FEM_DO_SAFE ( j, km1, enorn ) {
681 t =
a(k, j) + u2 *
a(k1, j) + u3 *
a(k2, j);
685 t =
b(k, j) + u2 *
b(k1, j) + u3 *
b(k2, j);
698 s = fem::dabs(
b(k2, k2)) + fem::dabs(
b(k2, k1)) + fem::dabs(
b(k2, k));
705 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2 + u3 * u3), u1);
712 FEM_DO_SAFE ( i, lor1, ll ) {
713 t =
a(i, k2) + u2 *
a(i, k1) + u3 *
a(i, k);
717 t =
b(i, k2) + u2 *
b(i, k1) + u3 *
b(i, k);
729 FEM_DO_SAFE ( i, 1, n ) {
730 t =
z(i, k2) + u2 *
z(i, k1) + u3 *
z(i, k);
737 s = fem::dabs(
b(k1, k1)) + fem::dabs(
b(k1, k));
743 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2), u1);
748 FEM_DO_SAFE ( i, lor1, ll ) {
749 t =
a(i, k1) + u2 *
a(i, k);
752 t =
b(i, k1) + u2 *
b(i, k);
762 FEM_DO_SAFE ( i, 1, n ) {
763 t =
z(i, k1) + u2 *
z(i, k);
846 arr_ref<double, 2>
a,
847 arr_ref<double, 2>
b,
848 arr_ref<double> alfr,
849 arr_ref<double> alfi,
850 arr_ref<double> beta,
852 arr_ref<double, 2>
z) {
865 double a1 = fem::double0;
866 double a2 = fem::double0;
867 double bn = fem::double0;
868 double an = fem::double0;
869 double a11 = fem::double0;
870 double a12 = fem::double0;
871 double a21 = fem::double0;
872 double a22 = fem::double0;
873 double b11 = fem::double0;
874 double b12 = fem::double0;
875 double b22 = fem::double0;
876 double e = fem::double0;
877 double ei = fem::double0;
878 double s = fem::double0;
879 double t = fem::double0;
880 double c = fem::double0;
881 double d = fem::double0;
882 double u1 = fem::double0;
883 double u2 = fem::double0;
884 double r = fem::double0;
885 double v1 = fem::double0;
886 double v2 = fem::double0;
889 double a11r = fem::double0;
890 double a11i = fem::double0;
891 double a12r = fem::double0;
892 double a12i = fem::double0;
893 double a22r = fem::double0;
894 double a22i = fem::double0;
895 double a1i = fem::double0;
896 double a2i = fem::double0;
897 double cz = fem::double0;
898 double szr = fem::double0;
899 double szi = fem::double0;
900 double cq = fem::double0;
901 double sqr = fem::double0;
902 double sqi = fem::double0;
903 double ssr = fem::double0;
904 double ssi = fem::double0;
905 double tr = fem::double0;
906 double ti = fem::double0;
907 double dr = fem::double0;
908 double di = fem::double0;
910 double epsb =
b(n, 1);
914 FEM_DO_SAFE ( nn, 1, n ) {
923 if (
a(en, na) != 0.0e0 ) {
928 alfr(en) =
a(en, en);
929 if (
b(en, en) < 0.0e0 ) {
930 alfr(en) = -alfr(en);
932 beta(en) = fem::dabs(
b(en, en));
937 if ( fem::dabs(
b(na, na)) <= epsb ) {
940 if ( fem::dabs(
b(en, en)) > epsb ) {
948 an = fem::dabs(
a(na, na)) + fem::dabs(
a(na, en)) + fem::dabs(
a(en,
949 na)) + fem::dabs(
a(en, en));
950 bn = fem::dabs(
b(na, na)) + fem::dabs(
b(na, en)) + fem::dabs(
b(en, en));
951 a11 =
a(na, na) / an;
952 a12 =
a(na, en) / an;
953 a21 =
a(en, na) / an;
954 a22 =
a(en, en) / an;
955 b11 =
b(na, na) / bn;
956 b12 =
b(na, en) / bn;
957 b22 =
b(en, en) / bn;
960 s = a21 / (b11 * b22);
961 t = (a22 - e * b22) / b22;
962 if ( fem::dabs(e) <= fem::dabs(ei) ) {
966 t = (a11 - e * b11) / b11;
968 c = 0.5e0 * (t - s * b12);
969 d = c * c + s * (a12 - e * b12);
975 e += (c + fem::dsign(fem::dsqrt(d), c));
979 if ( fem::dabs(a11) + fem::dabs(a12) < fem::dabs(a21) + fem::dabs(a22) ) {
990 s = fem::dabs(a1) + fem::dabs(a2);
993 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2), u1);
998 FEM_DO_SAFE ( i, 1, en ) {
999 t =
a(i, en) + u2 *
a(i, na);
1002 t =
b(i, en) + u2 *
b(i, na);
1011 FEM_DO_SAFE ( i, 1, n ) {
1012 t =
z(i, en) + u2 *
z(i, na);
1018 if ( bn == 0.0e0 ) {
1021 if ( an < fem::dabs(e) * bn ) {
1032 s = fem::dabs(a1) + fem::dabs(a2);
1038 r = fem::dsign(fem::dsqrt(u1 * u1 + u2 * u2), u1);
1043 FEM_DO_SAFE ( j, na, n ) {
1044 t =
a(na, j) + u2 *
a(en, j);
1047 t =
b(na, j) + u2 *
b(en, j);
1055 alfr(na) =
a(na, na);
1056 alfr(en) =
a(en, en);
1057 if (
b(na, na) < 0.0e0 ) {
1058 alfr(na) = -alfr(na);
1060 if (
b(en, en) < 0.0e0 ) {
1061 alfr(en) = -alfr(en);
1063 beta(na) = fem::dabs(
b(na, na));
1064 beta(en) = fem::dabs(
b(en, en));
1071 ei = fem::dsqrt(-d);
1072 a11r = a11 - e * b11;
1074 a12r = a12 - e * b12;
1076 a22r = a22 - e * b22;
1078 if ( fem::dabs(a11r) + fem::dabs(a11i) + fem::dabs(a12r) +
1079 fem::dabs(a12i) < fem::dabs(a21) + fem::dabs(a22r) +
1095 cz = fem::dsqrt(a1 * a1 + a1i * a1i);
1096 if ( cz == 0.0e0 ) {
1099 szr = (a1 * a2 + a1i * a2i) / cz;
1100 szi = (a1 * a2i - a1i *
a2) / cz;
1101 r = fem::dsqrt(cz * cz + szr * szr + szi * szi);
1110 if ( an < (fem::dabs(e) + ei) * bn ) {
1113 a1 = cz * b11 + szr * b12;
1119 a1 = cz * a11 + szr * a12;
1121 a2 = cz * a21 + szr * a22;
1125 cq = fem::dsqrt(a1 * a1 + a1i * a1i);
1126 if ( cq == 0.0e0 ) {
1129 sqr = (a1 * a2 + a1i * a2i) / cq;
1130 sqi = (a1 * a2i - a1i *
a2) / cq;
1131 r = fem::dsqrt(cq * cq + sqr * sqr + sqi * sqi);
1142 ssr = sqr * szr + sqi * szi;
1143 ssi = sqr * szi - sqi * szr;
1145 tr = cq * cz * a11 + cq * szr * a12 + sqr * cz * a21 + ssr * a22;
1146 ti = cq * szi * a12 - sqi * cz * a21 + ssi * a22;
1147 dr = cq * cz * b11 + cq * szr * b12 + ssr * b22;
1148 di = cq * szi * b12 + ssi * b22;
1152 tr = ssr * a11 - sqr * cz * a12 - cq * szr * a21 + cq * cz * a22;
1153 ti = -ssi * a11 - sqi * cz * a12 + cq * szi * a21;
1154 dr = ssr * b11 - sqr * cz * b12 + cq * cz * b22;
1155 di = -ssi * b11 - sqi * cz * b12;
1157 t = ti * dr - tr * di;
1162 r = fem::dsqrt(dr * dr + di * di);
1164 alfr(j) = an * (tr * dr + ti * di) / r;
1165 alfi(j) = an * t / r;
1235 arr_cref<double, 2>
a,
1236 arr_ref<double, 2>
b,
1237 arr_cref<double> alfr,
1238 arr_cref<double> alfi,
1239 arr_cref<double> beta,
1240 arr_ref<double, 2>
z) {
1242 a(dimension(nm, n));
1243 b(dimension(nm, n));
1247 z(dimension(nm, n));
1254 double alfm = fem::double0;
1255 double betm = fem::double0;
1258 double w = fem::double0;
1259 double r = fem::double0;
1261 double zz = fem::double0;
1262 double s = fem::double0;
1263 double t = fem::double0;
1264 double x = fem::double0;
1265 double y = fem::double0;
1266 double q = fem::double0;
1267 double almr = fem::double0;
1268 double almi = fem::double0;
1269 int enm2 = fem::int0;
1270 double w1 = fem::double0;
1271 double ra = fem::double0;
1272 double sa = fem::double0;
1273 double x1 = fem::double0;
1274 double z1 = fem::double0;
1275 double tr = fem::double0;
1276 double ti = fem::double0;
1277 double dr = fem::double0;
1278 double di = fem::double0;
1279 double rr = fem::double0;
1280 double d = fem::double0;
1281 double t1 = fem::double0;
1282 double t2 = fem::double0;
1286 double epsb =
b(n, 1);
1289 FEM_DO_SAFE ( nn, 1, n ) {
1295 if ( alfi(en) != 0.0e0 ) {
1307 FEM_DO_SAFE ( ii, 1, na ) {
1309 w = betm *
a(i, i) - alfm *
b(i, i);
1312 FEM_DO_SAFE ( j, m, en ) {
1313 r += (betm *
a(i, j) - alfm *
b(i, j)) *
b(j, en);
1316 if ( i == 1 || isw == 2 ) {
1319 if ( betm *
a(i, i - 1) == 0.0e0 ) {
1339 x = betm *
a(i, i + 1) - alfm *
b(i, i + 1);
1340 y = betm *
a(i + 1, i);
1342 t = (x * s - zz * r) / q;
1344 if ( fem::dabs(x) <= fem::dabs(zz) ) {
1347 b(i + 1, en) = (-r - w * t) / x;
1350 b(i + 1, en) = (-s - y * t) / zz;
1365 y = betm *
a(en, na);
1366 b(na, na) = -almi *
b(en, en) /
y;
1367 b(na, en) = (almr *
b(en, en) - betm *
a(en, en)) / y;
1375 FEM_DO_SAFE ( ii, 1, enm2 ) {
1377 w = betm *
a(i, i) - almr *
b(i, i);
1378 w1 = -almi *
b(i, i);
1382 FEM_DO_SAFE ( j, m, en ) {
1383 x = betm *
a(i, j) - almr *
b(i, j);
1384 x1 = -almi *
b(i, j);
1385 ra += x *
b(j, na) - x1 *
b(j, en);
1386 sa += x *
b(j, en) + x1 *
b(j, na);
1389 if ( i == 1 || isw == 2 ) {
1392 if ( betm *
a(i, i - 1) == 0.0e0 ) {
1414 if ( fem::dabs(di) > fem::dabs(dr) ) {
1419 t1 = (tr + ti * rr) / d;
1420 t2 = (ti - tr * rr) / d;
1422 case 1 :
goto statement_787;
1423 case 2 :
goto statement_782;
1429 t1 = (tr * rr + ti) / d;
1430 t2 = (ti * rr -
tr) / d;
1432 case 1 :
goto statement_787;
1433 case 2 :
goto statement_782;
1438 x = betm *
a(i, i + 1) - almr *
b(i, i + 1);
1439 x1 = -almi *
b(i, i + 1);
1440 y = betm *
a(i + 1, i);
1441 tr = y * ra - w * r + w1 *
s;
1442 ti = y * sa - w * s - w1 * r;
1443 dr = w * zz - w1 * z1 - x *
y;
1444 di = w * z1 + w1 * zz - x1 *
y;
1445 if ( dr == 0.0e0 && di == 0.0e0 ) {
1453 if ( fem::dabs(y) > fem::dabs(w) + fem::dabs(w1) ) {
1456 tr = -ra - x *
b(i + 1, na) + x1 *
b(i + 1, en);
1457 ti = -sa - x *
b(i + 1, en) - x1 *
b(i + 1, na);
1460 t1 = (-r - zz *
b(i + 1, na) + z1 *
b(i + 1, en)) / y;
1461 t2 = (-s - zz *
b(i + 1, en) - z1 *
b(i + 1, na)) / y;
1475 FEM_DO_SAFE ( jj, 1, n ) {
1478 FEM_DO_SAFE ( i, 1, n ) {
1481 FEM_DO_SAFE ( k, 1, j ) {
1482 zz +=
z(i, k) *
b(k, j);
1491 FEM_DO_SAFE ( j, 1, n ) {
1496 if ( alfi(j) != 0.0e0 ) {
1500 FEM_DO_SAFE ( i, 1, n ) {
1501 if ( fem::dabs(
z(i, j)) > d ) {
1502 d = fem::dabs(
z(i, j));
1506 FEM_DO_SAFE ( i, 1, n ) {
1507 z(i, j) =
z(i, j) / d;
1513 FEM_DO_SAFE ( i, 1, n ) {
1514 r = fem::dabs(
z(i, j - 1)) + fem::dabs(
z(i, j));
1516 r = r * fem::dsqrt(fem::pow2((
z(i, j - 1) / r)) + fem::pow2((
z(i,
1524 FEM_DO_SAFE ( i, 1, n ) {
1525 z(i, j - 1) =
z(i, j - 1) / d;
1526 z(i, j) =
z(i, j) / d;
1584 arr_ref<double, 2>
a,
1585 arr_ref<double, 2>
b,
1586 arr_ref<double> alfr,
1587 arr_ref<double> alfi,
1588 arr_ref<double> beta,
1590 arr_ref<double, 2>
z,
1593 a(dimension(nm, n));
1594 b(dimension(nm, n));
1598 z(dimension(nm, n));
1599 bool tf = fem::bool0;
1613 qzhes(nm, n, a, b, tf, z);
1614 qzit(nm, n, a, b, 0.0e0, tf, z, ierr);
1615 qzval(nm, n, a, b, alfr, alfi, beta, tf, z);
1620 qzhes(nm, n, a, b, tf, z);
1621 qzit(nm, n, a, b, 0.0e0, tf, z, ierr);
1622 qzval(nm, n, a, b, alfr, alfi, beta, tf, z);
1626 qzvec(nm, n, a, b, alfr, alfi, beta, z);
Header file for the EISPACK rgg routine.
cmplx w(cmplx z, double relerr)
void qzhes(int const &nm, int const &n, arr_ref< double, 2 > a, arr_ref< double, 2 > b, bool const &matz, arr_ref< double, 2 > z)
This subroutine is the first step of the QZ algorithm for solving generalized matrix eigenvalue probl...
void qzval(int const &nm, int const &n, arr_ref< double, 2 > a, arr_ref< double, 2 > b, arr_ref< double > alfr, arr_ref< double > alfi, arr_ref< double > beta, bool const &matz, arr_ref< double, 2 > z)
This subroutine is the third step of the QZ algorithm for solving generalized matrix eigenvalue probl...
void qzit(int const &nm, int const &n, arr_ref< double, 2 > a, arr_ref< double, 2 > b, double const &eps1, bool const &matz, arr_ref< double, 2 > z, int &ierr)
This subroutine is the second step of the QZ algorithm for solving generalized matrix eigenvalue prob...
void qzvec(int const &nm, int const &n, arr_cref< double, 2 > a, arr_ref< double, 2 > b, arr_cref< double > alfr, arr_cref< double > alfi, arr_cref< double > beta, arr_ref< double, 2 > z)
This subroutine is the optional fourth step of the QZ algorithm for solving generalized matrix eigenv...
THREAD_LOCAL basic::Tracer tr("struc_set_fragment_picker")
double epslon(double const &x)
Estimate unit roundoff in quantities of size x.
void rgg(int const &nm, int const &n, arr_ref< double, 2 > a, arr_ref< double, 2 > b, arr_ref< double > alfr, arr_ref< double > alfi, arr_ref< double > beta, int const &matz, arr_ref< double, 2 > z, int &ierr)
This subroutine calls the recommended sequence of subroutines from the eigensystem subroutine package...