Numpy 用scipy求解稀疏复杂线性系统

Numpy 用scipy求解稀疏复杂线性系统,numpy,scipy,sparse-matrix,Numpy,Scipy,Sparse Matrix,下午好 我正在开发一些数字代码,关键是我需要解一个稀疏线性系统。我已经用真正的浮点数设置和测试了所有这些。当我需要解一个系统Ax=b时,就会出现这个问题,其中a是稀疏实矩阵(用scipy以CSR格式存储)和复杂的RHS b,存储为numpy数组。当我求解系统时,我只得到解的真实值以及警告 /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/core/numeric.py:460:

下午好

我正在开发一些数字代码,关键是我需要解一个稀疏线性系统。我已经用真正的浮点数设置和测试了所有这些。当我需要解一个系统Ax=b时,就会出现这个问题,其中a是稀疏实矩阵(用scipy以CSR格式存储)和复杂的RHS b,存储为numpy数组。当我求解系统时,我只得到解的真实值以及警告

 /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/core/numeric.py:460: 
 ComplexWarning: Casting complex values to real discards the imaginary part 
 return array(a, dtype, copy=False, order=order)
下面是一个简单的工作示例:

 import numpy as np
 import scipy.sparse.linalg
 import scipy.sparse

 A = scipy.sparse.csr_matrix([[1, 2, 0], [0, 0, 3], [4, 0, 5]])

 b = np.array([1,1,1]) +1j*np.array([1,1,1])

 # throws warning and returns erroneous result
 x_complex = scipy.sparse.linalg.spsolve(A,b) 
这是个棘手的问题还是我做错了什么?有可能的解决办法吗?任何帮助都将不胜感激


编辑:我找到了一个解决方法,我们可以只解两个具有真实右手边的线性系统(做一件显而易见的事情,将RHS分解为实部和虚部)。但是有没有更好的方法?这会使代码变得不那么清晰。

解算器试图将矩阵和右侧转换为相同的数据类型,以便进行计算。因为涉及复数,所以应该将它们转换为复数,但出于某种原因,它试图转换为实浮点数(一个bug?或者只是假设矩阵的数据类型是要使用的)。创建一个复杂数据类型解决了以下问题:

A = scipy.sparse.csr_matrix([[1, 2, 0], [0, 0, 3], [4, 0, 5]], dtype=np.cfloat)
现在解算器返回正确的解

[-0.16666667-0.16666667j  0.58333333+0.58333333j  0.33333333+0.33333333j]

解算器试图将矩阵和右侧强制转换为相同的数据类型,以便进行计算。因为涉及复数,所以应该将它们转换为复数,但出于某种原因,它试图转换为实浮点数(一个bug?或者只是假设矩阵的数据类型是要使用的)。创建一个复杂数据类型解决了以下问题:

A = scipy.sparse.csr_matrix([[1, 2, 0], [0, 0, 3], [4, 0, 5]], dtype=np.cfloat)
现在解算器返回正确的解

[-0.16666667-0.16666667j  0.58333333+0.58333333j  0.33333333+0.33333333j]

在您的示例中,
b
是真实的,
A
是复杂的,与您所描述的相反。@hpaulj D'oh,我的糟糕。我现在就来解决它。@zaq我不小心在我的示例中切换了问题所在的位置,b应该是复杂的,A应该是真实的。我修改了这个示例以反映这一点。在您的示例中,
b
是真实的,
A
是复杂的,与您描述的相反。@hpaulj D'oh,我的错。我现在就来解决它。@zaq我不小心在我的示例中切换了问题所在的位置,b应该是复杂的,A应该是真实的。我修正了这个例子来反映这一点。嗯,这很好,但是当A是复杂的,b是真实的情况下呢?我希望这是一个尽可能灵活的解算器,因为有时我的RHS将是真实的,而其他时候它将是复杂的,我希望输出与输入是相同的类型。也许我会在他们的Github上打开一个问题,看看它是否可以修复。拥有real RHS不是问题,因为real可以无问题地转换为complex。声明A with
dtype=np.cfloat
允许您在系统中的任何地方使用复数,或者在任何地方都不使用复数。是的,我知道它会起作用并产生正确的结果,但如果我通过一个复杂的RHS,我的解是复杂的,而当我通过一个真正的RHS,我的解是真正的dtype,不用我手动检查并从一个转换到另一个。嗯,这很好,但是当A是复杂的,b是真实的情况下呢?我希望这是一个尽可能灵活的解算器,因为有时我的RHS将是真实的,而其他时候它将是复杂的,我希望输出与输入是相同的类型。也许我会在他们的Github上打开一个问题,看看它是否可以修复。拥有real RHS不是问题,因为real可以无问题地转换为complex。声明A with
dtype=np.cfloat
允许您在系统中的任何地方使用复数,或者在任何地方都不使用复数。是的,我知道它会起作用并产生正确的结果,但如果我通过一个复杂的RHS,我的解是复杂的,而当我通过一个真正的RHS,我的解是真正的dtype,无需我手动检查并从一个转换到另一个。