Python numpy:通过反向计算维护十进制类

Python numpy:通过反向计算维护十进制类,python,numpy,decimal,Python,Numpy,Decimal,我试图找到由特定类(decimal.decimal)组成的矩阵的逆矩阵,并在整个过程中将这些值作为十进制对象保留(以在整个计算过程中保持精确性) 我的问题是numpy.linalg.inverse总是以浮点形式返回矩阵值。我已经找到了一个解决办法,在计算逆矩阵后,将类型从浮点数更改为十进制对象,但我更愿意始终保持原始矩阵的类(我担心当数字转换为浮点数时可能会失去准确性) 所以我想我有几个问题:(1)当矩阵的值被转换成浮点类型时,我是否失去了准确性/精确性(我处理的是一个11乘11的矩阵);如果是

我试图找到由特定类(
decimal.decimal
)组成的矩阵的逆矩阵,并在整个过程中将这些值作为十进制对象保留(以在整个计算过程中保持精确性)

我的问题是
numpy.linalg.inverse
总是以浮点形式返回矩阵值。我已经找到了一个解决办法,在计算逆矩阵后,将类型从浮点数更改为十进制对象,但我更愿意始终保持原始矩阵的类(我担心当数字转换为浮点数时可能会失去准确性)

所以我想我有几个问题:(1)当矩阵的值被转换成浮点类型时,我是否失去了准确性/精确性(我处理的是一个11乘11的矩阵);如果是这样,(2)在使用
numpy
的整个计算过程中,是否仍然可以将值保持为
decimal.decimal
;如果不是,(3)是否有另一个模块/方法,我应该考虑这种类型的计算?< /P> 下面是我的代码的示例:

import numpy as np
from decimal import Decimal as D

a = np.array( [ [D('1'), D('2'), D('3')],
                [D('4'), D('5'), D('6')],
                [D('7'), D('8'), D('9')] ] )

print type(a[0,0])
# <class 'decimal.Decimal'>

inverse_a = np.linalg.inv(a)

print type(inverse_a[0,0])
# <type 'numpy.float64'>

inverse_a_Decimal_flat = [D(str(i)) for i in inverse_a.flat]  # change all values to decimal.Decimal
inverse_a_Decimal = np.reshape(inverse_a_Decimal_flat, [3, 3])  # reshape to 3x3

print type(inverse_a_Decimal[0,0]), d.shape
# <class 'decimal.Decimal'> (3,3)
将numpy导入为np
从十进制输入十进制为D
a=np.array([[D('1')、D('2')、D('3')]),
[D('4')、D('5')、D('6')],
[D('7')、D('8')、D('9')]]
打印类型(a[0,0])
# 
逆a=np.linalg.inv(a)
打印类型(反向_a[0,0])
# 
反求反求(Decimal)(Decimal)flat=[D(str(i))表示反求反求反求中的i]#将所有值更改为Decimal.Decimal
逆十进制=np。整形(逆十进制平面[3,3])整形为3x3
打印类型(反十进制[0,0]),d形
#  (3,3)

您的
a
是一个对象数组:

In [255]: a
Out[255]: 
array([[Decimal('1'), Decimal('2'), Decimal('3')],
       [Decimal('4'), Decimal('5'), Decimal('6')],
       [Decimal('7'), Decimal('8'), Decimal('9')]], dtype=object)
在我最新更新的
numpy
中,我尝试进行反向操作时出错

In [257]: np.linalg.inv(a)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-257-5c2063aa5f16> in <module>()
----> 1 np.linalg.inv(a)

/usr/local/lib/python3.5/dist-packages/numpy/linalg/linalg.py in inv(a)
    524     signature = 'D->D' if isComplexType(t) else 'd->d'
    525     extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 526     ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
    527     return wrap(ainv.astype(result_t, copy=False))
    528 

TypeError: No loop matching the specified signature and casting
was found for ufunc inv
In [258]: np.__version__
Out[258]: '1.11.2'
同样,这是一个如何编译
linalg
的问题

In [269]: a1=np.arange(1,10,dtype=np.double).reshape(3,3)
In [270]: np.linalg.inv(a1)
Out[270]: 
array([[  3.15221191e+15,  -6.30442381e+15,   3.15221191e+15],
       [ -6.30442381e+15,   1.26088476e+16,  -6.30442381e+15],
       [  3.15221191e+15,  -6.30442381e+15,   3.15221191e+15]])
我试图
dot
这个,但没有得到预期的
np.eye
数组。但这是一个近乎奇异的数组(行列式为0,或者差不多如此)

所以这是一个坏例子

将值洗牌到数组不再是单数的

In [288]: a1=np.array([[3,1,2],[4,6,5],[8,9,7]],np.float)
In [289]: a1.dot(np.linalg.inv(a1))
Out[289]: 
array([[  1.00000000e+00,   0.00000000e+00,   2.22044605e-16],
       [ -4.44089210e-16,   1.00000000e+00,   4.44089210e-16],
       [  0.00000000e+00,   0.00000000e+00,   1.00000000e+00]])
如果
a1
np.int
,我会得到同样的结果,因为
np.int
被上溯到
float64
。我可以使用
np.float32
进行测试,以查看较低精度的影响。如上所述,我无法转到
longfloat

inv
通常作为
I/a1
线性方程解计算:

In [297]: np.linalg.solve(a1,np.eye(3))
Out[297]: 
array([[ 0.14285714, -0.52380952,  0.33333333],
       [-0.57142857, -0.23809524,  0.33333333],
       [ 0.57142857,  0.9047619 , -0.66666667]])
