code: def fixed_point_quantized_affine(
      inp,
      n_outmaps,
      base_axis=1,
      w_init=None,
      b_init=None,
      fix_parameters=False,
      rng=None,
      with_bias=True,
      quantize_w=True,
      sign_w=True,
      n_w=8,
      delta_w=2**-4,
      ste_fine_grained_w=True,
      quantize_b=True,
      sign_b=True,
      n_b=8,
      delta_b=2**-4,
      ste_fine_grained_b=True,
  ):
      """Fixed-Point Quantized Affine.
  
      Fixed-Point Quantized Affine is the affine function,
      except the definition of the inner product is modified.
      The input-output relation of this function is as follows:
  
      .. math::
  
          y_j = \sum_{i} Q(w_{ji}) x_i,
  
      where :math:`Q(w_{ji})` is the fixed-point quantization function.
  
      .. note::
  
          1) if you would like to share weights between some layers, please
          make sure to share the standard, floating value weights (`weight`)
          and not the quantized weights (`quantized weight`)
  
          2) The weights and the quantized weights become synced only after :func:`~nnabla._variable.Variable.forward` is called,
          and not after a call to :func:`~nnabla._variable.Variable.backward`.
          To access the parameters of the network, remember to call :func:`~nnabla._variable.Variable.forward` once before doing so, otherwise the
          float weights and the quantized weights will not be in sync.
  
          3) CPU and GPU implementations now use float value for `quantized weight`,
          since this function is only for simulation purposes.
  
      Args:
          inp (~nnabla.Variable): Input N-D array with shape (:math:`M_0 \\times \ldots \\times M_{B-1} \\times D_B \\times \ldots \\times D_N`). Dimensions before and after base_axis are flattened as if it is a matrix.
          n_outmaps (:obj:`int` or :obj:`tuple` of :obj:`int`): Number of output neurons per data.
          base_axis (int): Dimensions up to `base_axis` are treated as the sample dimensions.
          w_init (:obj:`nnabla.initializer.BaseInitializer` or :obj:`numpy.ndarray`): Initializer for weight. By default, it is initialized with :obj:`nnabla.initializer.UniformInitializer` within the range determined by :obj:`nnabla.initializer.calc_uniform_lim_glorot`.
          b_init (:obj:`nnabla.initializer.BaseInitializer` or :obj:`numpy.ndarray`): Initializer for bias. By default, it is initialized with zeros if `with_bias` is `True`.
          fix_parameters (bool): When set to `True`, the weights and biases will not be updated.
          rng (numpy.random.RandomState): Random generator for Initializer.
          with_bias (bool): Specify whether to include the bias term.
          quantize_w (bool): Quantize weights if `True`.
          sign_w (bool): Use signed quantization if `True`.
          n_w (int): Bit width used for weight.
          delta_w (float): Step size for weight.
          ste_fine_grained_w (bool): STE is fine-grained if `True`.
          quantize_b (bool): Quantize bias if `True`.
          n_b (int): Bit width used for bias.
          delta_w (float): Step size for bias.
          ste_fine_grained_b (bool): STE is fine-grained if `True`.
  
      Returns:
          :class:`~nnabla.Variable`: :math:`(B + 1)`-D array. (:math:`M_0 \\times \ldots \\times M_{B-1} \\times L`)
  
      """
  
      if not hasattr(n_outmaps, "__iter__"):
          n_outmaps = [n_outmaps]
      n_outmaps = list(n_outmaps)
      n_outmap = int(np.prod(n_outmaps))
      if w_init is None:
          inmaps = np.prod(inp.shape[base_axis:])
          w_init = UniformInitializer(
              calc_uniform_lim_glorot(inmaps, n_outmap), rng=rng
          )
      if with_bias and b_init is None:
          b_init = ConstantInitializer()
  
      # Floating Weight
      w = get_parameter_or_create(
          "W",
          [int(np.prod(inp.shape[base_axis:]))] + n_outmaps,
          w_init,
          True,
          not fix_parameters,
      )
  
      # Quantized Weight
      if quantize_w:
          w_q = get_parameter_or_create(
              "W_q",
              [int(np.prod(inp.shape[base_axis:]))] + n_outmaps,
              w_init,
              False,
          )
          # Link computation graph
          real_w_q = F.fixed_point_quantize(
              w,
              quantize=quantize_w,
              sign=sign_w,
              n=n_w,
              delta=delta_w,
              ste_fine_grained=ste_fine_grained_w,
              outputs=[w_q.data],
          )
          real_w_q.persistent = True
      else:
          real_w_q = w
  
      # Bias
      # Floating
      b = None
      b_q = None
      real_b_q = None
      if with_bias:
          b = get_parameter_or_create(
              "b", n_outmaps, b_init, True, not fix_parameters
          )
          if quantize_b:
              b_q = get_parameter_or_create(
                  "b_q", n_outmaps, b_init, False
              )
              # Link computation graph
              real_b_q = F.fixed_point_quantize(
                  b,
                  quantize=quantize_b,
                  sign=sign_b,
                  n=n_b,
                  delta=delta_b,
                  ste_fine_grained=ste_fine_grained_b,
                  outputs=[b_q.data],
              )
              real_b_q.persistent = True
          else:
              real_b_q = b
  
      return F.affine(inp, real_w_q, real_b_q, base_axis)
  
imports: from six import exec_
  import numpy
  import nnabla
  import nnabla.functions
  from nnabla.parameter import get_parameter_or_create, get_parameter
  from nnabla.initializer import calc_uniform_lim_glorot, ConstantInitializer, NormalInitializer, UniformInitializer, WeightNormalizationScaleInitializer
label_desc: Use image node_id 29 for calling a global function with example usage: fixed_point_quantized_affine(inp, n_outmaps, base_axis, w_init, b_init, fix_parameters, rng, with_bias, quantize_w, sign_w, n_w, delta_w, ste_fine_grained_w, quantize_b, sign_b, n_b, delta_b, ste_fine_grained_b) and returns: F