internal virtual int cnvex_(int n, double[] a, bool[] h) { int i__1, i__2, i__3; int i, j, k, m, jc, nj; i__1 = n; for (i = 1; i <= i__1; ++i) { h[i - 1] = true; } k = (int)(Math.log(n - 2.0) / Math.log(2.0)); i__1 = k + 1; if (pow_ii(c__2, i__1) <= n - 2) { ++k; } m = 1; i__1 = k; for (i = 0; i <= i__1; ++i) { i__2 = 0; i__3 = (n - 2 - m) / (m + m); nj = Math.max(i__2, i__3); i__2 = nj; for (j = 0; j <= i__2; ++j) { jc = (j + j + 1) * m + 1; cmerge_(n, a, jc, m, h); } m += m; } return(0); }
internal virtual double z_abs(doublecomplex z) { double temp, real, imag; real = z.r; imag = z.i; if (real < 0) { real = -real; } if (imag < 0) { imag = -imag; } if (imag > real) { temp = real; real = imag; imag = temp; } if ((real + imag) == real) { return(real); } temp = imag / real; temp = real * Math.Sqrt(1.0 + temp * temp); return(temp); }
internal virtual int cmerge_(int n, double[] a, int i, int m, bool[] h) { int i__1, i__2; bool tstl, tstr; int[] ill = new int[1]; int[] irr = new int[1]; int[] il = new int[1]; int[] ir = new int[1]; left_(n, h, i, il); right_(n, h, i, ir); if (ctest_(n, a, il[0], i, ir[0])) { return(0); } else { h[i - 1] = false; while (true) { if (il[0] == i - m) { tstl = true; } else { left_(n, h, il[0], ill); tstl = ctest_(n, a, ill[0], il[0], ir[0]); } i__1 = n; i__2 = i + m; if (ir[0] == Math.min(i__1, i__2)) { tstr = true; } else { right_(n, h, ir[0], irr); tstr = ctest_(n, a, il[0], ir[0], irr[0]); } h[il[0] - 1] = tstl; h[ir[0] - 1] = tstr; if (tstl && tstr) { return(0); } if (!tstl) { il[0] = ill[0]; } if (!tstr) { ir[0] = irr[0]; } } } }
internal static void pqsolve(double p, double q, double[] r, double[] i) { p = -p / 2.0; q = p * p - q; if (q >= 0) { // TODO: Check this q = Math.Sqrt(q); r[0] = p + q; i[0] = 0.0; r[1] = p - q; i[1] = 0.0; } else { // TODO: Check this q = Math.Sqrt(-q); r[0] = p; i[0] = q; r[1] = p; i[1] = -q; } }
public static void bairstow(double[] ar, double[] ai, bool[] err) { for (var i = 0; i < err.Length; i++) { err[i] = true; } if (ar.Length != ai.Length || ar.Length != err.Length) { return; } var a = new double[ar.Length]; for (var i = 0; i < ar.Length; i++) { a[i] = ar[ar.Length - i - 1] / ar[ar.Length - 1]; } var n = ar.Length - 1; var b = new double[n + 1]; var c = new double[n + 1]; b[0] = c[0] = 1.0; while (n > 2) { double r, s, dn, dr, ds, drn, dsn, eps; int i, iter; r = s = 0; dr = 1.0; ds = 0; eps = 1e-14; iter = 1; bool precision_error_flag = false; while ((Math.abs(dr) + Math.abs(ds)) > eps) { if ((iter % 200) == 0) { r = Math.random() * 1000; } if ((iter % 500) == 0) { eps *= 10.0; precision_error_flag = true; } b[1] = a[1] - r; c[1] = b[1] - r; for (i = 2; i <= n; i++) { b[i] = a[i] - r * b[i - 1] - s * b[i - 2]; c[i] = b[i] - r * c[i - 1] - s * c[i - 2]; } dn = c[n - 1] * c[n - 3] - c[n - 2] * c[n - 2]; drn = b[n] * c[n - 3] - b[n - 1] * c[n - 2]; dsn = b[n - 1] * c[n - 1] - b[n] * c[n - 2]; if (Math.abs(dn) < 1e-16) { dn = 1; drn = 1; dsn = 1; } dr = drn / dn; ds = dsn / dn; r += dr; s += ds; iter++; } for (i = 0; i < n - 1; i++) { a[i] = b[i]; } a[n] = s; a[n - 1] = r; err[n - 1] = precision_error_flag; err[n - 2] = precision_error_flag; n -= 2; } var real = new double[2]; var imag = new double[2]; for (int i = a.Length - 1; i >= 2; i -= 2) { pqsolve(a[i - 1], a[i], real, imag); ar[i - 1] = real[0]; ai[i - 1] = imag[0]; ar[i - 2] = real[1]; ai[i - 2] = imag[1]; } if ((n % 2) == 1) { ar[0] = -a[1]; ai[0] = 0.0; err[0] = false; } else { err[0] = err[1] = false; } }
internal virtual int start_(int n, double[] a, doublecomplex[] y, double[] radius, int[] nz, double theSmall, double big, bool[] h) { int i__1, i__2, i__3; double d__1, d__2; doublecomplex z__1 = dc(), z__2 = dc(), z__3 = dc(); int iold; double xbig, temp; int i, j; double r = 0.0; int jj; double th, xsmall; int nzeros; double ang; xsmall = Math.log(theSmall); xbig = Math.log(big); nz[0] = 0; i__1 = n + 1; for (i = 1; i <= i__1; ++i) { if (a[i - 1] != 0.0) { a[i - 1] = Math.log(a[i - 1]); } else { a[i - 1] = -1e30; } } i__1 = n + 1; cnvex_(i__1, a, h); iold = 1; th = 6.2831853071796 / n; i__1 = n + 1; for (i = 2; i <= i__1; ++i) { if (h[i - 1]) { nzeros = i - iold; temp = (a[iold - 1] - a[i - 1]) / nzeros; if (temp < -xbig && temp >= xsmall) { nz[0] += nzeros; r = 1.0 / big; } if (temp < xsmall) { nz[0] += nzeros; } if (temp > xbig) { r = big; nz[0] += nzeros; } d__1 = -xbig; if (temp <= xbig && temp > Math.max(d__1, xsmall)) { r = Math.exp(temp); } ang = 6.2831853071796 / nzeros; i__2 = i - 1; for (j = iold; j <= i__2; ++j) { jj = j - iold + 1; if (r <= 1.0 / big || r == big) { radius[j - 1] = -1.0; } i__3 = j; d__1 = Math.cos(ang * jj + th * i + .7); d__2 = Math.sin(ang * jj + th * i + .7); z__3.r = d__2 * (float)0.0; z__3.i = d__2 * (float)1.0; z__2.r = d__1 + z__3.r; z__2.i = z__3.i; z__1.r = r * z__2.r; z__1.i = r * z__2.i; y[i__3 - 1].r = z__1.r; y[i__3 - 1].i = z__1.i; } iold = i; } } return(0); }
internal virtual void polzeros_(int n, doublecomplex[] poly, double eps, double big, double theSmall, int nitmax, doublecomplex[] root, double[] radius, bool[] err, int[] iter, double[] apoly, double[] apolyr) { int i__1, i__2, i__3, i__4; double d__1, d__2; doublecomplex z__1 = dc(), z__2 = dc(), z__3 = dc(), z__4 = dc(); double amax; doublecomplex corr = dc(); int i; doublecomplex abcorr = dc(); int[] nzeros = new int[1]; if (z_abs(poly[n]) == 0.0) { PrintError("Inconsistent data: the leading coefficient is zero"); return; } if (z_abs(poly[0]) == 0.0) { PrintError("The constant term is zero: deflate the polynomial"); return; } amax = 0.0; i__1 = n + 1; for (i = 1; i <= i__1; ++i) { apoly[i - 1] = z_abs(poly[i - 1]); d__1 = amax; d__2 = apoly[i - 1]; amax = Math.max(d__1, d__2); apolyr[i - 1] = apoly[i - 1]; } if (amax >= big / (n + 1)) { PrintError("WARNING: COEFFICIENTS TOO BIG, OVERFLOW IS LIKELY"); } i__1 = n; for (i = 1; i <= i__1; ++i) { radius[i - 1] = 0.0; err[i - 1] = true; } start_(n, apolyr, root, radius, nzeros, theSmall, big, err); i__1 = n + 1; for (i = 1; i <= i__1; ++i) { apolyr[n - i + 2 - 1] = eps * apoly[i - 1] * ((n - i + 1) * (float)3.8 + 1); apoly[i - 1] = eps * apoly[i - 1] * ((i - 1) * (float)3.8 + 1); } if (apoly[1 - 1] == 0.0 || apoly[n + 1 - 1] == 0.0) { PrintError("WARNING: THE COMPUTATION OF SOME INCLUSION RADIUS MAY FAIL. THIS IS REPORTED BY RADIUS=0"); } i__1 = n; for (i = 1; i <= i__1; ++i) { err[i - 1] = true; if (radius[i - 1] == -1.0) { err[i - 1] = false; } } i__1 = nitmax; for (iter[0] = 1; iter[0] <= i__1; ++iter[0]) { i__2 = n; for (i = 1; i <= i__2; ++i) { if (err[i - 1]) { newton_(n, poly, apoly, apolyr, root[i - 1], theSmall, radius, corr, err, i - 1); if (err[i - 1]) { aberth_(n, i, root, abcorr); i__3 = i; i__4 = i; z__4.r = corr.r * abcorr.r - corr.i * abcorr.i; z__4.i = corr.r * abcorr.i + corr.i * abcorr.r; z__3.r = 1 - z__4.r; z__3.i = -z__4.i; z_div(z__2, corr, z__3); z__1.r = root[i__4 - 1].r - z__2.r; z__1.i = root[i__4 - 1].i - z__2.i; root[i__3 - 1].r = z__1.r; root[i__3 - 1].i = z__1.i; } else { ++nzeros[0]; if (nzeros[0] == n) { return; } } } } } }