ftp.nice.ch/pub/next/unix/audio/cmix.s.tar.gz#/cmix/rlrlpc/factor.c

This is factor.c in view mode; [Download] [Up]

/* factor.f -- translated by f2c (version of 26 January 1990  18:57:16).
   You must link the resulting object file with the libraries:
	-lF77 -lI77 -lm -lc   (in that order)
*/

#include <f2c.h>

/* Table of constant values */

static integer c__1 = 1;

/* Subroutine */ int factor_(b, k4, rootr, rooti, kinsid, kprint, eps)
doublereal *b;
integer *k4;
doublereal *rootr, *rooti;
integer *kinsid, *kprint;
doublereal *eps;
{
    /* System generated locals */
    integer i_1, i_2, i_3;
    doublereal d_1, d_2;
    doublecomplex z_1, z_2;

    /* Builtin functions */
    double atan2();
    /* Subroutine */ int s_stop();
    double pow_dd(), sqrt();

    /* Local variables */
    static doublereal amax;
    static integer kerr;
    static doublereal dist, rmin, rmax;
    static integer i, j, k;
    static doublereal r;
    static doublecomplex z;
    static doublereal parti, distr, partr, r2, pi, resmag, resmax;
    extern /* Subroutine */ int dproot_();
    static integer k4m;
    static doublereal coe[37];
    static doublecomplex jay, res;

    /* Parameter adjustments */
    --b;
    --rootr;
    --rooti;

    /* Function Body */
/*       sets up problem, calls dproot, */
/*       and checks residual values at roots */
    jay.r = 0., jay.i = 1.;
    pi = atan2(1., 1.) * 4.;
    i_1 = *k4;
    for (i = 1; i <= i_1; ++i) {
/* L550: */
	coe[i - 1] = b[i];
    }
    k4m = *k4 - 1;
    dproot_(&k4m, coe, &rootr[1], &rooti[1], &kerr, kprint, eps);
/*      write(0,600)kerr */
/* L600: */
    if (kerr > 0) {
	s_stop("", 0L);
    }
    *kinsid = 0;
    resmax = 0.;
    rmax = 0.;
    rmin = 4294967296.;
    dist = 4294967296.;
    amax = 4294967296.;
    d_1 = 1. / *k4;
    r2 = pow_dd(&amax, &d_1);
    i_1 = k4m;
    for (j = 1; j <= i_1; ++j) {
	i_2 = j;
	i_3 = j;
	z_2.r = rooti[i_3] * jay.r, z_2.i = rooti[i_3] * jay.i;
	z_1.r = rootr[i_2] + z_2.r, z_1.i = z_2.i;
	z.r = z_1.r, z.i = z_1.i;
/* Computing 2nd power */
	d_1 = rootr[j];
/* Computing 2nd power */
	d_2 = rooti[j];
	r = sqrt(d_1 * d_1 + d_2 * d_2);
/*         skip residue calculation if root is too big */
	if (r > r2) {
	    goto L713;
	}
	i_2 = *k4;
	res.r = b[i_2], res.i = 0.;
	i_2 = *k4;
	for (k = 2; k <= i_2; ++k) {
/* L705: */
	    z_2.r = res.r * z.r - res.i * z.i, z_2.i = res.r * z.i + res.i * 
		    z.r;
	    i_3 = *k4 - k + 1;
	    z_1.r = z_2.r + b[i_3], z_1.i = z_2.i;
	    res.r = z_1.r, res.i = z_1.i;
	}
	partr = res.r;
	z_2.r = -jay.r, z_2.i = -jay.i;
	z_1.r = z_2.r * res.r - z_2.i * res.i, z_1.i = z_2.r * res.i + z_2.i *
		 res.r;
	parti = z_1.r;
/* Computing 2nd power */
	d_1 = partr;
/* Computing 2nd power */
	d_2 = parti;
	resmag = sqrt(d_1 * d_1 + d_2 * d_2);
	if (resmax <= resmag) {
	    resmax = resmag;
	}
L713:
	if (rmax < r) {
	    rmax = r;
	}
	if (rmin > r) {
	    rmin = r;
	}
	if (r < 1.) {
	    ++(*kinsid);
	}
	distr = (d_1 = r - 1., abs(d_1));
	if (dist > distr) {
	    dist = distr;
	}
/* L701: */
    }
/*     write(0,703)resmax */
/*     write(0,704)rmax,rmin,dist */
/* 703   format('resmax= ',d20.10) */
/* 704   format('rmax= ',d20.10/'rmin= ',d20.10/'dist=',d20.10) */
    return 0;
} /* factor_ */

