Ejemplo n.º 1
0
def inv_f(f):
    """
    Solve f^(-1)(i_f(r)) to get i_f and i_r using Newton's method

    Uses a fixed number of iterations for easy taping and a different
    formulation for f>0 and f<0 to ensure convergence in few
    iterations. Solution has good accuracy for all values.
    """
    # Obtain a good guess first using EKV's simple interpolation function
    i1 = 4. * f_simple(f)
    i2 = i1
    for counter in xrange(4):
        # (f > 0) => (i1 >= 3.) The 1e-15 term needed to prevent AD
        # library from choking as without it we have log(0) later
        sqi1p = np.sqrt(1. + i1 + 1e-15) 
        sqi11 = sqi1p - 1. 
        fodfp = (sqi1p - 2. + np.log(sqi11) - f) * 2. * sqi11
        i1 = abs(i1 - fodfp)
        # f < 0
        sqi1 = np.sqrt(1. + i2) 
        fodfn = (sqi1 - 1. - np.exp(f - sqi1 + 2.)) * 2. * sqi1 \
            / (np.exp(f - sqi1 + 2.) + 1.)
        i2 = i2 - fodfn

    return ad.condassign(f, i1, i2)
Ejemplo n.º 2
0
def inv_f(f):
    """
    Solve f^(-1)(i_f(r)) to get i_f and i_r using Newton's method

    Uses a fixed number of iterations for easy taping and a different
    formulation for f>0 and f<0 to ensure convergence in few
    iterations. Solution has good accuracy for all values.
    """
    # Obtain a good guess first using EKV's simple interpolation function
    i1 = 4. * f_simple(f)
    i2 = i1
    for counter in xrange(4):
        # (f > 0) => (i1 >= 3.) The 1e-15 term needed to prevent AD
        # library from choking as without it we have log(0) later
        sqi1p = np.sqrt(1. + i1 + 1e-15)
        sqi11 = sqi1p - 1.
        fodfp = (sqi1p - 2. + np.log(sqi11) - f) * 2. * sqi11
        i1 = abs(i1 - fodfp)
        # f < 0
        sqi1 = np.sqrt(1. + i2)
        fodfn = (sqi1 - 1. - np.exp(f - sqi1 + 2.)) * 2. * sqi1 \
            / (np.exp(f - sqi1 + 2.) + 1.)
        i2 = i2 - fodfn

    return ad.condassign(f, i1, i2)
Ejemplo n.º 3
0
def inv_f1(f):
    """
    Approximately solve f^(-1)(i_f(r)) to get i_f and i_r using relaxation 
    """
    # Obtain a good guess first using EKV's simple interpolation function
    i_f = 4. * f_simple(f)
    # Use fixed number of iterations for easy taping
    for i in xrange(30):
        sqi1 = np.sqrt(1. + i_f + 1e-15)
        # Uses different formulation for f>0 and f<0 for convergence
        i_fnew = ad.condassign(f, (f + 2. - np.log(sqi1 - 1.))**2 - 1.,
                               (np.exp(f - sqi1 + 2.) + 1.)**2 - 1.)
        i_f = .5 * i_f + .5 * i_fnew
    return i_f
Ejemplo n.º 4
0
def inv_f1(f):
    """
    Approximately solve f^(-1)(i_f(r)) to get i_f and i_r using relaxation 
    """
    # Obtain a good guess first using EKV's simple interpolation function
    i_f = 4. * f_simple(f)
    # Use fixed number of iterations for easy taping
    for i in xrange(30):
        sqi1 = np.sqrt(1. + i_f + 1e-15)
        # Uses different formulation for f>0 and f<0 for convergence
        i_fnew = ad.condassign(f, 
                               (f + 2. - np.log(sqi1 - 1.))**2 - 1.,
                               (np.exp(f - sqi1 + 2.) + 1.)**2 - 1.)
        i_f = .5 * i_f + .5 * i_fnew
    return i_f