python矩阵与numpy矩阵.我究竟做错了什么?

Hum*_*ood 2 python numpy

我正在用Python试验一些3d渲染.我一直在读Python,太慢了!我只是必须利用Numpy的C-awesomeness来完成我在着色器中无法做到的所有矩阵事物!否则什么都行不通,yadda,yadda(在这里解释......).

但是:我做了一些测试!

这是一个随机矩阵,曾经是Numpy-flavor:

matrix1 = numpy.matrix([[1, 1, 0, 0,], [0, 1, 0, 0], [0, 0, 1, 1], [0, 0, 0, 1]])
>>> matrix([[1, 1, 0, 0],
            [0, 1, 0, 0],
            [0, 0, 1, 1],
            [0, 0, 0, 1]])
Run Code Online (Sandbox Code Playgroud)

曾经作为沼泽标准元组:

matrix2 = (1, 1, 0, 0,\
      0, 1, 0, 0,\
      0, 0, 1, 1,\
      0, 0, 0, 1)
Run Code Online (Sandbox Code Playgroud)

现在,如果我想要反过来,我可以在Numpy中做到:

def inv_1():
    return matrix1.I
Run Code Online (Sandbox Code Playgroud)

或者作为纯Python(我省略了一些数学因为它伤害了我的脑袋):

def inv_2():
    m0, m1, m2, m3, \
    m4, m5, m6, m7, \
    m8, m9, m10, m11, \
    m12, m13, m14, m15 = matrix2

    A0 = (( m0 *  m5) - ( m1 *  m4))  ....
 ...B5 = ((m10 * m15) - (m11 * m14))

    det = 1.0 / det
    return (
        (+ ( m5 * B5) - ( m6 * B4) + ( m7 * B3)) * det, ...
     ...(+ ( m8 * A3) - ( m9 * A1) + (m10 * A0)) * det
    )
Run Code Online (Sandbox Code Playgroud)

两者都很好:

inv_1()
>>>> matrix([[ 1., -1.,  0.,  0.],
             [ 0.,  1.,  0.,  0.],
             [ 0.,  0.,  1., -1.],
             [ 0.,  0.,  0.,  1.]])

inv_2()
>>>> (1.0, -1.0, 0.0, 0.0, 
      0.0, 1.0, 0.0, 0.0, 
      0.0, 0.0, 1.0, -1.0,
      0.0, 0.0, 0.0, 1.0)   (I added the line-breaks here for clarity)
Run Code Online (Sandbox Code Playgroud)

但纯Python代码的运行速度始终比备受好评的Numpy快十倍:

timeit.timeit(inv_1, number=100000)
>>>> 3.0659120082855225

timeit.timeit(inv_2, number=100000)
>>>> 0.4014430046081543
Run Code Online (Sandbox Code Playgroud)

如果你添加将我漂亮的元组矩阵转换为Numpy矩阵的开销,它将会更慢.

那么这里发生了什么?难道我做错了什么?是否都是由于调用C函数的开销?我偷了反转代码的家伙违反了物理定律吗?

谢谢你让我退缩!爱你们!

mgi*_*son 7

你正在分析地反转矩阵(这是可能的,因为你知道尺寸,因为它们不是太大).numpy必须使用其他(数值)算法反转矩阵,如果矩阵是4x4以及10000x10000,则该算法可以工作.换句话说,一般问题比你拥有的简单4x4案例困难得多.

  • @ThaneBrimhall - 是的,但是,我有点担心"分析"版本在数字上实现时可能不是数值稳定的(除非作者以某种形式的旋转构建)...虽然,它已经有一段时间了我已经使用过任何矩阵反演算法,所以我的记忆可能会有点生疏...... (4认同)