Numpy:创建对称矩阵类

发布于 2024-11-05 04:01:05 字数 1330 浏览 1 评论 0原文

基于 这个答案 我正在用 numpy 在 python 中为对称矩阵编写一个简单的类,但是我我遇到了(可能是一个非常简单的)问题。这是有问题的代码:

import numpy as np

 class SyMatrix(np.ndarray):
    def __init__(self, arr):
        self = (arr + arr.T)/2.0 - np.diag(np.diag(arr)) 
    def __setitem__(self,(i,j), val):
        np.ndarray.__setitem__(self, (i, j), value)
        np.ndarray.__setitem__(self, (j, i), value)

除了这种感觉错误之外(我不知道分配给 self 是否是一个好的做法......)当我尝试创建一个新数组时,我得到了这个:

>>> foo = SyMatrix( np.zeros(shape = (2,2)))
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: only length-1 arrays can be converted to Python scalars

我也尝试过:

import numpy as np

 class SyMatrix(np.ndarray):
    def __init__(self, n):
        self =  np.zeros(shape = (n,n)).view(SyMatrix)  
    def __setitem__(self,(i,j), val):
        np.ndarray.__setitem__(self, (i, j), value)
        np.ndarray.__setitem__(self, (j, i), value)

然后我得到:

>>> foo = SyMatrix(2)
>>> foo
SyMatrix([  6.93581448e-310,   2.09933710e-316])
>>> 

我期望一个带有 shape=(2,2) 的数组。做我想做的事情的正确方法是什么?分配给 self 有问题吗?

based on this answer I was coding a simple class for symmetric matrices in python with numpy, but I'm having (probably a very simple) problem. This is the problematic code:

import numpy as np

 class SyMatrix(np.ndarray):
    def __init__(self, arr):
        self = (arr + arr.T)/2.0 - np.diag(np.diag(arr)) 
    def __setitem__(self,(i,j), val):
        np.ndarray.__setitem__(self, (i, j), value)
        np.ndarray.__setitem__(self, (j, i), value)

Besides this feeling wrong (I don't know if assigning to self is a good practice...) When I try to create a new array I get this:

>>> foo = SyMatrix( np.zeros(shape = (2,2)))
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: only length-1 arrays can be converted to Python scalars

I also tried:

import numpy as np

 class SyMatrix(np.ndarray):
    def __init__(self, n):
        self =  np.zeros(shape = (n,n)).view(SyMatrix)  
    def __setitem__(self,(i,j), val):
        np.ndarray.__setitem__(self, (i, j), value)
        np.ndarray.__setitem__(self, (j, i), value)

And then I get:

>>> foo = SyMatrix(2)
>>> foo
SyMatrix([  6.93581448e-310,   2.09933710e-316])
>>> 

where I expected an array with shape=(2,2). What's the correct way to do what I'm trying to do? Is assigning to self problematic?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南冥有猫 2024-11-12 04:01:05

这里有几个问题。

  1. 子类化numpy.ndarray(),您应该覆盖__new__(),而不是__init__()。你的线路

    foo = SyMatrix(2)
    

    实际上是用参数2调用numpy.ndarray.__new__(),与其签名

  2. 分配给self在这里绝对没有任何作用。它只是创建一个对象并使本地名称 self 指向该对象。一旦函数退出,所有本地名称都会被删除。 Python 中的赋值既不创建变量,也不改变对象;它只是为现有对象分配一个名称。

  3. 即使解决了最后两个问题,您的对称矩阵类也不会按预期工作。实际上,您需要覆盖数十种方法才能确保矩阵始终对称。

  4. (arr + arr.T)/2.0 - np.diag(np.diag(arr)) 很可能不是您想要的。对角线上总是有零。您可能需要 (arr + arr.T)/2.0

There are a few issues here.

  1. When subclassing numpy.ndarray(), you should overwrite __new__(), not __init__(). Your line

    foo = SyMatrix(2)
    

    actually calls numpy.ndarray.__new__() with the parameter 2, incompatible with its signature.

  2. Assigning to self does absolutely nothing here. It just creates an object and makes the local name self point to this object. As soon as the function exits, all local names are dropped. Assignment in Python neither creates variables, nor does it alter objects; it just assigns an existing object to a name.

  3. Even when fixing the last two issues, your symmetric matrix class won't work as expected. There are literally dozens of methods you would need to overwrite to ensure that the matrix is always symmetric.

  4. (arr + arr.T)/2.0 - np.diag(np.diag(arr)) most probably isn't what you want. It will always have zeros on the diagonal. You probably want (arr + arr.T)/2.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文