public double interpolate(double xx){
    	    // check that xx and xx2 are within the limits
    	    if(xx<x[0]){
    	        if(xx>=x[0]-CubicInterpolation.potentialRoundingError){
    	            xx=this.x[0];
    	        }
    	        else{
    	            throw new IllegalArgumentException(xx + " is outside the limits, " + x[0] + " - " + x[this.nPoints-1]);
    	        }
    	    }

    	    if(xx>this.x[this.nPoints-1]){
    	        if(xx<=this.x[this.nPoints-1]+CubicInterpolation.potentialRoundingError){
    	            xx=this.x[this.nPoints-1];
    	        }
    	        else{
    	            throw new IllegalArgumentException(xx + " is outside the limits, " + this.x[0] + " - " + this.x[this.nPoints-1]);
    	        }
    	    }

    	    // assign variables
    	    this.xx = xx;

            // Find grid surrounding the interpolation point
            int gridn = 0;
            int counter = 1;
            boolean test = true;
            while(test){
                if(xx<this.x[counter]){
                    gridn = counter - 1;
                    test = false;
                }
                else{
                    counter++;
                    if(counter>=this.nPoints){
                        gridn = this.nPoints-2;
                        test = false;
                    }
                }
            }

            // interpolation
            double xNormalised = (xx - x[gridn])/(x[gridn+1] - x[gridn]);
            this.interpolatedValue = 0.0;
            for(int i=0; i<4; i++){
                this.interpolatedValue += this.coeff[gridn][i]*Math.pow(xNormalised, i);
            }
            this.interpolatedDydx = 0.0;
            for(int i=1; i<4; i++){
                this.interpolatedDydx += i*this.coeff[gridn][i]*Math.pow(xNormalised, i-1);
            }

            return this.interpolatedValue;
        }