In [298]: np.linalg.inv(a1)
Out[298]: 
array([[ 0.14285714, -0.52380952,  0.33333333],
       [-0.57142857, -0.23809524,  0.33333333],
       [ 0.57142857,  0.9047619 , -0.66666667]])

您的
a
是一个对象数组:

In [255]: a
Out[255]: 
array([[Decimal('1'), Decimal('2'), Decimal('3')],
       [Decimal('4'), Decimal('5'), Decimal('6')],
       [Decimal('7'), Decimal('8'), Decimal('9')]], dtype=object)
在我最新更新的
numpy
中,我尝试进行反向操作时出错

In [257]: np.linalg.inv(a)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-257-5c2063aa5f16> in <module>()
----> 1 np.linalg.inv(a)

/usr/local/lib/python3.5/dist-packages/numpy/linalg/linalg.py in inv(a)
    524     signature = 'D->D' if isComplexType(t) else 'd->d'
    525     extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 526     ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
    527     return wrap(ainv.astype(result_t, copy=False))
    528 

TypeError: No loop matching the specified signature and casting
was found for ufunc inv
In [258]: np.__version__
Out[258]: '1.11.2'
同样,这是一个如何编译
linalg
的问题

In [269]: a1=np.arange(1,10,dtype=np.double).reshape(3,3)
In [270]: np.linalg.inv(a1)
Out[270]: 
array([[  3.15221191e+15,  -6.30442381e+15,   3.15221191e+15],
       [ -6.30442381e+15,   1.26088476e+16,  -6.30442381e+15],
       [  3.15221191e+15,  -6.30442381e+15,   3.15221191e+15]])
我试图
dot
这个,但没有得到预期的
np.eye
数组。但这是一个近乎奇异的数组(行列式为0,或者差不多如此)

所以这是一个坏例子

将值洗牌到数组不再是单数的

In [288]: a1=np.array([[3,1,2],[4,6,5],[8,9,7]],np.float)
In [289]: a1.dot(np.linalg.inv(a1))
Out[289]: 
array([[  1.00000000e+00,   0.00000000e+00,   2.22044605e-16],
       [ -4.44089210e-16,   1.00000000e+00,   4.44089210e-16],
       [  0.00000000e+00,   0.00000000e+00,   1.00000000e+00]])
如果
a1
np.int
,我会得到同样的结果,因为
np.int
被上溯到
float64
。我可以使用
np.float32
进行测试,以查看较低精度的影响。如上所述,我无法转到
longfloat

inv
通常作为
I/a1
线性方程解计算:

In [297]: np.linalg.solve(a1,np.eye(3))
Out[297]: 
array([[ 0.14285714, -0.52380952,  0.33333333],
       [-0.57142857, -0.23809524,  0.33333333],
       [ 0.57142857,  0.9047619 , -0.66666667]])
In [298]: np.linalg.inv(a1)
Out[298]: 
array([[ 0.14285714, -0.52380952,  0.33333333],
       [-0.57142857, -0.23809524,  0.33333333],
       [ 0.57142857,  0.9047619 , -0.66666667]])
是否可以接受使用

如果我们使用:

>>> import sympy as sy
>>> a = sy.Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> a.inv()
ValueError: Matrix det == 0; not invertible.
我们意识到反转这个矩阵根本没有意义

再次尝试将9替换为10,则

Matrix([
[-2/3, -4/3,  1],
[-2/3, 11/3, -2],
[   1,   -2,  1]])
哪个是所需的无限精度结果。

是否可以使用

如果我们使用:

>>> import sympy as sy
>>> a = sy.Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> a.inv()
ValueError: Matrix det == 0; not invertible.
我们意识到反转这个矩阵根本没有意义

再次尝试将9替换为10,则

Matrix([
[-2/3, -4/3,  1],
[-2/3, 11/3, -2],
[   1,   -2,  1]])

这是所需的无限精度结果。

1。对2.我不知道。3.你试过自己写吗?所以如果是准确的话,我想我可能需要使用
np.longdouble
类型。在准确性方面,这与十进制有什么不同?这听起来需要更长的时间来计算,所以我想知道这是否值得费心
float64
对于计算中的一个步骤可能足够好(我正在计算混合物的化学成分)。如果你想要精确,那么
Decimal
是不够的-你需要
分数。分数
,否则你最终会四舍五入到10的某个(负)幂。你可能想研究一下如何使用无限精度矩阵代数。这个矩阵是不可逆的!对于3x3矩阵,逆矩阵有一个解析表达式。它类似于9 2x2行列式除以完整行列式。检查一个符号数学程序。对2.我不知道。3.你试过自己写吗?所以如果是准确的话,我想我可能需要使用
np.longdouble
类型。在准确性方面,这与十进制有什么不同?这听起来需要更长的时间来计算,所以我想知道这是否值得费心
float64
对于计算中的一个步骤可能足够好(我正在计算混合物的化学成分)。如果你想要精确,那么
Decimal
是不够的-你需要
分数。分数
,否则你最终会四舍五入到10的某个(负)幂。你可能想研究一下如何使用无限精度矩阵代数。这个矩阵是不可逆的!对于3x3矩阵,逆矩阵有一个解析表达式。它类似于9 2x2行列式除以完整行列式。检查一个符号数学程序。我正在使用1.9.3版——我将更新并重试。因此,如果是这种情况,您会建议转换为
float64
或其他数据类型以获得精确性(可能是
np.longdouble
)?知道
float64
np.longdouble
(或
float96
)之间的精确性差异是什么吗?比如每种情况下小数点后有多少点是准确的