【问题标题】:Modular matrix inversion with large number大数模矩阵求逆
【发布时间】:2014-09-02 07:13:27
【问题描述】:

我正在尝试找到一种模块化矩阵求逆的方法。我找到了代码here

def generalizedEuclidianAlgorithm(a, b):
    if b > a:
        #print a, b
        return generalizedEuclidianAlgorithm(b,a);
    elif b == 0:
        return (1, 0);
    else:
        #print a,b
        (x, y) = generalizedEuclidianAlgorithm(b, a % b);
        return (y, x - (a / b) * y)

def inversemodp(a, p):
    a = a % p
    if (a == 0):
        print "a is 0 mod p"
        return 0
    (x,y) = generalizedEuclidianAlgorithm(p, a % p);
    return y % p

def identitymatrix(n):
    return [[long(x == y) for x in range(0, n)] for y in range(0, n)]

def inversematrix(matrix, q):
    n = len(matrix)
    A = np.matrix([[ matrix[j, i] for i in range(0,n)] for j in range(0, n)], dtype = long)
    Ainv = np.matrix(identitymatrix(n), dtype = long)
    for i in range(0, n):
        factor = inversemodp(A[i,i], q)
        A[i] = A[i] * factor % q
        Ainv[i] = Ainv[i] * factor % q
        for j in range(0, n):
            if (i != j):
                factor = A[j, i]
                A[j] = (A[j] - factor * A[i]) % q
                Ainv[j] = (Ainv[j] - factor * Ainv[i]) % q
                # print A, Ainv
                # print i, j, factor
    return Ainv

当我用小素数 q 和矩阵元素进行测试时,结果是正确的。但是,当我使用大素数 q 和包含大元素(例如 1024 位)的矩阵进行测试时,它会打印出错误:

A = np.matrix([[ matrix[j, i] for i in range(0,n)] for j in range(0, n)], dtype = long)

File "C:\Python27\lib\site-packages\numpy\matrixlib\defmatrix.py", line 257, in __new__

arr = N.array(data, dtype=dtype, copy=copy)

是因为 np.matrix 的 dtype 吗?如果是这样,为什么“长”数据类型不能支持这种情况?

你能告诉我如何解决这个错误吗?提前致谢

【问题讨论】:

  • 手工制作有什么理由吗?使用 scipy 包中的 numpy 库。您尝试做的很多事情已经在那里实施和优化。
  • dtype=long 被转换为固定宽度的整数 dtype(例如我的机器上的 int64)。你可能想要dtype=object
  • @Jesuisme 我不认为 numpy 支持模块化矩阵求逆
  • @MarkDickinson:谢谢。当我更改为 dtype=object 时,会导致以下错误:-A[i] = A[i] * factor % q, -Ainv[i] = Ainv[i] * factor % q, -A[j] = (A[j] - 因子 * A[i]) % q, -Ainv[j] = (Ainv[j] - 因子 * Ainv[i]) % q
  • 有趣。看起来这是 NumPy 中的一个错误。我可以用 NumPy 1.6.2 重现您的问题,但不能用 NumPy 1.8.1 重现您的问题。见github.com/numpy/numpy/issues/2469。一种解决方法是使用numpy.array 而不是numpy.matrix,这意味着您需要使用numpy.dot 来进行矩阵乘法。在 NumPy 中避免使用matrix 类型的原因有很多;看起来你刚刚找到了另一个。 :-)

标签: python numpy matrix


【解决方案1】:

我刚刚发现 np.array 会导致很多问题。一种解决方案是将矩阵视为二维列表。以下是我的代码

def generalizedEuclidianAlgorithm(a, b):
    if b > a:
        return generalizedEuclidianAlgorithm(b,a);
    elif b == 0:
        return (1, 0);
    else:
        (x, y) = generalizedEuclidianAlgorithm(b, a % b);
        return (y, x - (a / b) * y)

def inversemodp(a, p):
    a = a % p
    if (a == 0):
        print "a is 0 mod p"
        return 0
    (x,y) = generalizedEuclidianAlgorithm(p, a % p);
    return y % p

def identitymatrix(n):
    return [[long(x == y) for x in range(0, n)] for y in range(0, n)

def multiply_vector_scalar (vector, scalar, q):
    kq = []
    for i in range (0, len(vector)):
        kq.append (vector[i] * scalar %q)
    return kq

def minus_vector_scalar1(vector1, scalar, vector2, q):
    kq = []
    for i in range (0, len(vector1)):
        kq.append ((vector1[i] - scalar * vector2[i]) %q)
    return kq

def inversematrix1(matrix, q):
    n = len(matrix)

    A =[]
    for j in range (0, n):
        temp = []
        for i in range (0, n):
            temp.append (matrix[j][i])
        A.append(temp)

    Ainv = identitymatrix(n)

    for i in range(0, n):
        factor = inversemodp(A[i][i], q)
        A[i] = multiply_vector_scalar(A[i],factor,q)
        Ainv[i] = multiply_vector_scalar(Ainv[i],factor,q)
        for j in range(0, n):
            if (i != j):
                factor = A[j][i]
                A[j] = minus_vector_scalar1(A[j],factor,A[i],q)
                Ainv[j] = minus_vector_scalar1(Ainv[j],factor,Ainv[i],q)
    return Ainv

【讨论】:

  • 注意:identitymatrix 在列表理解中缺少结束 ]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
  • 2011-08-30
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 2017-11-24
相关资源
最近更新 更多