# 依赖: numpy import numpy as np def gm11(x0, steps=2): x0 = np.asarray(x0, dtype=float) if x0.ndim != 1 or len(x0) < 4 or not np.isfinite(x0).all() or np.any(x0 <= 0): raise ValueError('需要至少 4 个有限的正数观测值') if not isinstance(steps, int) or steps < 0: raise ValueError('预测步数必须是非负整数') n = len(x0) ratio = x0[:-1] / x0[1:] lo, hi = np.exp(-2 / (n + 1)), np.exp(2 / (n + 1)) if not np.all((ratio > lo) & (ratio < hi)): raise ValueError('级比未通过;先评估平移变换或改用其他模型') x1 = np.cumsum(x0) z1 = 0.5 * (x1[1:] + x1[:-1]) a, b = np.linalg.lstsq(np.column_stack([-z1, np.ones(n-1)]), x0[1:], rcond=None)[0] k = np.arange(n + steps, dtype=float) # a 趋于 0 时使用连续极限,避免 b/a 导致除零。 if abs(a) < 1e-10: x1_hat = x0[0] + b * k else: x1_hat = x0[0] * np.exp(-a*k) - b/a * np.expm1(-a*k) # 第一个观测值是初值,不能与自身作差而变成 0。 return np.r_[x0[0], np.diff(x1_hat)] print(np.round(gm11([2.8, 3.1, 3.4, 3.7, 4.1], steps=2), 3))