使用mpmath与numpy数值计算结果不一致,求修正mpmath代码
我最初使用numpy完成数值计算,结果正确但精度不足易引发错误,因此改用mpmath进行计算,却发现两者结果不一致。以下是对应的实现代码,恳请协助修正mpmath代码以得到正确结果:
numpy实现代码
import sympy as sy import numpy as np from sympy import Poly from functools import lru_cache y, omega = sy.symbols('y omega') def lambda0_f(y): return 2 * y * (1 - 1j * omega) / (1 - y**2) def s0_f(y): return (1 - 2 * 1j * omega - 2 * omega**2) / (2 * (1 - y**2)) y0_val = 0.4 num_val = 3 lambda0_series = sy.series(lambda0_f(y), y, y0_val, num_val+1).removeO() s0_series = sy.series(s0_f(y), y, y0_val, num_val+1).removeO() def c0i(i0): if i0 == 0: return lambda0_f(y0_val) else: return lambda0_series.coeff((y-y0_val)**i0) def d0i(i0): if i0 == 0: return s0_f(y0_val) else: return s0_series.coeff((y-y0_val)**i0) c0i_coeffs = [Poly(c0i(i), omega).all_coeffs() for i in range(num_val+1)] d0i_coeffs = [Poly(d0i(i), omega).all_coeffs() for i in range(num_val+1)] c0i_coeffs_np = [np.array(coef, dtype=np.complex128) for coef in c0i_coeffs] d0i_coeffs_np = [np.array(coef, dtype=np.complex128) for coef in d0i_coeffs] def convolve_polys(poly1, poly2): return np.convolve(poly1, poly2) def poly_add(poly1, poly2): len_diff = len(poly1) - len(poly2) if len_diff > 0: poly2 = np.pad(poly2, (len_diff, 0), mode='constant') elif len_diff < 0: poly1 = np.pad(poly1, (-len_diff, 0), mode='constant') return poly1 + poly2 @lru_cache(maxsize=None) def compute_cni_dni_coeffs(i0, num, c0_coeffs, d0_coeffs): if num == 0: return c0_coeffs[i0], d0_coeffs[i0] c_result = np.zeros(num, dtype=np.complex128) d_result = np.zeros(num, dtype=np.complex128) for k in range(i0 + 1): c_result, d_result=poly_add(c_result, convolve_polys(np.array(c0_coeffs[k]), np.array(compute_cni_dni_coeffs(i0 - k, num - 1, tuple(map(tuple, c0_coeffs)), tuple(map(tuple, d0_coeffs)))[0]))),poly_add(d_result, convolve_polys(np.array(d0_coeffs[k]), np.array(compute_cni_dni_coeffs(i0 - k, num - 1, tuple(map(tuple, c0_coeffs)), tuple(map(tuple, d0_coeffs)))[0]))) if i0 + 1 <= num_val: c_result, d_result=poly_add(c_result, poly_add((i0 + 1) * np.array(compute_cni_dni_coeffs(i0 + 1, num - 1, tuple(map(tuple, c0_coeffs)), tuple(map(tuple, d0_coeffs)))[0]), np.array(compute_cni_dni_coeffs(i0, num - 1, tuple(map(tuple, c0_coeffs)), tuple(map(tuple, d0_coeffs)))[1]))),poly_add(d_result, (i0 + 1) * np.array(compute_cni_dni_coeffs(i0 + 1, num - 1, tuple(map(tuple, c0_coeffs)), tuple(map(tuple, d0_coeffs)))[1])) return tuple(c_result), tuple(d_result) cni_coeffs, dni_coeffs = compute_cni_dni_coeffs(0, num_val, tuple(map(tuple, c0i_coeffs_np)), tuple(map(tuple, d0i_coeffs_np))) cni_coeffs, dni_coeffs = compute_cni_dni_coeffs(0, num_val, tuple(map(tuple, c0i_coeffs_np)), tuple(map(tuple, d0i_coeffs_np))) print("cni_coeffs:", cni_coeffs) print("dni_coeffs:", dni_coeffs)
mpmath实现代码
from functools import lru_cache import mpmath import numpy as np from mpmath import mp, mpc import sympy as sy from sympy import symbols, Poly ndps=20 mp.dps = ndps y, rh, r2, omega, l ,M,Q= sy.symbols('y r_h r_2 omega ell M Q') def lambda0_f(y): return 2 * y * (1 - 1j * omega) / (1 - y**2 + 1e-15) def s0_f(y): return (1 - 2 * 1j * omega - 2 * omega**2) / (2 * (1 - y**2 + 1e-15)) y0_val = 0.4 num_val =3 lambda0_series = sy.series(lambda0_f(y), y, y0_val, num_val+1).removeO() s0_series = sy.series(s0_f(y), y, y0_val, num_val+1).removeO() def c0i(i0): if i0 == 0: return lambda0_f(y0_val) else: return lambda0_series.coeff((y-y0_val)**i0) def d0i(i0): if i0 == 0: return s0_f(y0_val) else: return s0_series.coeff((y-y0_val)**i0) c0i_coeffs = [Poly(c0i(i),omega).all_coeffs() for i in range(num_val+1)] d0i_coeffs = [Poly(d0i(i),omega).all_coeffs() for i in range(num_val+1)] c0i_coeffs_np = [np.array(coef, dtype=np.complex128) for coef in c0i_coeffs] d0i_coeffs_np = [np.array(coef, dtype=np.complex128) for coef in d0i_coeffs] def numpy_to_mpmath(x): return [[mpc(np.real(y),np.imag(y)) for y in z ] for z in x ] lambda_coes_mpmath = [[mpc(np.real(y),np.imag(y)) for y in z ] for z in c0i_coeffs_np ] s_coes_mpmath = [[mpc(np.real(y),np.imag(y)) for y in z ] for z in d0i_coeffs_np ] def poly_add(poly1, poly2): if len(poly2) > len(poly1): poly1, poly2 = poly2, poly1 result = [mpc(0) for _ in range(len(poly1))] for i in range(len(poly2)): result[i] = poly1[i] + poly2[i] for i in range(len(poly2), len(poly1)): result[i] = poly1[i] return result def convolve_polys(p1, p2): result_length = len(p1) + len(p2) - 1 result = [mpc(0) for _ in range(result_length)] for i in range(len(p1)): for j in range(len(p2)): result[i + j] += p1[i] * p2[j] return result @lru_cache(maxsize=None) def compute_cni_dni_coeffs(i0, num, c0_coeffs, d0_coeffs): if num == 0: return c0_coeffs[i0], d0_coeffs[i0] c_result = [mpc(0) for _ in range(num)] d_result = [mpc(0) for _ in range(num)] for k in range(i0 + 1): c_k, d_k = compute_cni_dni_coeffs(i0 - k, num - 1, c0_coeffs, d0_coeffs) c_result,d_result = poly_add(c_result, convolve_polys(c0_coeffs[k], c_k)),poly_add(d_result, convolve_polys(d0_coeffs[k], c_k)) if i0 + 1 <= num_val: c_next, d_next = compute_cni_dni_coeffs(i0 + 1, num - 1, c0_coeffs, d0_coeffs) _,d_c0=compute_cni_dni_coeffs(i0, num - 1, c0_coeffs, d0_coeffs) c_result = poly_add(c_result, poly_add(convolve_polys(c_next, [mpc(i0 + 1,0)]), d_c0)) d_result = poly_add(d_result, convolve_polys(d_next, [mpc(i0 + 1,0)])) return c_result, d_result cni_coeffs, dni_coeffs = compute_cni_dni_coeffs(0, num_val, tuple(map(tuple, lambda_coes_mpmath)), tuple(map(tuple, s_coes_mpmath)))
内容的提问来源于stack exchange,提问作者Yu-Qi Lei
相关产品推荐
相关产品推荐

