You need to enable JavaScript to run this app. FPGA实现S15.16定点牛顿-拉夫逊除法近0输入的初值优化咨询
优惠活动
大模型
产品
解决方案
定价
更多

FPGA实现S15.16定点牛顿-拉夫逊除法近0输入的初值优化咨询

FPGA平台S15.16格式牛顿-拉夫逊除法算法实现问题

现有实现基础

当前已在FPGA平台完成S15.16格式牛顿-拉夫逊除法算法开发,整体支持输入取值范围为[-16:16]。
针对输入幅值处于[1:16]区间的使用场景,现有方案采用各取值区间中点取倒数的方式设置迭代初值$a_0$,对应公式为:
$$a_0 = \frac{2}{Min+Max}$$
典型初值配置示例:

  • 1 ≤ x < 2 区间取 $a_0 = 2/3$
  • 6 ≤ x < 7 区间取 $a_0 = 2/13$
  • 15 ≤ x < 16 区间取 $a_0 = 2/31$
    该初值方案仅需3次迭代即可实现10e-9的MSE,精度表现符合预期。

[0:1]输入区间的待解问题

目前算法的短板集中在x ∈ [0:1]的输入区间:
参考公开方案的处理思路,针对该区间的通用流程为:通过比特移位将除数D缩放至0.5 ≤ D ≤ 1的归一化区间,采用线性近似式 $X_0 = T_1 + T_2 D \approx \frac{1}{D}$ 作为迭代初值。
为最小化[0.5,1]区间内近似值的最大绝对误差,当前已选用针对该区间优化的线性近似公式:
$$X_0 = \frac{48}{17} - \frac{32}{17}D$$
该公式在[0.5:1]区间可达到较好的近似精度,但仍存在两个核心问题待明确:

  • 当输入值逐步趋近于0(如0.1、0.01、0.001、0.00001等不同量级)时,是否需要为[0.01:0.1]、[0.001:0.01]等逐段细分区间分别配置适配初值?
  • 针对幅值极小的输入值,是否更适合采用Goldschmidt除法算法替代现有牛顿-拉夫逊实现方案?

参考仿真代码

以下为已实现的S15.16定点牛顿-拉夫逊除法仿真代码,供方案分析参考:

i = 0
# 16 fractional bits
SHIFT = 2 ** 16 
# Lut with "optimal?" values to init NRD algorithm
LUT = np.round(1 / np.arange(0.5, 16, 1) * SHIFT).astype(np.int64)
LUT_f = 1 / np.arange(0.5, 16, 1)
# Function to simulates the NRD algorithm in S15.16 over a FPGA
def FIXED_RECIPROCAL(x):
    # Smart adressing to the initial iteration value
    adress = x >> 16
    # Get the value from LUT
    a0 = LUT[adress]
    # Algorithm with only 3 iterations
    for i in range(3):
        s1 = (a0*a0) >> 16
        s2 = (x*s1) >> 16
        a0 = (a0 << 1) - s2
    # Return rescaled value (Only for analysis purposes)
    return(a0 / SHIFT)

# ----- TEST ----- #
t = np.arange(1, 16, 0.1)
teor = 1 / t
t_fixed = (t * SHIFT).astype(np.int32)
prac = np.zeros(len(t))
for value in t_fixed:
    prac[i] = FIXED_RECIPROCAL(value)
    i = i + 1

# Get and print Errors
errors = abs(prac - teor)
mse = ((prac - teor)**2).mean(axis=None)

print("Max Error : %s" % ('{:.3E}'.format(np.max(errors))))
print("MSE:      : %s" % ('{:.3E}'.format(mse)))

# Print the obtained values:
import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.plot(t, teor, label='Theorical division')
plt.plot(t, prac, '.', label='Newton-Raphson Division')
plt.legend(fontsize=16)
plt.title('Float 32 theorical division Vs. S15.16 Newton-Raphson division', fontsize=22)
plt.xlabel('x', fontsize=20)
plt.ylabel('1 / x', fontsize=16)
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)

内容的提问来源于stack exchange,提问作者Diego Ruiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.05 16:24:05