Python 绘制 Wigner Matrices

Python 绘制 Wigner Matrices

上随机矩阵暑期课程的时候,老师讲到Wigner Matrices的内容,刚好自己编程水平有限,就试着编程实现了一下。

Wigner Matrices定义:

X N = ( X i j ) X_N =(X_{ij}) XN=(Xij) N × N N×N N×N的对称方阵,对角线及其上元素均为i.i.d. 满足
E X i j = 0 \mathbb{E}X_{ij} = 0 EXij=0 E ∣ X i j ∣ 2 = 1 \mathbb{E} |X_{ij} |^2 = 1 EXij2=1
X i j = X j i X_{ij} = X_{ji} Xij=Xji (对称性).

  • Wigner Matrices的谱为:
    Y N = X N N Y_N = \frac{X_N}{\sqrt{N}} YN=N XN

  • semi-circular 分布为:
    x → 4 − x 2 2 π x \rightarrow \frac{\sqrt{4 - x^2}}{2\pi} x2π4x2

接下来我们绘图来验证半圆率,通俗的理解就是当 N N N取足够大时,绘制上述方阵的特征值会在 [ − 2 , 2 ] [-2,2] [2,2]区间形成半圆,具体理论证明待补.

Wigner’s theorem (1948):
The histogram of a Wigner matrix converges to the semi-circular distribution!

问题:生成期望为0,方差为1的对称矩阵

网上很多关于对称矩阵的程序是简单用

n = 100 #任意整数
A = np.random.randn(n)
B = (A + A^T) / 2

完成的,但实际上,这样得到的样本方差并不是1,样本量足够大的时候是0.5.这样会导致直方图不是在 [ − 2 , 2 ] [-2,2] [2,2]中.

解决方案1:

所以我先生成与方阵上三角元素数量相等的服从N(0,1)的随机数,再通过for循环将元素写进预先生成的零矩阵中,具体程序如下

import numpy as np
import matplotlib.pyplot as plt
n = 1500  # 矩阵的维度
m = (n*n-n)/2+n
X = np.random.randn(int(m))
# print(X)
print('原始生成X的方差是:',np.var(X))

matrix = np.zeros((n, n))  # 创建一个n x n的全零矩阵
k = 0
for i in range(n):
    for j in range(i, n):    #从i开始到n结束
        matrix[i][j] = X[k] # 上三角部分赋值
        k = k+1
matrix += matrix.T - np.diag(matrix.diagonal())
print('生成对称矩阵的方差是:',np.var(matrix))

解决方案2:

一个更为简便的写法,直接进行矩阵分解,待补

绘图部分

鉴于自己总是忘记plt的用法,今天记录详细一些:
首先用

plt.figure(figuresize=(6,6))

确定画布尺寸,这句命令需要在绘图的最开始,否则产生空白画布.
其次,使用

plt.hist(eigenvalue, bins=50, density=True, label='spectrum', edgecolor = 'black')

来绘制直方图,hist是histogram的缩写,第一项参数是需要统计频率的值,bins代表需要绘制的条数,normed = true被移除了,改成density = True,使用edgecolor来指定条与条之间的分割线.
最后,使用

plt.savefig()

来保存图片,该命令需要在plt.show()前,否则会得到一张空白的画布,这是因为show本身产生一张空白画布.

在这里插入图片描述

完整程序

完整程序如下,在电脑上命名为semi-circle_law.py

import numpy as np
import matplotlib.pyplot as plt
n = 1500  # 矩阵的维度
m = (n*n-n)/2+n
X = np.random.randn(int(m))
# print(X)
print('原始生成X的方差是:',np.var(X))

matrix = np.zeros((n, n))  # 创建一个n x n的全零矩阵
k = 0
for i in range(n):
    for j in range(i, n):    #从i开始到n结束
        matrix[i][j] = X[k] # 上三角部分赋值
        k = k+1
matrix += matrix.T - np.diag(matrix.diagonal())
print('生成对称矩阵的方差是:',np.var(matrix))
#绘图
plt.figure(figsize=(6, 6))
Z = np.random.uniform(low=-2,high=2,size=n)
M = np.sqrt(4 - np.power(Z,2)) / (2*np.pi)
plt.scatter(Z,M,c='r')

Y = matrix / np.sqrt(n)
eigenvalue, eigenvector = np.linalg.eig(Y)
plt.hist(eigenvalue, bins=50, density=True, label='spectrum', edgecolor = 'black')
plt.legend()
plt.savefig('/Users/XXX/Desktop/matlab_test/Python/002.png') #需要在plt.show前
plt.show()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值