def fn(step):
    if (step <= x_milestones[0]):
        return float(f_values[0])
    elif ((step > x_milestones[0]) and (step <= x_milestones[1])):
        m = (float((f_values[1] - f_values[0])) / float(max(1, (x_milestones[1] - x_milestones[0]))))
        return (float(f_values[0]) + (m * float((step - x_milestones[0]))))
    elif ((step > x_milestones[1]) and (step <= x_milestones[2])):
        return float(f_values[1])
    elif ((step > x_milestones[2]) and (step <= x_milestones[3])):
        progress = (float((step - x_milestones[2])) / float(max(1, (x_milestones[3] - x_milestones[2]))))
        tmp = (0.5 * (1.0 + math.cos((math.pi * progress))))
        return (float(f_values[2]) + (tmp * float((f_values[1] - f_values[2]))))
    else:
        return float(f_values[2])
def fn(step):
    if (step <= x_milestones[0]):
        return float(f_values[0])
    elif ((step > x_milestones[0]) and (step <= x_milestones[1])):
        m = (float((f_values[1] - f_values[0])) / float(max(1, (x_milestones[1] - x_milestones[0]))))
        return (float(f_values[0]) + (m * float((step - x_milestones[0]))))
    elif ((step > x_milestones[1]) and (step <= x_milestones[2])):
        return float(f_values[1])
    elif ((step > x_milestones[2]) and (step <= x_milestones[3])):
        progress = (float((step - x_milestones[2])) / float(max(1, (x_milestones[3] - x_milestones[2]))))
        tmp = (0.5 * (1.0 + math.cos((math.pi * progress))))
        return (float(f_values[2]) + (tmp * float((f_values[1] - f_values[2]))))
    else:
        return float(f_values[2])