47 #define Swap(type,a,b) { type t; t = a; a = b; b = t; }
52 template <
class nr_type_t>
66 template <
class nr_type_t>
68 if (
R != NULL)
delete R;
69 if (
T != NULL)
delete T;
70 if (
B != NULL)
delete B;
71 if (
S != NULL)
delete S;
72 if (
E != NULL)
delete E;
73 if (
V != NULL)
delete V;
74 if (rMap != NULL)
delete[] rMap;
75 if (cMap != NULL)
delete[] cMap;
76 if (nPvt != NULL)
delete[] nPvt;
81 template <
class nr_type_t>
100 template <
class nr_type_t>
107 if (
N !=
A->getCols ()) {
109 if (cMap)
delete[] cMap; cMap =
new int[
N];
110 if (rMap)
delete[] rMap; rMap =
new int[
N];
111 if (nPvt)
delete[] nPvt; nPvt =
new nr_double_t[
N];
117 if (
B != NULL)
delete B;
125 template <
class nr_type_t>
128 time_t
t = time (NULL);
138 solve_gauss_jordan ();
144 solve_lu_doolittle ();
147 factorize_lu_crout ();
150 factorize_lu_doolittle ();
153 substitute_lu_crout ();
156 substitute_lu_doolittle ();
179 A->getRows (),
A->getCols (), time (NULL) -
t);
184 template <
class nr_type_t>
195 template <
class nr_type_t>
197 nr_double_t MaxPivot;
202 for (i = 0; i <
N; i++) {
204 for (MaxPivot = 0, pivot = r = i; r <
N; r++) {
205 if (
abs (
A_(r, i)) > MaxPivot) {
206 MaxPivot =
abs (
A_(r, i));
211 assert (MaxPivot != 0);
213 A->exchangeRows (i, pivot);
214 B->exchangeRows (i, pivot);
217 for (r = i + 1; r <
N; r++) {
218 f =
A_(r, i) /
A_(i, i);
219 for (c = i + 1; c <
N; c++)
A_(r, c) -= f *
A_(i, c);
225 for (i = N - 1; i >= 0; i--) {
227 for (c = i + 1; c <
N; c++) f -=
A_(i, c) *
X_(c);
228 X_(i) = f /
A_(i, i);
235 template <
class nr_type_t>
237 nr_double_t MaxPivot;
242 for (i = 0; i <
N; i++) {
244 for (MaxPivot = 0, pivot = r = i; r <
N; r++) {
245 if (
abs (
A_(r, i)) > MaxPivot) {
246 MaxPivot =
abs (
A_(r, i));
251 assert (MaxPivot != 0);
253 A->exchangeRows (i, pivot);
254 B->exchangeRows (i, pivot);
259 for (c = i + 1; c <
N; c++)
A_(i, c) /= f;
263 for (r = 0; r <
N; r++) {
266 for (c = i + 1; c <
N; c++)
A_(r, c) -= f *
A_(i, c);
277 #define VIRTUAL_RES(txt,i) { \
278 qucs::exception * e = new qucs::exception (EXCEPTION_SINGULAR); \
280 e->setData (rMap[i]); \
281 A_(i, i) = NR_TINY; \
282 throw_exception (e); }
289 template <
class nr_type_t>
295 factorize_lu_crout ();
299 substitute_lu_crout ();
303 template <
class nr_type_t>
309 factorize_lu_doolittle ();
313 substitute_lu_doolittle ();
320 template <
class nr_type_t>
322 nr_double_t d, MaxPivot;
327 for (r = 0; r <
N; r++) {
328 for (MaxPivot = 0, c = 0; c <
N; c++)
329 if ((d =
abs (
A_(r, c))) > MaxPivot)
331 if (MaxPivot <= 0) MaxPivot = NR_TINY;
332 nPvt[r] = 1 / MaxPivot;
337 for (c = 0; c <
N; c++) {
339 for (r = 0; r <
c; r++) {
341 for (k = 0; k < r; k++) f -=
A_(r, k) *
A_(k, c);
342 A_(r, c) = f /
A_(r, r);
345 for (MaxPivot = 0, pivot = r; r <
N; r++) {
347 for (k = 0; k <
c; k++) f -=
A_(r, k) *
A_(k, c);
350 if ((d = nPvt[r] *
abs (f)) > MaxPivot) {
360 e->
setText (
"no pivot != 0 found during Crout LU decomposition");
365 VIRTUAL_RES (
"no pivot != 0 found during Crout LU decomposition", c);
372 A->exchangeRows (c, pivot);
373 Swap (
int, rMap[c], rMap[pivot]);
374 Swap (nr_double_t, nPvt[c], nPvt[pivot]);
386 template <
class nr_type_t>
388 nr_double_t d, MaxPivot;
393 for (r = 0; r <
N; r++) {
394 for (MaxPivot = 0, c = 0; c <
N; c++)
395 if ((d =
abs (
A_(r, c))) > MaxPivot)
397 if (MaxPivot <= 0) MaxPivot = NR_TINY;
398 nPvt[r] = 1 / MaxPivot;
403 for (c = 0; c <
N; c++) {
405 for (r = 0; r <
c; r++) {
407 for (k = 0; k < r; k++) f -=
A_(r, k) *
A_(k, c);
411 for (MaxPivot = 0, pivot = r; r <
N; r++) {
413 for (k = 0; k <
c; k++) f -=
A_(r, k) *
A_(k, c);
416 if ((d = nPvt[r] *
abs (f)) > MaxPivot) {
426 e->
setText (
"no pivot != 0 found during Doolittle LU decomposition");
431 VIRTUAL_RES (
"no pivot != 0 found during Doolittle LU decomposition", c);
438 A->exchangeRows (c, pivot);
439 Swap (
int, rMap[c], rMap[pivot]);
440 Swap (nr_double_t, nPvt[c], nPvt[pivot]);
446 for (r = c + 1; r <
N; r++)
A_(r, c) *= f;
457 template <
class nr_type_t>
463 for (i = 0; i <
N; i++) {
465 for (c = 0; c <
i; c++) f -=
A_(i, c) *
X_(c);
466 X_(i) = f /
A_(i, i);
470 for (i = N - 1; i >= 0; i--) {
472 for (c = i + 1; c <
N; c++) f -=
A_(i, c) *
X_(c);
482 template <
class nr_type_t>
488 for (i = 0; i <
N; i++) {
490 for (c = 0; c <
i; c++) f -=
A_(i, c) *
X_(c);
496 for (i = N - 1; i >= 0; i--) {
498 for (c = i + 1; c <
N; c++) f -=
A_(i, c) *
X_(c);
499 X_(i) = f /
A_(i, i);
510 template <
class nr_type_t>
515 nr_double_t reltol = 1e-4;
516 nr_double_t abstol = NR_TINY;
517 nr_double_t
diff, crit;
526 if ((crit = convergence_criteria ()) >= 1) {
536 for (r = 0; r <
N; r++) {
539 for (c = 0; c <
N; c++)
A_(r, c) /= f;
550 for (r = 0; r <
N; r++) {
551 for (f = 0, c = 0; c <
N; c++) {
554 if (c < r) f +=
A_(r, c) *
X_(c);
555 else if (c > r) f +=
A_(r, c) * Xprev->
get (c);
559 if (c != r) f +=
A_(r, c) * Xprev->
get (c);
565 for (conv = 1, r = 0; r <
N; r++) {
566 diff =
abs (
X_(r) - Xprev->
get (r));
567 if (diff >= abstol + reltol *
abs (
X_(r))) {
571 if (!finite (diff)) { error++;
break; }
576 while (++i < MaxIter && !conv);
580 if (!conv || error) {
582 "WARNING: no convergence after %d %s iterations\n",
583 i, algo ==
ALGO_JACOBI ?
"jacobi" :
"gauss-seidel");
589 "NOTIFY: %s convergence after %d iterations\n",
590 algo ==
ALGO_JACOBI ?
"jacobi" :
"gauss-seidel", i);
599 template <
class nr_type_t>
604 nr_double_t reltol = 1e-4;
605 nr_double_t abstol = NR_TINY;
606 nr_double_t
diff, crit, l = 1, d,
s;
615 if ((crit = convergence_criteria ()) >= 1) {
625 for (r = 0; r <
N; r++) {
628 for (c = 0; c <
N; c++)
A_(r, c) /= f;
639 for (r = 0; r <
N; r++) {
640 for (f = 0, c = 0; c <
N; c++) {
641 if (c < r) f +=
A_(r, c) *
X_(c);
642 else if (c > r) f +=
A_(r, c) * Xprev->
get (c);
644 X_(r) = (1 - l) * Xprev->
get (r) + l * (
B_(r) - f);
647 for (s = 0, d = 0, conv = 1, r = 0; r <
N; r++) {
648 diff =
abs (
X_(r) - Xprev->
get (r));
649 if (diff >= abstol + reltol *
abs (
X_(r))) {
654 if (!finite (diff)) { error++;
break; }
658 if ((s == 0 && d == 0) || d >= abstol * N + reltol * s) {
660 if (l >= 0.6) l -= 0.1;
661 if (l >= 1.0) l = 1.0;
665 if (l < 1.5) l += 0.01;
666 if (l < 1.0) l = 1.0;
672 while (++i < MaxIter && !conv);
676 if (!conv || error) {
678 "WARNING: no convergence after %d sor iterations (l = %g)\n",
685 "NOTIFY: sor convergence after %d iterations\n", i);
693 template <
class nr_type_t>
696 for (
int r = 0; r <
A->getCols (); r++) {
697 for (
int c = 0; c <
A->getCols (); c++) {
698 if (r != c) f +=
norm (
A_(r, c) /
A_(r, r));
707 template <
class nr_type_t>
709 ensure_diagonal_MNA ();
718 template <
class nr_type_t>
720 int restart, exchanged, begin = 0,
pairs;
721 int pivot1, pivot2,
i;
723 restart = exchanged = 0;
725 for (i = begin; i <
N; i++) {
727 pairs = countPairs (i, pivot1, pivot2);
729 A->exchangeRows (i, pivot1);
730 B->exchangeRows (i, pivot1);
733 else if ((
pairs > 1) && !restart) {
742 for (i = begin; !exchanged && i <
N; i++) {
744 pairs = countPairs (i, pivot1, pivot2);
745 A->exchangeRows (i, pivot1);
746 B->exchangeRows (i, pivot1);
757 template <
class nr_type_t>
760 for (
int r = 0; r <
N; r++) {
761 if (fabs (
real (
A_(r, i))) == 1.0) {
764 for (r++; r <
N; r++) {
765 if (fabs (
real (
A_(r, i))) == 1.0) {
767 if (++pairs >= 2)
return pairs;
778 template <
class nr_type_t>
781 nr_double_t MaxPivot;
782 for (
int i = 0; i <
N; i++) {
784 for (MaxPivot = 0, pivot = i, r = 0; r <
N; r++) {
785 if (
abs (
A_(r, i)) > MaxPivot &&
787 MaxPivot =
abs (
A_(r, i));
793 A->exchangeRows (i, pivot);
794 B->exchangeRows (i, pivot);
804 template <
class nr_type_t>
812 template <
class nr_type_t>
814 factorize_qr_householder ();
815 substitute_qr_householder ();
821 template <
class nr_type_t>
824 factorize_qr_householder ();
825 substitute_qr_householder_ls ();
830 euclidian_update (nr_double_t a, nr_double_t&
n, nr_double_t& scale) {
848 template <
class nr_type_t>
850 nr_double_t scale = 0, n = 1;
851 for (
int i = r; i <
N; i++) {
852 euclidian_update (
real (
A_(i, c)), n, scale);
853 euclidian_update (
imag (
A_(i, c)), n, scale);
855 return scale *
sqrt (n);
860 template <
class nr_type_t>
862 nr_double_t scale = 0, n = 1;
863 for (
int i = c; i <
N; i++) {
864 euclidian_update (
real (
A_(r, i)), n, scale);
865 euclidian_update (
imag (
A_(r, i)), n, scale);
867 return scale *
sqrt (n);
875 template <
class nr_type_t>
879 nr_double_t
s, MaxPivot;
883 for (c = 0; c <
N; c++) {
885 nPvt[
c] = euclidian_c (c);
889 for (c = 0; c <
N; c++) {
892 MaxPivot = nPvt[
c]; pivot =
c;
893 for (r = c + 1; r <
N; r++) {
894 if ((s = nPvt[r]) > MaxPivot) {
900 A->exchangeCols (pivot, c);
901 Swap (
int, cMap[pivot], cMap[c]);
902 Swap (nr_double_t, nPvt[pivot], nPvt[c]);
908 s = euclidian_c (c, c + 1);
914 A_(c, c) = (a -
b) / t;
915 for (r = c + 1; r <
N; r++)
A_(r, c) /=
t;
922 for (r = c + 1; r <
N; r++) {
923 for (f = 0, k = c; k <
N; k++) f +=
conj (
A_(k, c)) *
A_(k, r);
924 for (k = c; k <
N; k++)
A_(k, r) -= 2.0 * f *
A_(k, c);
928 for (r = c + 1; r <
N; r++) {
929 nPvt[r] = euclidian_c (r, c + 1);
940 template <
class nr_type_t>
943 nr_double_t
s, MaxPivot;
947 for (c = 0; c <
N; c++) {
949 nPvt[
c] = euclidian_c (c);
953 for (c = 0; c <
N; c++) {
956 MaxPivot = nPvt[
c]; pivot =
c;
957 for (r = c + 1; r <
N; r++)
958 if ((s = nPvt[r]) > MaxPivot) {
963 A->exchangeCols (pivot, c);
964 Swap (
int, cMap[pivot], cMap[c]);
965 Swap (nr_double_t, nPvt[pivot], nPvt[c]);
969 T_(c) = householder_left (c);
972 for (r = c + 1; r <
N; r++) {
973 if ((s = nPvt[r]) > 0) {
975 nr_double_t t =
norm (
A_(c, r) / s);
977 y = s *
sqrt (1 - t);
978 if (fabs (y / s) < NR_TINY)
979 nPvt[r] = euclidian_c (r, c + 1);
989 template <
class nr_type_t>
995 for (c = 0; c < N - 1; c++) {
997 for (f = 0, r = c; r <
N; r++) f +=
conj (
A_(r, c)) *
B_(r);
999 for (r = c; r <
N; r++)
B_(r) -= 2.0 * f *
A_(r, c);
1003 for (r = N - 1; r >= 0; r--) {
1005 for (c = r + 1; c <
N; c++) f -=
A_(r, c) *
X_(cMap[c]);
1007 X_(cMap[r]) = f /
R_(r);
1015 template <
class nr_type_t>
1021 for (c = 0; c <
N; c++) {
1024 for (f =
B_(c), r = c + 1; r <
N; r++) f +=
conj (
A_(r, c)) *
B_(r);
1027 for (r = c + 1; r <
N; r++)
B_(r) -= f *
A_(r, c);
1032 for (r = N - 1; r >= 0; r--) {
1033 for (f =
B_(r), c = r + 1; c <
N; c++) f -=
A_(r, c) *
X_(cMap[c]);
1035 X_(cMap[r]) = f /
A_(r, r);
1045 template <
class nr_type_t>
1051 for (r = 0; r <
N; r++) {
1052 for (f =
B_(r), c = 0; c < r; c++) f -=
A_(c, r) *
B_(c);
1054 B_(r) = f /
A_(r, r);
1060 for (c = N - 1; c >= 0; c--) {
1063 for (f =
B_(c), r = c + 1; r <
N; r++) f +=
conj (
A_(r, c)) *
B_(r);
1065 f *=
T_(c);
B_(c) -= f;
1066 for (r = c + 1; r <
N; r++)
B_(r) -= f *
A_(r, c);
1071 for (r = 0; r <
N; r++)
X_(cMap[r]) =
B_(r);
1074 #define sign_(a) (real (a) < 0 ? -1 : 1)
1082 template <
class nr_type_t>
1086 s = euclidian_c (c, c + 1);
1087 if (s == 0 &&
imag (
A_(c, c)) == 0) {
1098 for (
int r = c + 1; r <
N; r++)
A_(r, c) /=
b;
1108 template <
class nr_type_t>
1111 nr_type_t t = householder_create_left (c);
1114 householder_apply_left (c, t);
1123 template <
class nr_type_t>
1126 nr_type_t t = householder_create_right (r);
1129 householder_apply_right (r, t);
1140 template <
class nr_type_t>
1144 s = euclidian_r (r, r + 2);
1145 if (s == 0 &&
imag (
A_(r, r + 1)) == 0) {
1156 for (
int c = r + 2; c <
N; c++)
A_(r, c) /=
b;
1164 template <
class nr_type_t>
1169 for (r = c + 1; r <
N; r++) {
1172 for (k = c + 1; k <
N; k++) f +=
conj (
A_(k, c)) *
A_(k, r);
1174 f *=
conj (t);
A_(c, r) -= f;
1175 for (k = c + 1; k <
N; k++)
A_(k, r) -= f *
A_(k, c);
1181 template <
class nr_type_t>
1186 for (c = r + 1; c <
N; c++) {
1189 for (k = r + 2; k <
N; k++) f +=
conj (
A_(r, k)) *
A_(c, k);
1191 f *=
conj (t);
A_(c, r + 1) -= f;
1192 for (k = r + 2; k <
N; k++)
A_(c, k) -= f *
A_(r, k);
1205 template <
class nr_type_t>
1210 for (c = r + 1; c <
N; c++) {
1213 for (k = r + 2; k <
N; k++) f +=
conj (
A_(r, k)) *
V_(c, k);
1215 f *=
conj (t);
V_(c, r + 1) -= f;
1216 for (k = r + 2; k <
N; k++)
V_(c, k) -= f *
A_(r, k);
1222 template <
class nr_type_t>
1230 template <
class nr_type_t>
1233 nr_double_t Max, Min;
1235 for (c = 0; c < N; c++) if (fabs (S_(c)) > Max) Max = fabs (
S_(c));
1237 for (c = 0; c <
N; c++)
if (fabs (
S_(c)) < Min)
S_(c) = 0.0;
1243 template <
class nr_type_t>
1248 for (c = 0; c <
N; c++) {
1252 for (r = 0; r <
N; r++) f +=
conj (
U_(r, c)) *
B_(r);
1259 for (r = 0; r <
N; r++) {
1260 for (f = 0.0, c = 0; c <
N; c++) f +=
conj (
V_(c, r)) *
R_(c);
1268 template <
class nr_type_t>
1281 for (i = 0; i <
N; i++) {
1282 T_(i) = householder_left (i);
1283 if (i < N - 1)
R_(i) = householder_right (i);
1287 for (i = 0; i <
N; i++)
S_(i) =
real (
A_(i, i));
1288 for (
E_(0) = 0, i = 1; i <
N; i++)
E_(i) =
real (
A_(i - 1, i));
1292 for (l = N, i = N - 1; i >= 0; l = i--) {
1294 if ((t =
R_(i)) != 0.0) {
1295 householder_apply_right_extern (i,
conj (t));
1297 else for (j = l; j <
N; j++)
1298 V_(i, j) =
V_(j, i) = 0.0;
1305 for (l = N, i = N - 1; i >= 0; l = i--) {
1306 for (j = l; j <
N; j++)
1308 if ((t =
T_(i)) != 0.0) {
1309 householder_apply_left (i,
conj (t));
1310 for (j = l; j <
N; j++)
A_(j, i) *= -
t;
1312 else for (j = l; j <
N; j++)
1323 # define MAX(x,y) (((x) > (y)) ? (x) : (y))
1328 givens (nr_double_t a, nr_double_t b, nr_double_t& c, nr_double_t& s) {
1329 nr_double_t z =
xhypot (a, b);
1335 template <
class nr_type_t>
1337 nr_double_t c, nr_double_t s) {
1338 for (
int i = 0; i <
N; i++) {
1339 nr_type_t y =
U_(i, c1);
1340 nr_type_t z =
U_(i, c2);
1341 U_(i, c1) = y * c + z *
s;
1342 U_(i, c2) = z * c - y *
s;
1346 template <
class nr_type_t>
1348 nr_double_t c, nr_double_t s) {
1349 for (
int i = 0; i <
N; i++) {
1350 nr_type_t y =
V_(r1, i);
1351 nr_type_t z =
V_(r2, i);
1352 V_(r1, i) = y * c + z *
s;
1353 V_(r2, i) = z * c - y *
s;
1362 template <
class nr_type_t>
1365 int i, l, j, its, k,
n, MaxIters = 30;
1366 nr_double_t an, f, g, h, d,
c,
s,
b, a;
1369 for (an = 0, i = 0; i <
N; i++)
1370 an =
MAX (an, fabs (
S_(i)) + fabs (
E_(i)));
1374 for (k = N - 1; k >= 0; k--) {
1376 for (its = 0; its <= MaxIters; its++) {
1381 for (n = 0, l = k; l >= 1; l--) {
1384 if (fabs (
E_(l)) + an == an) { split =
false;
break; }
1385 if (fabs (
S_(n)) + an == an)
break;
1393 for (i = l; i <= k; i++) {
1396 if (fabs (f) + an == an)
break;
1398 S_(i) = givens (f, g, c, s);
1400 givens_apply_u (n, i, c, s);
1410 for (j = 0; j <
N; j++)
V_(k, j) = -
V_(k, j);
1414 if (its == MaxIters) {
1428 f = (b - d) * (b + d) + (g - h) * (g + h);
1431 f = ((a - d) * (a + d) + h * (b / f - h)) / a;
1437 for (j = l; j <=
n; j++) {
1443 E_(j) = givens (f, h, c, s);
1455 givens_apply_v (j, i, c, s);
1473 givens_apply_u (j, i, c, s);