import math


def max_uv_distance(max_fact, radius_deg, freq_hz):
    """Function to evaluate maximum uv distance for given amplitude drop.

    Follows equation 1 from:
    ftp://ftp.cv.nrao.edu/NRAO-staff/bcotton/Obit/BLAverage.pdf

    Args:
        max_fact (float) : amplitude reduction factor
        radius_deg (float) : Source / FoV radius
        freq_hz (float) : Observation frequency, in Hz

    Returns:
        Maxium distance in the UV plane over which data can be averaged,
        in metres.
    """
    def inv_sinc(arg):
        """Newton-Raphson method for calculating arcsinc(x), from Obit."""
        x1 = 0.001
        for i in range(0, 1000):
            x0 = x1
            a = x0 * math.pi
            x1 = x0 - ((math.sin(a) / a) - arg) / \
                ((a * math.cos(a) - math.pi * math.sin(a)) / (a**2))
            if math.fabs(x1 - x0) < 1.0e-6:
                break
        return x1

    delta_uv = inv_sinc(1.0 / max_fact) / (radius_deg * (math.pi / 180.))
    wavelength = 299792458.0 / freq_hz
    delta_uv *= wavelength  # convert to metres
    return delta_uv