import math


def natural_cubic(xi, data):
    """
    Interpolate a value from a set of points.  The points must have been
    prepared with natural_cubic_prep.

    Enter: xi: x value to interpolate from.
           data: the tuple of (x, y, D, logx) as returned from
                 natural_cubic_prep.
    Exit:  yi: the interpolated y value.  0 if the data list is empty.
           in_range: True if x is interpolated, False if it is
                     extrapolated.
    """
    (x, y, D, logx) = data
    if not len(x):
        return (0, False)
    if len(x) == 1:
        return (y[0], x[0] == xi)
    if logx:
        xi = math.log10(xi)
    in_range = (xi >= x[0] and xi <= x[-1])
    pos = 1
    while x[pos] < xi:
        pos += 1
        if pos+1 == len(x):
            break
    t = (xi-x[pos-1])/(x[pos]-x[pos-1])
    a = D[pos-1]*(x[pos]-x[pos-1])-(y[pos]-y[pos-1])
    b = -D[pos]*(x[pos]-x[pos-1])+(y[pos]-y[pos-1])
    yi = (1-t)*y[pos-1]+t*y[pos]+t*(1-t)*(a*(1-t)+b*t)
    return (yi, in_range)