gpt4 book ai didi

python - 将 SymPy 表达式转换为 SymPy longdoubles 的精度问题

转载 作者:行者123 更新时间:2023-12-04 07:28:26 26 4
gpt4 key购买 nike

在将 SymPy 表达式转换为 NumPy longdoubles(下面的代码片段)时,我注意到 NumPy 结果中的最后三位数字通常是垃圾。我不明白为什么会发生这种情况,因为我明确指出 NumPy 结果应该是 dtype=np.longdouble .我做错了什么,有没有(直接的)方法来解决它?
There doesn't seem to be a single mention of SymPy in NumPy's documentation ,所以我不确定 NumPy 到底是什么 array构造函数在给定 SymPy 输入时执行。

    from sympy import *
import numpy as np

print(np.finfo(np.longdouble))

symMat = Matrix([[sqrt(5), sqrt(7)]])
print(symMat)
print(N(symMat, 19))

np.set_printoptions(precision = 18)

numMat = np.array(symMat, dtype=np.longdouble)
print("", repr(numMat))
numMat = np.array(N(symMat, 19), dtype=np.longdouble)
print("", repr(numMat))
这会产生以下输出:
    Machine parameters for float128
---------------------------------------------------------------
precision = 18 resolution = 1e-18
machep = -63 eps = 1.084202172485504434e-19
negep = -64 epsneg = 5.42101086242752217e-20
minexp = -16382 tiny = 3.3621031431120935063e-4932
maxexp = 16384 max = 1.189731495357231765e+4932
nexp = 15 min = -max
---------------------------------------------------------------

Matrix([[sqrt(5), sqrt(7)]])
Matrix([[2.236067977499789696, 2.645751311064590591]])
array([[2.236067977499789805, 2.645751311064590716]], dtype=float128)
array([[2.236067977499789805, 2.645751311064590716]], dtype=float128)

最佳答案

我很确定 np.longdouble只需通过 __float__ 转换输入:

In [4]: np.array([float(N(sqrt(5), 19))], dtype=np.longdouble)
Out[4]: array([2.236067977499789805], dtype=float128)
Python 通常没有很好的方式在不同的非整数类型之间进行互操作:所有东西通常都经过浮点数。话虽如此,numpy 不承认 sympy 的 Rational 遵循数字 ABC,因此在这种情况下可以进行更好的转换。对于 SymPy 的 Float 没有什么好方法,因为 Real ABC 除了将浮点类型转换为 float 之外,没有提供任何方式来互操作浮点类型。 :
https://docs.python.org/3/library/numbers.html#numbers.Real
https://bugs.python.org/issue43602#msg391183
您可以通过转动 Float 手动执行此操作。进入 Rational并将分子和分母提取为整数,其中 np.longdouble可以处理:
In [28]: M = Matrix([[sqrt(5), sqrt(7)]])

In [29]: Mfr = M.applyfunc(lambda e: Rational(N(e, 19)))

In [30]: Mfr
Out[30]:
⎡10312043428088987147 24402748658945006457⎤
⎢──────────────────── ────────────────────⎥
⎣4611686018427387904 9223372036854775808 ⎦

In [31]: Mnum = Mfr.applyfunc(lambda e: e.numerator)

In [32]: Mden = Mfr.applyfunc(lambda e: e.denominator)

In [33]: Mnum
Out[33]: [10312043428088987147 24402748658945006457]

In [34]: Mden
Out[34]: [4611686018427387904 9223372036854775808]

In [35]: to_np = lambda A: np.array([[int(e) for e in row] for row in A.tolist()], dtype=np.longdouble)

In [36]: a = to_np(Mnum) / to_np(Mden)

In [37]: a
Out[37]: array([[2.236067977499789696, 2.64575131106459059 ]], dtype=float128)

关于python - 将 SymPy 表达式转换为 SymPy longdoubles 的精度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68100807/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com