def METHOD_NAME(x, w, i, b, dy, base_axis, num_bits,
                        inq_iterations, selection_algorithm, seed, **kw):
    shape = list(x.shape[:base_axis])
    if inq_iterations[-1] == 0:
        # last element in `inq_iterations`, quantize all weights
        i = np.ones_like(i)
    elif 0 in inq_iterations:
        # only `largest_abs` is deterministic
        assert (selection_algorithm == 'largest_abs')
        idx_var = np.flatnonzero(i == 0)
        idx_newfix = idx_var[np.argsort(
            np.abs(w.ravel()[idx_var]))[-(len(idx_var) // 2):]]
        i.ravel()[idx_newfix] = 1
    x_ = x.reshape(np.prod(shape), -1)
    wq_ = np.copy(w)
    if np.any(i == 1):
        wq_[i == 1] = quantize(w[i == 1], np.max(np.abs(w)), num_bits)
    wq_ = wq_.reshape(w.shape[0], -1)
    dy_ = dy.reshape(np.prod(shape), -1)
    dx = np.dot(dy_, np.transpose(wq_))
    dw = np.dot(np.transpose(x_), dy_)
    if b is not None:
        db = np.sum(dy_, 0)
    else:
        db = np.empty(0)
    return np.concatenate([dx.flatten(),
                           dw.flatten(),
                           db.flatten()])