public static Complex laguerre(Complex estx, Complex[] pcoeff, int m){
                double  eps = 1e-7;     // estimated fractional round-off error
                int     mr = 8;         // number of fractional values in Adam's method of breaking a limit cycle
                int     mt = 1000;      // number of steps in breaking a limit cycle
                int     maxit = mr*mt;  // maximum number of iterations allowed
                int     niter = 0;      // number of iterations taken

                // fractions used to break a limit cycle
                double  frac[]={0.5, 0.25, 0.75, 0.13, 0.38, 0.62, 0.88, 1.0};

                Complex root = new Complex();    // root
                Complex b   = new Complex();
                Complex d   = new Complex();
                Complex f   = new Complex();
                Complex g   = new Complex();
                Complex g2  = new Complex();
                Complex h   = new Complex();
                Complex sq  = new Complex();
                Complex gp  = new Complex();
                Complex gm  = new Complex();
                Complex dx  = new Complex();
                Complex x1  = new Complex();
                Complex temp1  = new Complex();
                Complex temp2  = new Complex();

                double  abp = 0.0D, abm = 0.0D;
                double  err = 0.0D, abx = 0.0D;

                for(int i=1; i<=maxit; i++){
                        niter=i;
                        b=Complex.copy(pcoeff[m]);
                        err=Complex.abs(b);
                        d=f=Complex.zero();
                        abx=Complex.abs(estx);
                        for(int j=m-1; j>=0;j--)
                        {
                                // Efficient computation of the polynomial and its first two derivatives
                                f=Complex.plus(Complex.times(estx, f),  d);
                                d=Complex.plus(Complex.times(estx, d),  b);
                                b=Complex.plus(Complex.times(estx, b),  pcoeff[j]);
                                err=Complex.abs(b)+abx*err;
                        }
                        err*=eps;

                        // Estimate of round-off error in evaluating polynomial
                        if(Complex.abs(b)<=err)
                        {
                                root=Complex.copy(estx);
                                niter=i;
                                return root;
                        }
                        // Laguerre formula
                        g=Complex.over(d, b);
                        g2=Complex.square(g);
                        h=Complex.minus(g2, Complex.times(2.0, Complex.over(f, b)));
                        sq=Complex.sqrt(Complex.times((double)(m-1), Complex.minus(Complex.times((double)m, h), g2)));
                        gp=Complex.plus(g, sq);
                        gm=Complex.minus(g, sq);
                        abp=Complex.abs(gp);
                        abm=Complex.abs(gm);
                        if( abp < abm ) gp = gm;
                        temp1.setReal((double)m);
                        temp2.setReal(Math.cos((double)i));
                        temp2.setImag(Math.sin((double)i));
                        dx=((Math.max(abp, abm) > 0.0 ? Complex.over(temp1, gp):Complex.times(Math.exp(1.0+abx),temp2)));
                        x1=Complex.minus(estx, dx);
                        if(Complex.isEqual(estx, x1))
                        {
                                root=Complex.copy(estx);
                                niter=i;
                                return root;     // converged
                        }
                        if ((i % mt)!= 0){
                                estx=Complex.copy(x1);
                        }
                        else{
                                // Every so often we take a fractional step to break any limit cycle
                                // (rare occurence)
                                estx=Complex.minus(estx, Complex.times(frac[i/mt-1], dx));
                        }
                        niter=i;
                }
                // exceeded maximum allowed iterations
                root=Complex.copy(estx);
                System.out.println("Maximum number of iterations exceeded in laguerre");
                System.out.println("root returned at this point");
                return root;
        }