private double neigh_value(double x_cur, double x_min, double x_max, double r) {

        double ranval, zvalue, new_value;
        double work3, work2 = 0, work1 = 0;

        double x_range = x_max - x_min;

// ------------ generate a standard normal random variate (zvalue) -------------------

        // perturb current value with normal random variable
//	CALL DRNNOA(1,zvalue)  // generates a standard normal random deviate
        // ISML Stat Library 2 routine - Acceptance/rejection

//	Below returns a standard Gaussian random number based upon Numerical recipes gasdev and
//	Marsagalia-Bray Algorithm
        work3 = 2.0;

        while (work3 >= 1.0 || work3 == 0.0) {
            ranval = rand.nextDouble();
            work1 = 2.0 * ranval - 1.0;
            ranval = rand.nextDouble();
            work2 = 2.0 * ranval - 1.0;
            work3 = work1 * work1 + work2 * work2;
        }
        // was dlog() !!!
        work3 = Math.pow((-2.0 * Math.log(work3)) / work3, 0.5);  // natural log

        // pick one of two deviates at random (don't worry about trying to use both):
        ranval = rand.nextDouble();
        if (ranval < 0.5) {
            zvalue = work1 * work3;
        } else {
            zvalue = work2 * work3;
        }

// ------------ done standard normal random variate generation -----------------
        // calculate new decision variable value:
        new_value = x_cur + zvalue * r * x_range;

        //  check new value is within DV bounds.  If not, bounds are reflecting.
        if (new_value < x_min) {
            new_value = x_min + (x_min - new_value);
            if (new_value > x_max) {
                // if reflection goes past x_max { value should be x_min since
                // without reflection the approach goes way past lower bound.
                // This keeps x close to lower bound when x_cur is close to lower bound
                //  Practically speaking, this should never happen with r values <0.3
                new_value = x_min;
            }
        } else if (new_value > x_max) {
            new_value = x_max - (new_value - x_max);
            if (new_value < x_min) {
                // if reflection goes past x_min { value should be x_max for same reasons as above
                new_value = x_max;
            }
        }
        return new_value;
    }