numpy 的对称矩阵

发布于 2024-11-11 18:30:56 字数 405 浏览 3 评论 0原文

from random import *
N = 100
gamma = 0.7
connect = zeros((N,N))

for i in range(N):
    for j in range(i+1):
        if random() < gamma:
            connect[i,j] = 1
            connect[j,i] = 1
        else:
            connect[i,j] = 0
            connect[j,i] = 0

我尝试做的是创建一个对称矩阵,用 0 和 1 填充(概率为 0.7 的)。 这是双 for 循环,非常低效...我将用 numpy 做一些东西,我相信这可以大大加快速度? 有谁知道如何进行? 非常感谢!

from random import *
N = 100
gamma = 0.7
connect = zeros((N,N))

for i in range(N):
    for j in range(i+1):
        if random() < gamma:
            connect[i,j] = 1
            connect[j,i] = 1
        else:
            connect[i,j] = 0
            connect[j,i] = 0

What I try to do is to create a symmetrical matrix, filled with zeros and ones (ones with a probability of 0.7).
Here is the double for loop, very inefficient...I shall make something with numpy, which I believe could speed up thing a great deal?
Does anyone know how to proceed?
Thank you very much!

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

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

发布评论

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

评论(1

ぃ弥猫深巷。 2024-11-18 18:30:56

您可以使用 numpy random 模块生成随机向量,并使用这些向量作为矩阵的种子。例如:

import numpy as np

N = 100
gamma = 0.7
connect = np.zeros((N,N),dtype=np.int32)

for i in range(0,N):
        dval = np.diag((np.random.random_sample(size=(N-i))<gamma).astype(np.int32),i)
        connect += dval
        if (i>0):
                connect += dval.T

使用 numpy.diag 对角线执行此操作,但您可以按行执行此操作以组装上三角部分或下三角部分,然后使用加法形成对称矩阵。我不知道哪个可能更快。


编辑
事实上,这个行方式版本比对角版本快大约 5 倍,考虑到它使用的内存访问模式与对角汇编相比,我想这应该不足为奇。

N = 100
gamma = 0.7
connect = np.zeros((N,N),dtype=np.int32)

for i in range(0,N):
    rval = (np.random.random_sample(size=(N-i))<gamma).astype(np.int32)
    connect[i,i:] = rval

connect += np.triu(connect,1).T

EDIT 2

这比上面的 row-wise 版本更简单,速度大约是 4 倍。这里,三角矩阵直接由完整的权重矩阵形成,然后添加到其转置以生成对称矩阵:

N = 100
gamma = 0.7
a=np.triu((np.random.random_sample(size=(N,N))<gamma).astype(np.int32))
connect = a + np.triu(a,1).T

在我测试的 Linux 系统上,版本 1 大约需要 6.5 毫秒,版本 2 大约需要 1.5 毫秒,版本 3大约需要 450 微秒。

You could use the numpy random module to generate random vectors, and use those vectors to seed the matrix. For example:

import numpy as np

N = 100
gamma = 0.7
connect = np.zeros((N,N),dtype=np.int32)

for i in range(0,N):
        dval = np.diag((np.random.random_sample(size=(N-i))<gamma).astype(np.int32),i)
        connect += dval
        if (i>0):
                connect += dval.T

does this diagonally using numpy.diag, but you could do it row-wise to assemble the upper or lower triangular portion, then use addition to form the symmetrical matrix. I don't have a feeling for which might be faster.


EDIT:
In fact this row wise version is about 5 times faster than the diagonal version, which I guess shouldn't be all that surprising given the memory access patterns it uses compared to diagonal assembly.

N = 100
gamma = 0.7
connect = np.zeros((N,N),dtype=np.int32)

for i in range(0,N):
    rval = (np.random.random_sample(size=(N-i))<gamma).astype(np.int32)
    connect[i,i:] = rval

connect += np.triu(connect,1).T

EDIT 2

This is even simpler and about 4 times faster than the row-wise version above. Here a triangular matrix is formed directly from a full matrix of weights, then added to its transpose to produce the symmetric matrix:

N = 100
gamma = 0.7
a=np.triu((np.random.random_sample(size=(N,N))<gamma).astype(np.int32))
connect = a + np.triu(a,1).T

On the Linux system I tested it on, version 1 takes about 6.5 milliseconds, version 2 takes about 1.5 milliseconds, version 3 takes about 450 microseconds.

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