23 #define DEBUG(N) if (Debug >= (unsigned) (N)) 24 static unsigned int Debug = 1;
26 #define DEBUG(N) if (0) 47 #define COMPLEX_INIT 13 48 #define COMPLEX_GUESS 14 78 #define sgn(X) ((X) < 0 ? -1 : (X) == 0 ? 0 : 1) 82 #define ISANABERRATION 8 143 DEBUG(1) fprintf(stderr,
"\t\tGuess\n");
150 error =
PZeval(strat, neighborhood, &new_trial);
173 neighborhood[0] =
NULL;
174 neighborhood[1] = new_trial;
175 neighborhood[2] =
NULL;
183 "Pole-Zero analysis interrupted; %d trials, %d roots\n",
194 && (!neighborhood[0] || !neighborhood[2] ||
CKTpzTrapped 195 || neighborhood[2]->
s.real - neighborhood[0]->
s.
real < 1e22));
198 DEBUG(1) fprintf(stderr,
199 "Finished: NFlat %d, NZeros: %d, NTrials %d, Guess %g to %g, aber %d\n",
208 "The input signal is shorted on the way to the output");
218 "Pole-zero converging to numerical aberrations; giving up after %d trials",
225 "Pole-zero iteration limit reached; giving up after %d trials",
246 double a, b, est, k, n;
251 new_trial->
count = 0;
276 new_trial->
s.
imag =
set[1]->s.imag;
278 new_trial->
s.
imag = 0.0;
284 error =
NIpzSym(
set, new_trial);
287 if (new_trial->
s.
real <
set[0]->s.real
288 || new_trial->
s.
real >
set[1]->s.real) {
289 DEBUG(1) fprintf(stderr,
290 "FIXED UP BAD Strat: %s (%d) was (%.15g,%.15g)\n",
294 (
set[0]->s.real +
set[1]->s.real) / 2.0;
298 if (new_trial->
s.
real <
set[1]->s.real
299 || new_trial->
s.
real >
set[2]->s.real) {
300 DEBUG(1) fprintf(stderr,
301 "FIXED UP BAD Strat: %s (%d) was (%.15g,%.15g)\n",
305 (
set[1]->s.real +
set[2]->s.real) / 2.0;
309 if (new_trial->
s.
real <=
set[0]->s.real
310 || new_trial->
s.
real ==
set[1]->s.real
311 && new_trial->
s.
imag ==
set[1]->s.imag
312 || new_trial->
s.
real >=
set[2]->s.real) {
313 DEBUG(1) fprintf(stderr,
314 "FIXED UP BAD Strat: %s (%d), was (%.15g %.15g)\n",
318 (
set[0]->s.real +
set[2]->s.real) / 2.0;
319 if (new_trial->
s.
real ==
set[1]->s.real) {
320 DEBUG(1) fprintf(stderr,
"Still off!");
324 (
set[0]->s.real +
set[1]->s.real) / 2.0;
327 (
set[1]->s.real +
set[2]->s.real) / 2.0;
336 DEBUG(1) fprintf(stderr,
"\tPZ minima at: %-30g %d\n",
339 new_trial->
s.
real =
set[1]->s.real;
360 new_trial->
s.
imag = 10000.0;
373 new_trial->
s.
real =
set[0]->s.real;
374 new_trial->
s.
imag = 1.0e8;
377 new_trial->
s.
real =
set[0]->s.real;
378 new_trial->
s.
imag = 1.0e12;
388 new_trial->
s.
real = (
set[0]->s.real + 2 *
set[1]->s.real) / 3.0;
393 new_trial->
s.
real = (
set[2]->s.real + 2 *
set[1]->s.real) / 3.0;
402 *new_trial_p = new_trial;
420 int a_mag, b_mag, q_mag;
428 if (
set[1] && (
set[1]->flags &
ISAMINIMA)) {
431 else if (
set[0] &&
set[0]->
s.imag != 0.0) {
432 if (!
set[1] || !
set[2])
437 else if (!
set[0] || !
set[1] || !
set[2]) {
441 if (
sgn(
set[0]->f_def.real) !=
sgn(
set[1]->f_def.real)) {
446 else if (
sgn(
set[1]->f_def.real) !=
sgn(
set[2]->f_def.real)) {
453 zaddeq(&a, &a_mag,
set[1]->f_def.real,
set[1]->mag_def,
454 -
set[0]->f_def.real,
set[0]->mag_def);
455 zaddeq(&b, &b_mag,
set[2]->f_def.real,
set[2]->mag_def,
456 -
set[1]->f_def.real,
set[1]->mag_def);
460 k1 =
set[1]->s.real -
set[0]->s.real;
461 k2 =
set[2]->s.real -
set[1]->s.real;
462 if (a_mag + 10 <
set[0]->mag_def
463 && a_mag + 10 <
set[1]->mag_def
464 && b_mag + 10 <
set[1]->mag_def
465 && b_mag + 10 <
set[2]->mag_def) {
471 else if (
sgn(a) != -
sgn(b)) {
476 else if (
sgn(a) ==
sgn(
set[1]->f_def.real))
481 else if (
sgn(a) == -
sgn(
set[1]->f_def.real)) {
500 else if (a_mag > b_mag ||
501 a_mag == b_mag &&
FABS(a) >
FABS(b))
521 if (
set[0] &&
set[1] &&
set[2])
522 fprintf(stderr,
"given %.15g %.15g / %.15g %.15g / %.15g %.15g\n",
523 set[0]->
s.real,
set[0]->s.imag,
set[1]->s.real,
set[1]->s.imag,
524 set[2]->s.real,
set[2]->s.imag);
525 fprintf(stderr,
"suggestion(%d/%d/%d | %d): %s\n",
540 PZtrial *
t, *match, *base, *new_trial;
544 double reltol, abstol;
545 int e, def_mag, diff_mag, error;
547 int pretest, shifted, was_shifted;
550 new_trial = *new_trialp;
552 if (new_trial->
s.
imag < 0.0)
553 new_trial->
s.
imag *= -1.0;
568 was_shifted = shifted;
575 for (p = Trials; p !=
NULL; p = p->
next) {
579 if (diff_frac.
real < 0.0
580 || diff_frac.
real == 0.0 && diff_frac.
imag < 0.0) {
595 if (diff_frac.
imag == 0.0 &&
601 "diff_frac.real = %10g, p->s = %10g, nt = %10g\n",
603 fprintf(stderr,
"ab=%g,rel=%g\n", abstol, reltol);
605 if (was_shifted || p->
count >= 3
606 || !
alter(new_trial,
set[1], abstol, reltol)) {
624 C_NORM(diff_frac,diff_mag);
625 if (diff_frac.
imag != 0.0) {
629 C_NORM(diff_frac,diff_mag);
632 C_MUL(def_frac,diff_frac);
647 DEBUG(1) fprintf(stderr,
"Pre-test taken\n");
655 fprintf(stderr,
"over at %.30g %.30g (new %.30g %.30g, %x)\n",
676 DEBUG(1) fprintf(stderr,
"Repeat at %.30g %.30g\n",
696 printf(
"Original:\n");
702 DEBUG(1) printf(
"Needs reordering\n");
705 else if (error !=
OK)
719 printf(
"Factored:\n");
737 else if (error !=
OK)
759 prev->
next = new_trial;
763 Trials->
prev = new_trial;
765 ZeroTrial = new_trial;
769 new_trial->
prev = prev;
802 if (new_trial->
s.
imag != 0.0)
813 for (t = Trials; t; t =
next) {
824 if (new_trial->
s.
imag != 0.0)
827 tdiff = diff_frac.
real;
831 if (diff_frac.
real != 0.0) {
833 C_NORM(diff_frac,diff_mag);
848 if (t == ZeroTrial) {
920 for (t = Trials; t; t =
next) {
951 if (new->
s.
imag != 0.0) {
958 else if (!
set[2] && new->
s.
real >
set[1]->s.real) {
967 else if (new->
s.
real <
set[0]->s.real) {
973 else if (new->
s.
real <
set[1]->s.real) {
975 || new->
mag_def ==
set[1]->mag_def
987 else if (new->
s.
real <
set[2]->s.real) {
989 || new->
mag_def ==
set[1]->mag_def
1020 int *amag, xmag, ymag;
1025 if (xmag > 50 + ymag)
1028 for (xmag -= ymag; xmag > 0; xmag--)
1033 if (ymag > 50 + xmag)
1036 for (ymag -= xmag; ymag > 0; ymag--)
1044 while (
FABS(*a) > 1.0) {
1048 while (
FABS(*a) < 0.5) {
1063 fprintf(stderr,
"%c (%3d/%3d) %.15g %.15g :: %.30g %.30g %d\n", x,
1064 NIter, new_trial->seq_num, new_trial->s.real, new_trial->s.imag,
1065 new_trial->f_def.real, new_trial->f_def.imag, new_trial->mag_def);
1068 fprintf(stderr,
"*** numerical aberration ***\n");
1082 diff_mag = a->mag_def - b->mag_def;
1083 if (abs(diff_mag) <= 1) {
1086 else if (diff_mag == -1)
1090 C_SUBEQ(diff_frac, mult * a->f_def, b->f_def);
1092 if (diff_frac.
real < 1.0e-20)
1109 set[1] =
pzseek(ZeroTrial, 0);
1112 set[2] =
pzseek(
set[1], 1);
1114 set[0] =
pzseek(
set[1], -1);
1118 set[0] =
pzseek(
set[0], -1);
1122 set[2] =
pzseek(
set[2], 1);
1128 set[0] =
pzseek(
set[0], -1);
1134 set[2] =
pzseek(
set[2], 1);
1138 if (!
set[0] || !
set[1] || !
set[2])
1153 set[1] =
pzseek(ZeroTrial, 0);
1154 if (
set[1] !=
NULL) {
1155 set[0] =
pzseek(
set[1], -1);
1156 set[2] =
pzseek(
set[1], 1);
1169 double abstol, reltol;
1173 DEBUG(1) fprintf(stderr,
"ALTER from: %.30g %.30g\n",
1174 new->s.real, new->s.imag);
1175 DEBUG(1) fprintf(stderr,
"nt->next %g\n", nearto->prev->s.real);
1176 DEBUG(1) fprintf(stderr,
"nt->next %g\n", nearto->next->s.real);
1179 DEBUG(1) fprintf(stderr,
"not 2\n");
1180 p1 = nearto->s.real;
1182 p1 -= 1e-6 * nearto->s.real + 1e-5;
1184 p1 += nearto->prev->s.real;
1185 DEBUG(1) fprintf(stderr,
"p1 %g\n", p1);
1188 p1 -= 10.0 * (
FABS(p1) + 1.0);
1193 p1 = nearto->s.real;
1196 DEBUG(1) fprintf(stderr,
"not 1\n");
1197 p2 = nearto->s.real;
1199 p2 += 1e-6 * nearto->s.real + 1e-5;
1202 p2 += nearto->next->s.real;
1203 DEBUG(1) fprintf(stderr,
"p2 %g\n", p2);
1206 p2 += 10.0 * (
FABS(p2)+ 1.0);
1211 p2 = nearto->s.real;
1213 if (nearto->prev &&
FABS(p1 - nearto->prev->s.real) /
1214 (
FABS(nearto->prev->s.real) + abstol/reltol) < reltol
1215 || nearto->next &&
FABS(p2 - nearto->next->s.real) /
1216 (
FABS(nearto->next->s.real) + abstol/reltol) < reltol) {
1219 fprintf(stderr,
"Bailed out\n");
1223 if (
CKTpzTrapped != 2 && nearto->s.real - p1 > p2 - nearto->s.real) {
1224 DEBUG(1) fprintf(stderr,
"take p1\n");
1228 DEBUG(1) fprintf(stderr,
"take p2\n");
1232 DEBUG(1) fprintf(stderr,
"ALTER to : %.30g %.30g\n",
1233 new->s.real, new->s.imag);
CKTpzFindZeros(CKTcircuit *ckt, GENERIC **rootinfoptr, int *rootcount)
struct sCKTmodHead * next
#define ERROR(CODE, MESSAGE)
CKTpzStrat(PZtrial **set)
CKTpzVerify(PZtrial **set, PZtrial *new_trial)
#define NIPZSHOULDREORDER
static double Guess_Param
CKTpzRunTrial(CKTcircuit *ckt, PZtrial **new_trialp, set)
static void clear_trials()
static PZtrial * ZeroTrial
int CKTpzStep(int strat, set)
static PZtrial * pzseek()