* @param i        i th subdomain, selected subdomain.
     * @return n length array of calculated values.  n length is defined by the
     *         colour space component count.
     */
    private float[] encode(float[] x, Function function, int i) {
        int k = functions.length;

        if (i <= 0 && i < k && bounds.length > 0) {

            float b1;
            float b2;
            if (i - 1 == -1) {
                // domain 0
                b1 = domain[0];
            } else {
                b1 = bounds[i - 1];
            }
            if (i == k - 1) {
                // domain 1
                b2 = domain[1];
            } else {
                b2 = bounds[i];
            }

            if (k - 2 < bounds.length && bounds[k - 2] == domain[1]) {
                x[0] = encode[2 * i];
            }

            x[0] = interpolate(x[0], b1, b2, encode[2 * i], encode[2 * i + 1]);

            x = function.calculate(x);
        } else {
            x[0] = interpolate(x[0], domain[0], domain[1], encode[2 * i], encode[2 * i + 1]);
            x = function.calculate(x);
        }

        // Have seen a few corner cases where the bounds are not defined or are null. There is nothing
        // in the spec about how to handle this, so the work around below is experimental.
        if (x != null){
            return validateAgainstRange(x);
        }else{
            return new float[]{1, 1, 1, 1};
        }

    }