public static double critchi(double p, int df)
    {
        if (p <= 0.0) {
            return CHI_MAX;
        } else {
            if (p >= 1.0) {
                return 0.0;
            }
        }
        
        /*
        double chisqval = 0.5 * df / Math.sqrt(p);    // fair first value 
        double minchisq = 0.0;
        double maxchisq = CHI_MAX;
        while ((maxchisq - minchisq) > CHI_EPSILON) {
System.out.println(" ** "+chisqval);          
            if (pochisq(chisqval, df) < p) {
                maxchisq = chisqval;
            } else {
                minchisq = chisqval;
            }
            chisqval = 0.5 * (maxchisq + minchisq);
        }
        */
        double h = (df - 0.7)/Math.sqrt(p);
        double c1 =   h, d1 = pochisq(c1, df) - p;
        double c2 = 0.0, d2 = pochisq(c2, df) - p;
        int l = 0;
        while ( Math.abs(c1 - c2) > CHI_EPSILON ) {
            double c = (d1 * c2 - d2 * c1)/(d1 - d2);
            double d = pochisq(c, df) - p;
// System.out.println(" ** "+c1+" "+c2+" "+d1+" "+d2+" || "+c+" "+d);          
            if ( d * d1 < 0.0 ) {
                c2 = c; d2 = d;
                if ( l == 1 ) d1 /= 2.0; else l = 1;
            } else {
                c1 = c; d1 = d;
                if ( l == 2 ) d2 /= 2.0; else l = 2;
            }
        }
        return 0.5*(c1+c2);
    }