Generate matrices A, with random Gaussian entries, B, a Toeplitz matrix, where A ∈ R n×m and B ∈ R m×m , for n = 200, m = 500.
import numpy as np
from scipy.linalg import toeplitz
def main():
n = 200
m = 500
A = np.asmatrix(np.random.normal(10,0.1,(n,m)))
B = toeplitz(range(m))
print("A =")
print(A)
print("B =")
print(B)
if __name__ == "__main__":
main()
输出
A =
[[ 9.94186462 10.05140128 9.87265521 ... 9.95895018 10.00338756
10.07937725]
[ 9.94187758 10.18091082 9.85461275 ... 10.11452693 9.97987467
10.12605741]
[10.15649595 10.03904471 9.93678092 ... 10.15058251 10.01907891
9.9783559 ]
...
[10.16156542 9.88539033 9.90841392 ... 10.02714359 9.88436529
10.05041043]
[10.04137656 10.10312934 9.90587997 ... 10.09109832 10.08594594
10.09082619]
[10.03875258 10.0312299 9.98732194 ... 9.87067483 9.97646584
9.88518366]]
B =
[[ 0 1 2 ... 497 498 499]
[ 1 0 1 ... 496 497 498]
[ 2 1 0 ... 495 496 497]
...
[497 496 495 ... 0 1 2]
[498 497 496 ... 1 0 1]
[499 498 497 ... 2 1 0]]
Exercise 9.1: Matrix operations
Calculate A + A, AA > , A > A and AB. Write a function that computes A(B − λI) for any λ.
import numpy as np
from scipy.linalg import toeplitz
def main():
n = 200
m = 500
A=np.asmatrix(np.random.normal(10,0.1,(n,m)))
B=toeplitz(range(m))
print('A + A =')
print(A + A)
print("A * AT =")
print(A * A.T)
print("AT * A =")
print(A.T * A)
def foo(lamb_da):
return A * (B - _lambda * np.identity(m))
_lambda = int(input("lambda ="))
print(foo(_lambda))
if __name__ == "__main__":
main()
输出
A + A =
[[20.35032774 20.08343419 19.78585233 ... 20.03292084 19.65271172
20.131985 ]
[20.02420667 20.19115685 20.33060615 ... 19.57166265 19.9927543
19.68497817]
[19.95848838 20.21328063 19.6544746 ... 20.29099631 19.7901824
19.93780946]
...
[19.65514047 20.02298593 20.09202996 ... 20.05442504 20.1395504
19.96671972]
[19.65758841 19.8959879 20.1061677 ... 20.46638292 19.84632951
19.85667836]
[19.89852582 20.30852369 19.91787167 ... 20.18496843 19.78785214
20.00977736]]
AAT =
[[49991.86970332 49989.48826328 49984.11320619 ... 49940.70962563
50006.14341998 50020.33616987]
[49989.48826328 49998.26626346 49987.12766513 ... 49944.48909893
50009.04335193 50024.06578165]
[49984.11320619 49987.12766513 49985.56358572 ... 49938.53739597
50003.68961847 50018.46177963]
...
[49940.70962563 49944.48909893 49938.53739597 ... 49900.26383682
49960.62799721 49975.31502684]
[50006.14341998 50009.04335193 50003.68961847 ... 49960.62799721
50030.45265898 50040.74143224]
[50020.33616987 50024.06578165 50018.46177963 ... 49975.31502684
50040.74143224 50060.11688783]]
ATA =
[[20013.49433679 20013.54949313 19992.66309631 ... 19999.23236627
19994.05551741 20034.43284611]
[20013.54949313 20018.0111935 19994.54611293 ... 20001.52622754
19996.49231904 20036.45596993]
[19992.66309631 19994.54611293 19975.81905171 ... 19980.62610569
19975.36947904 20015.59791924]
...
[19999.23236627 20001.52622754 19980.62610569 ... 19989.18062339
19981.87186867 20022.12994281]
[19994.05551741 19996.49231904 19975.36947904 ... 19981.87186867
19978.86520347 20017.30032378]
[20034.43284611 20036.45596993 20015.59791924 ... 20022.12994281
20017.30032378 20059.01779107]]
lambda =5
[[1247260.0594858 1242281.76193302 1237323.62453522 ... 1237358.51092724
1242318.99186772 1247296.97681391]
[1246995.61525592 1242015.57308451 1237055.79082213 ... 1237790.31209538
1242749.23063644 1247729.96410125]
[1247038.5691728 1242058.82882604 1237101.33575563 ... 1237454.21461278
1242414.80051021 1247393.5554876 ]
...
[1245985.01216738 1241008.96829498 1236053.69441207 ... 1236381.14832526
1241335.60864097 1246310.85339718]
[1247711.91141824 1242729.68069753 1237767.41651392 ... 1237889.61661226
1242852.75604833 1247834.16580824]
[1248027.20821391 1243043.32212939 1238081.7461933 ... 1238303.91943918
1243267.87421606 1248250.06924132]]
Exercise 9.2: Solving a linear system
Generate a vector b with m entries and solve Bx = b.
import numpy as np
from scipy.linalg import toeplitz
def main():
n = 200
m = 500
A=np.asmatrix(np.random.normal(10,0.1,(n,m)))
B=toeplitz(range(m))
b = np.asmatrix(np.random.random_integers(0, m, (m, 1)))
print(np.linalg.solve(B, b))
if __name__ == "__main__":
main()
Exercise 9.3: Norms
Compute the Frobenius norm of A: kAk F and the infinity norm of B: kBk ∞ . Also find the largest and smallest singular values of B.
import numpy as np
from scipy.linalg import toeplitz
def main():
n = 200
m = 500
A=np.asmatrix(np.random.normal(10,0.1,(n,m)))
B=toeplitz(range(m))
print(np.linalg.norm(A))
print(np.linalg.norm(B, np.inf))
U, S, VT = np.linalg.svd(B)
print(S.max(), S.min())
if __name__ == "__main__":
main()
输出
3162.383288037191
124750.0
86851.66898467168 0.5000049348346778
Exercise 9.4: Power iteration
Generate a matrix Z, n × n, with Gaussian entries, and use the power iteration to find the largest eigenvalue and corresponding eigenvector of Z. How many iterations are needed till convergence? Optional: use the time.clock() method to compare computation time when varying n.
import numpy as np
import time
def main():
n = 100
while(n < 1000):
Z = np.asmatrix(np.random.normal(10, 0.1, (n, n)))
start = time.clock()
eigvals, eigvts = np.linalg.eig(Z, )
end = time.clock()
eigvts = eigvts.T
iteration = zip(eigvals, eigvts)
maxi = eigvals[0], eigvts[0]
for item in iteration:
if item[0] > maxi[0]:
maxi = item
print("largest eigenvalue:", maxi[0])
print("corresponding eigenvector:", maxi[1])
print(n, "time:", end - start)
n += 100
if __name__ == "__main__":
main()
Exercise 9.5: Singular values
Generate an n × n matrix, denoted by C, where each entry is 1 with probability p and 0 otherwise. Use the linear algebra library of Scipy to compute the singular values of C. What can you say about the relationship between n, p and the largest singular value?
import numpy as np
import random
import scipy.linalg
def main():
for i in range(10):
n = random.randint(300, 500)
p = random.random()
C = np.asmatrix(np.random.binomial(1, p, (n, n)))
print("n=",n,"p=",p, "n*p=",n*p, "SV=",scipy.linalg.svd(C)[1].max())
if __name__ == "__main__":
main()
输出
n= 471 p= 0.5423822047761114 n*p= 255.46201844954848 SV= 256.1076541092697
n= 303 p= 0.6777353889503704 n*p= 205.35382285196224 SV= 205.903354787994
n= 406 p= 0.8264185783699588 n*p= 335.52594281820325 SV= 336.3931485004287
n= 423 p= 0.4931134658194686 n*p= 208.58699604163522 SV= 209.58767982918746
n= 418 p= 0.9956879662117939 n*p= 416.1975698765298 SV= 416.1911186261932
n= 486 p= 0.11130218426023619 n*p= 54.09286155047479 SV= 55.16596387353942
n= 426 p= 0.3632316821643655 n*p= 154.73669660201972 SV= 156.1114002871462
n= 396 p= 0.035523460879627766 n*p= 14.067290508332595 SV= 14.910426251552508
n= 499 p= 0.6678216390556562 n*p= 333.24299788877244 SV= 333.292566140136
n= 332 p= 0.7772912948005953 n*p= 258.06070987379763 SV= 258.2346706889625
Exercise 9.6: Nearest neighbor
Write a function that takes a value z and an array A and finds the element in A that is closest to z. The function should return the closest value, not index.
import numpy as np
def main(n,A):
z = n
A = np.fabs(A - np.asarray([np.ones(n) * z for i in range(n)]))
index = np.argmin(A)
print(z, A[index // n, index % n] + z)