private float multilinearInterpolate(float[] encoded, int od) {
        // first calculate the distances -- the differences between
        // each encoded value and the integer below it.
        float[] dists = new float[encoded.length];
        
        for (int i = 0; i < dists.length; i++) {
            dists[i] = (float) (encoded[i] - Math.floor(encoded[i]));
        }
        
        // initialize the map of axes.  Each bit in this map represents
        // whether the control value in that dimension should be the integer
        // above or below encoded[i]
        int map = 0;
        
        // the initial values
        float val = getSample(encoded, map, od);
        float prev = val;
        
        // walk the axes
        for (int i = 0; i < dists.length; i++) {
            // find the largest value of dist remaining
            int idx = 0;
            float largest = -1;
            for (int c = 0; c < dists.length; c++) {
                if (dists[c] > largest) {
                    largest = dists[c];
                    idx = c;
                }
            }
            
            // now find the sample with that axis set to 1
            map |= (0x1 << idx);
            float cur = getSample(encoded, map, od);
            
            // calculate the value and remember it
            val += dists[idx] * (cur - prev);
            prev = val;
            
            // make sure we won't find this distance again
            dists[idx] = -1;
        }
        
        // voila
        return val;
    }