Пример #1
0
def exp2_fx(a):
    if types.program.options.ring:
        sint = types.sint
        intbitint = types.intbitint
        # how many bits to use from integer part
        n_int_bits = int(math.ceil(math.log(a.k - a.f, 2)))
        n_bits = a.f + n_int_bits
        n_shift = int(types.program.options.ring) - a.k
        r_bits = [sint.get_random_bit() for i in range(a.k)]
        shifted = ((a.v - sint.bit_compose(r_bits)) << n_shift).reveal()
        masked_bits = (shifted >> n_shift).bit_decompose(a.k)
        lower_overflow = sint()
        comparison.CarryOut(lower_overflow, masked_bits[a.f - 1::-1],
                            r_bits[a.f - 1::-1])
        lower_r = sint.bit_compose(r_bits[:a.f])
        lower_masked = sint.bit_compose(masked_bits[:a.f])
        lower = lower_r + lower_masked - (lower_overflow << (a.f))
        c = types.sfix._new(lower, k=a.k, f=a.f)
        higher_bits = intbitint.bit_adder(masked_bits[a.f:n_bits],
                                          r_bits[a.f:n_bits],
                                          carry_in=lower_overflow,
                                          get_carry=True)
        d = types.sfix.from_sint(floatingpoint.Pow2_from_bits(
            higher_bits[:-1]),
                                 k=a.k,
                                 f=a.f)
        e = p_eval(p_1045, c)
        g = d * e
        small_result = types.sfix._new(g.v.round(
            a.k + 1, a.f, signed=False, nearest=types.sfix.round_nearest),
                                       k=a.k,
                                       f=a.f)
        carry = comparison.CarryOutLE(masked_bits[n_bits:-1],
                                      r_bits[n_bits:-1], higher_bits[-1])
        # should be for free
        highest_bits = intbitint.ripple_carry_adder(masked_bits[n_bits:-1],
                                                    [0] * (a.k - n_bits),
                                                    carry_in=higher_bits[-1])
        bits_to_check = [
            x.bit_xor(y) for x, y in zip(highest_bits[:-1], r_bits[n_bits:-1])
        ]
        t = floatingpoint.KMul(bits_to_check)
        # sign
        s = masked_bits[-1].bit_xor(r_bits[-1]).bit_xor(carry)
        return s.if_else(t.if_else(small_result, 0), g)
    else:
        # obtain absolute value of a
        s = a < 0
        a = (s * (-2) + 1) * a
        # isolates fractional part of number
        b = trunc(a)
        c = a - load_sint(b, type(a))
        # squares integer part of a
        d = load_sint(b.pow2(types.sfix.k - types.sfix.f), type(a))
        # evaluates fractional part of a in p_1045
        e = p_eval(p_1045, c)
        g = d * e
        return (1 - s) * g + s * ((types.sfix(1)) / g)
Пример #2
0
def SqrtComp(z, old=False):
    f = types.sfix.f
    k = len(z)
    if isinstance(z[0], types.sint):
        return types.sfix._new(
            sum(z[i] * types.cfix(2**(-(i - f + 1) / 2)).v for i in range(k)))
    k_prime = k // 2
    f_prime = f // 2
    c1 = types.sfix(2**((f + 1) / 2 + 1))
    c0 = types.sfix(2**(f / 2 + 1))
    a = [z[2 * i].bit_or(z[2 * i + 1]) for i in range(k_prime)]
    tmp = types.sfix._new(types.sint.bit_compose(reversed(a[:2 * f_prime])))
    if old:
        b = sum(types.sint.conv(zi).if_else(i, 0)
                for i, zi in enumerate(z)) % 2
    else:
        b = util.tree_reduce(lambda x, y: x.bit_xor(y), z[::2])
    return types.sint.conv(b).if_else(c1, c0) * tmp
Пример #3
0
def exp2_fx(a):
    # obtain absolute value of a
    s = a < 0
    a = (s * (-2) + 1) * a
    # isolates fractional part of number
    b = trunc(a)
    c = a - load_sint(b, type(a))
    # squares integer part of a
    d = load_sint(types.sint.pow2(b), type(a))
    # evaluates fractional part of a in p_1045
    e = p_eval(p_1045, c)
    g = d * e
    return (1 - s) * g + s * ((types.sfix(1)) / g)
Пример #4
0
def norm_SQ(b, k):
    # calculation of z
    # x in order 0 - k
    x_order = b.bit_decompose()
    x = [0] * k
    #x i now inverted
    for i in range(k - 1, -1, -1):
        x[k - 1 - i] = x_order[i]
    # y is inverted for PReOR and then restored
    y_order = floatingpoint.PreOR(x)

    # y in order (restored in orginal order
    y = [0] * k
    for i in range(k - 1, -1, -1):
        y[k - 1 - i] = y_order[i]

    # obtain z
    z = [0] * k
    for i in range(k - 1):
        z[i] = y[i] - y[i + 1]

    z[k - 1] = y[k - 1]

    # now reverse bits of z[i] to generate v
    v = types.sint()
    for i in range(k):
        v += (2**(k - i - 1)) * z[i]
    c = b * v

    # construct m
    m = types.sint()
    for i in range(k):
        m = m + (i + 1) * z[i]

    # construct w, changes from what is on the paper
    # and the documentation
    k_over_2 = k / 2 + 1  #int(math.ceil((k/2.0)))+1
    w_array = [0] * (k_over_2)
    for i in range(1, k_over_2):
        w_array[i] = z[2 * i - 1 - (1 - k % 2)] + z[2 * i - (1 - k % 2)]

    w_array[0] = types.sfix(0)
    w = types.sint()
    for i in range(k_over_2):
        w += (2**i) * w_array[i]

    # return computed values
    return c, v, m, w
Пример #5
0
def sqrt_simplified_fx(x):
    # fix theta (number of iterations)
    theta = max(int(math.ceil(math.log(types.sfix.k))), 6)

    # process to use 2^(m/2) approximation
    m_odd, m, w = norm_simplified_SQ(x.v, x.k)
    # process to set up the precision and allocate correct 2**f
    if x.f % 2 == 1:
        m_odd = (1 - 2 * m_odd) + m_odd
        w = (w * 2 - w) * (1 - m_odd) + w
    # map number to use sfix format and instantiate the number
    w = types.sfix(w * 2**((x.f - (x.f % 2)) / 2))
    # obtains correct 2 ** (m/2)
    w = (w * (types.cfix(2**(1 / 2.0))) - w) * m_odd + w
    # produce x/ 2^(m/2)
    y_0 = types.cfix(1.0) / w

    # from this point on it sufices to work sfix-wise
    g_0 = (y_0 * x)
    h_0 = y_0 * types.cfix(0.5)
    gh_0 = g_0 * h_0

    ## initialization
    g = g_0
    h = h_0
    gh = gh_0

    for i in range(1, theta - 2):
        r = (3 / 2.0) - gh
        g = g * r
        h = h * r
        gh = g * h

    # newton
    r = (3 / 2.0) - gh
    h = h * r
    H = 4 * (h * h)
    H = H * x
    H = (3) - H
    H = h * H
    g = H * x
    g = g

    return g