code: def approx_sqrt_inv(prot, x: "TFEPrivateTensor", precision: int = 1):
      """
      From x, to compute an approximation of 1/sqrt(x).
      """
  
      def select(x, y, bit):
          """
          return y if bit = 0 else x.
          """
          c = np.ones(shape=bit.shape) * (x - y)
          return prot.mul_ab(prot.define_constant(c), bit) + y
  
      k = prot.fixedpoint_config.precision_fractional
      n = x.backing_dtype.nbits
      # using top half bits as integer, bottom half bits as fraction.
      s = (n // 2) - k
      xs = x << s
      assert k >= s
      assert n % 2 == 0
      assert x.is_scaled, "Er.. tricky here."
      with tf.name_scope("inv_sqrt"):
          # bit-decomposition.
          x_bits = prot.a2b(xs, n)
          y_bits = prefix_ORs(x_bits, n)
          z_bits = (
              y_bits ^ (y_bits >> 1)
          ) << 1  # note: x = c * 2^m where c \in [0.25, 0.5)
          rev_z_bits = prot.bit_reverse(z_bits)
  
          frac = prot.b2a(rev_z_bits, n)
          # By default, bottom k bits used as fraction,
          # do truncate manually here.
          frac.is_scaled = False
          normalized = frac * x  # normalized \in [0.25, 0.5)
          normalized = prot.truncate(normalized, amount=k + s)
          normalized.is_scaled = True
          """
          f(b) = 4.7979 * b^2 - 5.9417 * b + 3.1855 approixmates 1/sqrt(b) in [0.25, 0.5)
          with less than 0.7% relative error
          """
          sqrt_inv = (
              (4.7979 * normalized) - 5.9417
          ) * normalized + 3.1855
          # more iteration, more precision
          for i in range(precision):
              sqrt_inv = sqrt_inv * (
                  3 - normalized * sqrt_inv * sqrt_inv
              )
              sqrt_inv = sqrt_inv * 0.5
          """
              Indeed, the exponetent part is 2^{j+k+s}
              where k is the scaling factor, s = (n // 2) - k
              We want to compute sqrt(2^{-j}) with k-bit precision,
              i.e., sqrt(2^{-j}) * 2^k.
              In other words, we compute sqrt(2^{-j}) * 2^k from 2^{j+k+s}.
  
              1. We first obtain 2^{-(j+k+s)} from 2^{j+k+s}.
              2. Then we compute 2^{floor(-(j+k+s)/2)}. Rewrite it as
                 2^{floor(-(j+k+s)/2)} = c * 2^{floor(-j/2)} * 2^{floor(-(k+s)/2)}
                 where c depends on the parity of j, and k + s.
              3. We compute the parity of j+k+s, i.e., check the LSB of j+k+s.
              4. Suppose k+s is even, 2^{floor((s-k)/2)} = 2^{(s-k)/2}.
                 Then we can cancel this term via 2^{s-k/2}.
                 If lsb(j+k+s) = 0 <-> j is even. In this case,
                 2^{floor(-j/2)} = 2^{-j/2} = sqrt(2^{-j}).
                 If lsb(j+k+s) = 1 <-> j is odd. Then
                 2^{floor(-j/2)} * 2^{-1/2} = sqrt(2^{-j}).
  
                 Suppose k+s is odd,
                 We need 2^{(s-k)//2} * 2 to cancel 2^{floor(-(k+s)/2)}.
                 If lsb(j+k+s) = 0 <-> j is odd. In this case,
                 2^{floor(-j/2)} * 2^{-1/2} = sqrt(2^{-j}).
                 If lsb(j+k+s) = 1 <-> j is even. Then
                 2^{floor(-j/2)} = 2^{-j/2} = sqrt(2^{-j}).
          """
          sum_jks = prot.xor_indices(z_bits)
          lsb = prot.bit_extract(
              sum_jks, 0
          )  # lsb = 0 <-> j+k+s is even
          exponet = prot.b2a(
              prot.bit_gather(rev_z_bits | rev_z_bits >> 1, 0, 2), k + s
          )  # 2^{floor(-(j+k+s)/2)}
          esk = 2 ** ((k - s) // 2)
          if (
              k + s
          ) & 1 == 0:  # k+s is even which means lsb = 1 <=> j is odd
              exponet = exponet * select(esk, esk * np.sqrt(2.0), lsb)
          else:  # k+s is odd which means lsb = 1 <=> j is even
              exponet = exponet * select(
                  esk * np.sqrt(2.0), esk * 2, lsb
              )
  
      return sqrt_inv * exponet
  
imports: from math import ceil
  from math import log2
  import numpy
  import tensorflow
  from ..protocol import TFEPrivateTensor
  from ..protocol import TFEPublicTensor
label_desc: Use image node_id 16 for calling a global function with example usage: approx_sqrt_inv(prot, x, precision) and returns: unknown, unknown