5.16 numpy exercise




import numpy as np
from scipy.linalg import toeplitz
import time

toep = list(i for i in range(1,501))
A = np.random.normal(size= (200, 500))

# Exercise 9.1: Matrix operations
def fun1(A, B, lam):
    tmp = B - lam* np.eye(B.shape[0], B.shape[1])
    return np.dot(A, tmp)

B = toeplitz(toep)
print("A is:")
print(A)
print("\nB is:")
print(B)
print("\nA+A is:")
print(A+A)
print("\nA*A.T is:")
print(np.dot(A, A.T))
print("\nA.T*A is:")
print(np.dot(A.T, A))
print("\nA*B is:")
print(np.dot(A,B))

print("fun1 test:")
print(fun1(A,B, 0.5))


# Exercise 9.2: Solving a linear system
# 先用no.linalg.inv求逆,再相乘
def fun2(B, b):
    return np.dot(np.linalg.inv(B) ,b)

b = np.linspace(0,1,500)
print("\n求Bx = b的解:")
print(fun2(B, b))



用numpy.linalg中的svd分解,返回3个参数,中间的sigma即为由特征值组成的向量。

# Exercise 9.3: Norms
# 求A的范数
print("\nA的范数", np.linalg.norm(A))
# 求B的无穷范数
print("\nB的无穷范数:", np.linalg.norm(B, np.inf))
u, sigma, v = np.linalg.svd(B)

print("\n最大特征值:", max(sigma))
print("最小特征值:", min(sigma))

结果如图所示



幂迭代方法,如图所示,摘自数值方法第四版第一章关于幂方法求最大特征值和特征向量的



import numpy as np
import time

def power_ite(Z):
    start_time = time.clock()
    eigen_vector = np.ones((200,1))
    y = np.dot(Z, eigen_vector)

    eigen_value = y[0, 0]
    maxium = abs(y[0, 0])
    i = 1
    while i < y.size:
       if abs(y[i, 0]) > maxium:
           eigen_value = y[i, 0]
           maxium = abs(y[i, 0])
       i += 1
    eigen_vector = y / eigen_value
    last_eigen = eigen_value + 10e-4
    diff = abs(eigen_value - last_eigen)
    cnt = 1
    while diff >= 10e-5:
        cnt += 1
        y = np.dot(Z, eigen_vector)
        last_eigen = eigen_value
        eigen_value = y[0, 0]
        maxium = abs(y[0, 0])
        i = 1
        while i < y.size:
            if abs(y[i, 0]) > maxium:
                eigen_value = y[i, 0]
                maxium = abs(y[i, 0])
            i += 1
        eigen_vector = y / eigen_value
        diff = abs(eigen_value - last_eigen)

    return cnt, eigen_vector, eigen_value, time.clock() - start_time


Z = np.random.randn(200, 200)
# Z = np.random.normal(size=(200,200))

cnt, eigen_vector_z, eigen_value, using_time = power_ite(Z)

print("eigen vector:")
print(eigen_vector_z)
print("iteration counter:", cnt)
print("eigen value:", eigen_value)
print("time uesd:",using_time)


输出如图所示。特征向量过长就不展示了。当然这个迭代方法有一定几率会无法收敛。




# Exercise 9.5: Singular values
n = 100
t, p = 1, 0.7
C = np.random.binomial(t, p, (n,n))
u, sigma, v = np.linalg.svd(C)
largest_singular_value = max(sigma)
print("largest singular value:",largest_singular_value)
print("p:",p)
print("n:",n)
t, p = 1, 0.4
C = np.random.binomial(t, p, (n,n))
u, sigma, v = np.linalg.svd(C)
largest_singular_value = max(sigma)
print("largest singular value:",largest_singular_value)
print("p:",p)
print("n:",n)
n = 200
t, p = 1, 0.7
C = np.random.binomial(t, p, (n,n))
u, sigma, v = np.linalg.svd(C)
largest_singular_value = max(sigma)
print("largest singular value:",largest_singular_value)
print("p:",p)
print("n:",n)

# 规律np = largest singular value

结果如图所示


可以观察发现,最大特征值≈n*p




按照提示,使用numpy.argmin()

查找文档得知,argmin接收一个(多维)数组,返回这个数组中最小数的下标。另外可以使用参数指定返回下标的格式,默认是返回平面化的一维数组下标。之后可以用numpy.unralvel_index转换成对应在原数组中的坐标。


# Exercise 9.6: Nearest neighbor
def fun_9_6(A, z):
    tmp = abs(A - z)
    ind = np.unravel_index(np.argmin(tmp, axis=None), tmp.shape)
    return A[ind]

A = np.random.normal(size= (5, 10))
print(A)
print("The closest number to", 0.03, "in A is:",fun_9_6(A,0.03))


输出如图所示


验证正确。

猜你喜欢

转载自blog.csdn.net/control_xu/article/details/80383806