/* Subroutine */ int dproot_(mm, a, rootr, rooti, kerr, kprint, eps)
integer *mm;
doublereal *a, *rootr, *rooti;
integer *kerr, *kprint;
doublereal *eps;
{
    /* Format strings */
    static char fmt_776[] = "(\002kount=\002,i5,\002  root no.=\002,i5)";

    /* System generated locals */
    integer i_1, i_2, i_3, i_4;
    doublereal d_1, d_2;
    doublecomplex z_1, z_2, z_3;

    /* Builtin functions */
    double pow_dd(), sqrt(), cos(), sin();
    integer s_wsfe(), do_fio(), e_wsfe();
    void z_div();

    /* Local variables */
    static integer mdec;
    static doublereal amin, amax, save[37];
    static integer kmax, kpol;
    static doublereal temp, size;
    static integer ktry;
    static doublereal real1, real2;
    static doublecomplex b[37], c[37];
    static integer i, j, k, m;
    static doublecomplex p, w, z;
    static doublereal parti;
    static integer kpolm;
    static doublereal partr;
    static integer kount, newst, nroot;
    static doublereal r1, r2;
    static integer ktrym;
    static doublecomplex bb[37], cc[37];
    static integer mp;
    static doublecomplex pp;
    static doublereal sqteps, rkount, rr1, rr2;
    static doublecomplex jay;
    static integer mmp;

    /* Fortran I/O blocks */
    static cilist io__54 = { 0, 0, 0, fmt_776, 0 };


    /* Parameter adjustments */
    --a;
    --rootr;
    --rooti;

    /* Function Body */
/*        mm=degree of polynomial */
/*        a=coefficient array, lowest to highest degree */
/*        kprint=1 for full printing */
/*        kerr=0 is normal return */
    jay.r = 0., jay.i = 1.;
    mmp = *mm + 1;
    m = *mm;
    mp = mmp;
    i_1 = mp;
    for (i = 1; i <= i_1; ++i) {
/* L700: */
	save[i - 1] = a[i];
    }
/*       kount is number of iterations so far */
    kount = 0;
/*       kmax is maximum total number of iterations allowed */
    kmax = m * 20;
/*       newst is number of re-starts */
    newst = 0;
/*       ktrym is number of attempted iterations before re-starting */
    ktrym = 20;
/*      kpolm is number of attempted iterations before polishing is 
stopped*/
    kpolm = 20;
/*       amax is the largest number we allow */
    amax = 4294967296.;
    amin = 1. / amax;
/*       rr1 and rr2 are radii within which we work for polishing */
    d_1 = 1. / m;
    rr1 = pow_dd(&amin, &d_1);
    d_1 = 1. / m;
    rr2 = pow_dd(&amax, &d_1);
/*     eps is the tolerance for convergence */
    sqteps = sqrt(*eps);
/*        main loop; m is current degree */
L10:
    if (m <= 0) {
	goto L200;
    }
/*        new z, a point on the unit circle */
    rkount = (doublereal) kount;
    d_1 = cos(rkount);
    d_2 = sin(rkount);
    z_2.r = d_2 * jay.r, z_2.i = d_2 * jay.i;
    z_1.r = d_1 + z_2.r, z_1.i = z_2.i;
    z.r = z_1.r, z.i = z_1.i;
    ktry = 0;
/*      r1 and r2 are boundaries of an expanding annulus within which we 
work*/
    d_1 = 1. / m;
    r1 = pow_dd(&amin, &d_1);
    d_1 = 1. / m;
    r2 = pow_dd(&amax, &d_1);
/*        inside loop */
L20:
    partr = z.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * z.r - z_2.i * z.i, z_1.i = z_2.r * z.i + z_2.i * z.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    size = sqrt(d_1 * d_1 + d_2 * d_2);
    if (size < r1 || size > r2) {
	goto L300;
    }
    if (ktry >= ktrym) {
	goto L300;
    }
    ++ktry;
    if (kount >= kmax) {
	goto L400;
    }
    ++kount;
/*        get value of polynomial at z, synthetic division */
    i_1 = mp - 1;
    i_2 = mp;
    b[i_1].r = a[i_2], b[i_1].i = 0.;
    i_1 = m;
    for (j = 1; j <= i_1; ++j) {
	k = m - j + 1;
/* L30: */
	i_2 = k - 1;
	i_3 = k;
	z_2.r = z.r * b[i_3].r - z.i * b[i_3].i, z_2.i = z.r * b[i_3].i + z.i 
		* b[i_3].r;
	i_4 = k;
	z_1.r = z_2.r + a[i_4], z_1.i = z_2.i;
	b[i_2].r = z_1.r, b[i_2].i = z_1.i;
    }
    p.r = b[0].r, p.i = b[0].i;
    partr = p.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * p.r - z_2.i * p.i, z_1.i = z_2.r * p.i + z_2.i * p.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    if (sqrt(d_1 * d_1 + d_2 * d_2) > amax) {
	goto L300;
    }
/*        get value of derivative at z, synthetic division */
    i_2 = mp - 1;
    i_3 = mp - 1;
    c[i_2].r = b[i_3].r, c[i_2].i = b[i_3].i;
    mdec = m - 1;
    i_2 = mdec;
    for (j = 1; j <= i_2; ++j) {
	k = m - j + 1;
/* L60: */
	i_3 = k - 1;
	i_4 = k;
	z_2.r = z.r * c[i_4].r - z.i * c[i_4].i, z_2.i = z.r * c[i_4].i + z.i 
		* c[i_4].r;
	i_1 = k - 1;
	z_1.r = z_2.r + b[i_1].r, z_1.i = z_2.i + b[i_1].i;
	c[i_3].r = z_1.r, c[i_3].i = z_1.i;
    }
    pp.r = c[1].r, pp.i = c[1].i;
    partr = pp.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * pp.r - z_2.i * pp.i, z_1.i = z_2.r * pp.i + z_2.i * pp.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    if (sqrt(d_1 * d_1 + d_2 * d_2) < amin) {
	goto L300;
    }
/*        test for convergence */
    partr = p.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * p.r - z_2.i * p.i, z_1.i = z_2.r * p.i + z_2.i * p.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    size = sqrt(d_1 * d_1 + d_2 * d_2);
    if (size > *eps) {
	goto L775;
    }
    nroot = *mm - m + 1;
    if (*kprint == 1) {
	s_wsfe(&io__54);
	do_fio(&c__1, (char *)&kount, (ftnlen)sizeof(integer));
	do_fio(&c__1, (char *)&nroot, (ftnlen)sizeof(integer));
	e_wsfe();
    }
    goto L500;
L775:
    z_div(&z_2, &p, &pp);
    z_1.r = z.r - z_2.r, z_1.i = z.i - z_2.i;
    z.r = z_1.r, z.i = z_1.i;
    goto L20;
/*        end of main loop */
/*        normal return */
L200:
    *kerr = 0;
    goto L600;
/*        new start */
L300:
    rkount = (doublereal) kount;
    d_1 = cos(rkount);
    d_2 = sin(rkount);
    z_2.r = d_2 * jay.r, z_2.i = d_2 * jay.i;
    z_1.r = d_1 + z_2.r, z_1.i = z_2.i;
    z.r = z_1.r, z.i = z_1.i;
    ktry = 0;
    ++newst;
    goto L20;
/*        too many iterations */
L400:
    *kerr = 400;
    goto L600;
/*        root z located */
/*        polish z to get w */
L500:
    w.r = z.r, w.i = z.i;
    kpol = 0;
L510:
    partr = w.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * w.r - z_2.i * w.i, z_1.i = z_2.r * w.i + z_2.i * w.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    size = sqrt(d_1 * d_1 + d_2 * d_2);
/*       give up polishing if w is outside annulus */
    if (size < rr1 || size > rr2) {
	goto L501;
    }
/*       give up polishing if kpol>=kpolm */
    if (kpol >= kpolm) {
	goto L501;
    }
    ++kpol;
    if (kount >= kmax) {
	goto L400;
    }
    ++kount;
    i_3 = mmp - 1;
    i_4 = mmp - 1;
    bb[i_3].r = save[i_4], bb[i_3].i = 0.;
    i_3 = *mm;
    for (j = 1; j <= i_3; ++j) {
	k = *mm - j + 1;
/* L530: */
	i_4 = k - 1;
	i_1 = k;
	z_2.r = w.r * bb[i_1].r - w.i * bb[i_1].i, z_2.i = w.r * bb[i_1].i + 
		w.i * bb[i_1].r;
	i_2 = k - 1;
	z_1.r = z_2.r + save[i_2], z_1.i = z_2.i;
	bb[i_4].r = z_1.r, bb[i_4].i = z_1.i;
    }
    p.r = bb[0].r, p.i = bb[0].i;
    partr = p.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * p.r - z_2.i * p.i, z_1.i = z_2.r * p.i + z_2.i * p.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    if (sqrt(d_1 * d_1 + d_2 * d_2) > amax) {
	goto L300;
    }
    i_4 = mmp - 1;
    i_1 = mmp - 1;
    cc[i_4].r = bb[i_1].r, cc[i_4].i = bb[i_1].i;
    mdec = *mm - 1;
    i_4 = mdec;
    for (j = 1; j <= i_4; ++j) {
	k = *mm - j + 1;
/* L560: */
	i_1 = k - 1;
	i_2 = k;
	z_2.r = w.r * cc[i_2].r - w.i * cc[i_2].i, z_2.i = w.r * cc[i_2].i + 
		w.i * cc[i_2].r;
	i_3 = k - 1;
	z_1.r = z_2.r + bb[i_3].r, z_1.i = z_2.i + bb[i_3].i;
	cc[i_1].r = z_1.r, cc[i_1].i = z_1.i;
    }
    pp.r = cc[1].r, pp.i = cc[1].i;
    partr = pp.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * pp.r - z_2.i * pp.i, z_1.i = z_2.r * pp.i + z_2.i * pp.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    if (sqrt(d_1 * d_1 + d_2 * d_2) < amin) {
	goto L300;
    }
    partr = p.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * p.r - z_2.i * p.i, z_1.i = z_2.r * p.i + z_2.i * p.r;
    parti = z_1.r;
/* Computing 2nd power */
    d_1 = partr;
/* Computing 2nd power */
    d_2 = parti;
    size = sqrt(d_1 * d_1 + d_2 * d_2);
/*       test for convergence of polishing */
    if (size <= *eps) {
	goto L501;
    }
    z_div(&z_2, &p, &pp);
    z_1.r = w.r - z_2.r, z_1.i = w.i - z_2.i;
    w.r = z_1.r, w.i = z_1.i;
    goto L510;
/*        deflate */
L501:
    i_1 = mp - 1;
    i_2 = mp;
    b[i_1].r = a[i_2], b[i_1].i = 0.;
    i_1 = m;
    for (j = 1; j <= i_1; ++j) {
	k = m - j + 1;
/* L830: */
	i_2 = k - 1;
	i_3 = k;
	z_2.r = z.r * b[i_3].r - z.i * b[i_3].i, z_2.i = z.r * b[i_3].i + z.i 
		* b[i_3].r;
	i_4 = k;
	z_1.r = z_2.r + a[i_4], z_1.i = z_2.i;
	b[i_2].r = z_1.r, b[i_2].i = z_1.i;
    }
    p.r = b[0].r, p.i = b[0].i;
    i_2 = m;
    rootr[i_2] = w.r;
    i_2 = m;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * w.r - z_2.i * w.i, z_1.i = z_2.r * w.i + z_2.i * w.r;
    rooti[i_2] = z_1.r;
    --m;
    --mp;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * w.r - z_2.i * w.i, z_1.i = z_2.r * w.i + z_2.i * w.r;
    parti = z_1.r;
    if (abs(parti) > sqteps) {
	goto L140;
    }
/*        real root */
    rooti[m + 1] = 0.;
    i_2 = mp;
    for (j = 1; j <= i_2; ++j) {
/* L100: */
	i_3 = j;
	i_4 = j;
	a[i_3] = b[i_4].r;
    }
    goto L10;
/*        complex root */
L140:
    partr = z.r;
    z_2.r = -jay.r, z_2.i = -jay.i;
    z_1.r = z_2.r * z.r - z_2.i * z.i, z_1.i = z_2.r * z.i + z_2.i * z.r;
    parti = z_1.r;
    z_2.r = parti * jay.r, z_2.i = parti * jay.i;
    z_1.r = partr - z_2.r, z_1.i = -z_2.i;
    z.r = z_1.r, z.i = z_1.i;
    i_3 = mp - 1;
    i_4 = mp;
    c[i_3].r = b[i_4].r, c[i_3].i = b[i_4].i;
    i_3 = m;
    for (j = 1; j <= i_3; ++j) {
	k = m - j + 1;
/* L110: */
	i_4 = k - 1;
	i_2 = k;
	z_2.r = z.r * c[i_2].r - z.i * c[i_2].i, z_2.i = z.r * c[i_2].i + z.i 
		* c[i_2].r;
	i_1 = k;
	z_1.r = z_2.r + b[i_1].r, z_1.i = z_2.i + b[i_1].i;
	c[i_4].r = z_1.r, c[i_4].i = z_1.i;
    }
    i_4 = m;
    rootr[i_4] = w.r;
    i_4 = m;
    z_3.r = -jay.r, z_3.i = -jay.i;
    z_2.r = z_3.r * w.r - z_3.i * w.i, z_2.i = z_3.r * w.i + z_3.i * w.r;
    z_1.r = -z_2.r, z_1.i = -z_2.i;
    rooti[i_4] = z_1.r;
    --m;
    --mp;
    i_4 = mp;
    for (j = 1; j <= i_4; ++j) {
/* L130: */
	i_2 = j;
	i_1 = j;
	a[i_2] = c[i_1].r;
    }
    goto L10;
/*        report and return */
L600:
    real1 = (doublereal) kount;
    real2 = (doublereal) (*mm);
    temp = real1 / real2;
/*     write(0,150)kount,temp */
/* L150: */
/*     write(0,151)newst,kerr */
/* L151: */
    return 0;
} /* dproot_ */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.