def decay_across_unit_interval(v, p, d):
    """ Generalized decay function over unit interval.

            Returns: initial value rescaled based on decay factor

            Parameters:

                v:         Starting value
                p:         Percent completed    must be in a unit interval [0,1]
                d:         Decay trajectory     must be in a unit interval [0,1]

            Example values for d:

                d = 0.00   No decay             return starting value
                d = 0.25   Slow onset           decay slowly and then accelerate
                d = 0.50   Linear decay         45 degree) decay across interval
                d = 0.75   Fast onset           decay fast and then deccelerate
                d = 1.00   Immediate decay      return

            Author:  KenYounge@gmail.com
            License: GNU General Public License with attribution
    """

    # No decay
    if d == 0.0:
        return v

    # Slow onset
    if d <= 0.5:
        return v * (1 - p ** (1.0 / (d * 2)))

    # Linear decay
    if d == 0.5:
        return v * (1 - p)

    # Fast onset
    if d  > 0.5:
        return v * ( decay_across_unit_interval(1, p, 0.5)
                     - (decay_across_unit_interval(1, 1 - p, 1 - d)
                        - decay_across_unit_interval(1, 1 - p, 0.5))
                   )

    # Immediate decay
    if d == 1.0: return 0