def lin_app_SQ(b, k, f): alpha = types.cfix((-0.8099868542) * 2 ** (k)) beta = types.cfix(1.787727479 * 2 ** (2 * k)) # obtain normSQ parameters c, v, m, W = norm_SQ(types.sint(b), k) # c is now escalated w = alpha * load_sint(c,types.sfix) + beta # equation before b and reduction by order of k # m even or odd determination m_bit = types.sint() comparison.Mod2(m_bit, m, int(math.ceil(math.log(k, 2))), w.kappa, False) m = load_sint(m_bit, types.sfix) # w times v this way both terms have 2^3k and can be symplified w = w * v factor = 1.0 / (2 ** (3.0 * k - 2 * f)) w = w * factor # w escalated to 3k -2 * f # normalization factor W* 1/2 ^{f/2} w = w * W * types.cfix(1.0 / (2 ** (f / 2.0))) # now we need to elminate an additional root of 2 in case m was odd sqr_2 = types.cfix((2 ** (1 / 2.0))) w = (1 - m) * w + sqr_2 * w * m return w
def atan(x): """ Returns the arctangent (sfix) of any given fractional value. :param x: fractional input (sfix). :return: arctan of :py:obj:`x` (sfix). """ # obtain absolute value of x s = x < 0 x_abs = (s * (-2) + 1) * x # angle isolation b = x_abs > 1 v = (types.cfix(1.0) / x_abs) v = (1 - b) * (x_abs - v) + v v_2 = v * v # range of polynomial coefficients assert x.k - x.f >= 18 P = p_eval(p_5102, v_2) Q = p_eval(q_5102, v_2) # padding y = v * (P / Q) y_pi_over_two = pi_over_2 - y # sign correction y = (1 - b) * (y - y_pi_over_two) + y_pi_over_two y = (1 - s) * (y - (-y)) + (-y) return y
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
def pow_fx(x, y): log2_x = 0 # obtains log2(x) if (type(x) == int or type(x) == float): log2_x = math.log(x, 2) log2_x = types.cfix(log2_x) else: log2_x = log2_fx(x) # obtains y * log2(x) exp = y * log2_x # returns 2^(y*log2(x)) return exp2_fx(exp)
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
def atan(x): # obtain absolute value of x s = x < 0 x_abs = (s * (-2) + 1) * x # angle isolation b = x_abs > 1 v = (types.cfix(1.0) / x_abs) v = (1 - b) * (x_abs - v) + v v_2 = v * v P = p_eval(p_5102, v_2) Q = p_eval(q_5102, v_2) # padding y = v * (P / Q) y_pi_over_two = pi_over_2 - y # sign correction y = (1 - b) * (y - y_pi_over_two) + y_pi_over_two y = (1 - s) * (y - (-y)) + (-y) return y