""" U : ma trận U
s : vectơ đường chéo của ma trận Σ
S : ma trận Σ
VT: ma trận chuyển vị của ma trận V """
from scipy import linalg
# Bài 1 ########################################################################
def tinh_svd(A):
"""Tính toán SVD của ma trận A."""
U, s, VT = linalg.svd(A)
# Tạo ma trận S với kích thước phù hợp với U và VT
S = np.zeros((A.shape[0], A.shape[1])) # Ma trận 0 có kích thước của A
S[:A.shape[0], :A.shape[0]] = np.diag(s) # Chèn các giá trị đơn lẻ vào đường chéo chính
return U, S, VT
# Bài 2 ########################################################################
def tinh_compact_svd(A):
"""Tính toán compact SVD của ma trận A."""
# 1. Tìm SVD của ma trận A
U, S, VT = tinh_svd(A)
# 2. Tìm số giá trị λ khác 0 của ma trận A, đặt là r
r = np.count_nonzero(S)
# 3. Giữ lại r hàng và r cột đầu tiên của ma trận Σ để tạo thành Σr
Sr = S[:r, :r]
# 4. Giữ lại r cột đầu tiên của ma trận U để tạo ra Ur
Ur = U[:, :r]
# 5. Giữ lại r hàng đầu tiên của ma trận VT để tạo ra VTr
VTr = VT[:r, :]
return Ur, Sr, VTr
# Bài 3 ########################################################################
def tinh_truncated_svd_k(A, k):
"""Tính toán truncated SVD của ma trận A với k."""
# 1. Tìm SVD của ma trận A
U, S, VT = tinh_svd(A)
# 2. Giữ lại k hàng và k cột đầu tiên của ma trận Σ để tạo thành Σk
Sk = S[:k, :k]
# 3. Giữ lại k cột đầu tiên của ma trận U để tạo ra Uk
Uk = U[:, :k]
# 4. Giữ lại k hàng đầu tiên của ma trận VT để tạo ra VTk
VTk = VT[:k, :]
# 5. Tìm số I từ k
sum_r = np.sum(S**2)
sum_k = np.sum(Sk**2)
I = sum_k/sum_r
return Uk, Sk, VTk, I
# Bài 4 ########################################################################
def tinh_truncated_svd_I(A, I):
"""Tính toán truncated SVD của ma trận A với I."""
# 1. Tìm SVD của ma trận A
U, S, VT = tinh_svd(A)
# 2. Tìm số k từ I
sum_r = np.sum(S**2)
sum_k = 0
i = 0
while sum_k/sum_r < I and i < S.shape[0]:
sum_k += S[i, i]**2
i += 1
k = i
# 3. Giữ lại k hàng và k cột đầu tiên của ma trận Σ để tạo thành Σk
Sk = S[:k, :k]
# 4. Giữ lại k cột đầu tiên của ma trận U để tạo ra Uk
Uk = U[:, :k]
# 5. Giữ lại k hàng đầu tiên của ma trận VT để tạo ra VTk
VTk = VT[:k, :]
return Uk, Sk, VTk, k
IiIiCVUgOiBtYSB0cuG6rW4gVQoJcyA6IHZlY3TGoSDEkcaw4budbmcgY2jDqW8gY+G7p2EgbWEgdHLhuq1uIM6jCglTIDogbWEgdHLhuq1uIM6jCglWVDogbWEgdHLhuq1uIGNodXnhu4NuIHbhu4sgY+G7p2EgbWEgdHLhuq1uIFYgIiIiCgpmcm9tIHNjaXB5IGltcG9ydCBsaW5hbGcKCiMgQsOgaSAxICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwpkZWYgdGluaF9zdmQoQSk6CiAgICAiIiJUw61uaCB0b8OhbiBTVkQgY+G7p2EgbWEgdHLhuq1uIEEuIiIiCiAgICBVLCBzLCBWVCA9IGxpbmFsZy5zdmQoQSkKCiAgICAjIFThuqFvIG1hIHRy4bqtbiBTIHbhu5tpIGvDrWNoIHRoxrDhu5tjIHBow7kgaOG7o3AgduG7m2kgVSB2w6AgVlQKICAgIFMgPSBucC56ZXJvcygoQS5zaGFwZVswXSwgQS5zaGFwZVsxXSkpICAjIE1hIHRy4bqtbiAwIGPDsyBrw61jaCB0aMaw4bubYyBj4bunYSBBCiAgICBTWzpBLnNoYXBlWzBdLCA6QS5zaGFwZVswXV0gPSBucC5kaWFnKHMpICAjIENow6huIGPDoWMgZ2nDoSB0cuG7iyDEkcahbiBs4bq7IHbDoG8gxJHGsOG7nW5nIGNow6lvIGNow61uaAoKICAgIHJldHVybiBVLCBTLCBWVAoKIyBCw6BpIDIgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCmRlZiB0aW5oX2NvbXBhY3Rfc3ZkKEEpOgogICAgIiIiVMOtbmggdG/DoW4gY29tcGFjdCBTVkQgY+G7p2EgbWEgdHLhuq1uIEEuIiIiCgogICAgIyAxLiBUw6xtIFNWRCBj4bunYSBtYSB0cuG6rW4gQQogICAgVSwgUywgVlQgPSB0aW5oX3N2ZChBKQoKICAgICMgMi4gVMOsbSBz4buRIGdpw6EgdHLhu4sgzrsga2jDoWMgMCBj4bunYSBtYSB0cuG6rW4gQSwgxJHhurd0IGzDoCByCiAgICByID0gbnAuY291bnRfbm9uemVybyhTKQoKICAgICMgMy4gR2nhu68gbOG6oWkgciBow6BuZyB2w6AgciBj4buZdCDEkeG6p3UgdGnDqm4gY+G7p2EgbWEgdHLhuq1uIM6jIMSR4buDIHThuqFvIHRow6BuaCDOo3IKICAgIFNyID0gU1s6ciwgOnJdCgogICAgIyA0LiBHaeG7ryBs4bqhaSByIGPhu5l0IMSR4bqndSB0acOqbiBj4bunYSBtYSB0cuG6rW4gVSDEkeG7gyB04bqhbyByYSBVcgogICAgVXIgPSBVWzosIDpyXQoKICAgICMgNS4gR2nhu68gbOG6oWkgciBow6BuZyDEkeG6p3UgdGnDqm4gY+G7p2EgbWEgdHLhuq1uIFZUIMSR4buDIHThuqFvIHJhIFZUcgogICAgVlRyID0gVlRbOnIsIDpdCgogICAgcmV0dXJuIFVyLCBTciwgVlRyCgojIELDoGkgMyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKZGVmIHRpbmhfdHJ1bmNhdGVkX3N2ZF9rKEEsIGspOgogICAgIiIiVMOtbmggdG/DoW4gdHJ1bmNhdGVkIFNWRCBj4bunYSBtYSB0cuG6rW4gQSB24bubaSBrLiIiIgoKICAgICMgMS4gVMOsbSBTVkQgY+G7p2EgbWEgdHLhuq1uIEEKICAgIFUsIFMsIFZUID0gdGluaF9zdmQoQSkKCiAgICAjIDIuIEdp4buvIGzhuqFpIGsgaMOgbmcgdsOgIGsgY+G7mXQgxJHhuqd1IHRpw6puIGPhu6dhIG1hIHRy4bqtbiDOoyDEkeG7gyB04bqhbyB0aMOgbmggzqNrCiAgICBTayA9IFNbOmssIDprXQoKICAgICMgMy4gR2nhu68gbOG6oWkgayBj4buZdCDEkeG6p3UgdGnDqm4gY+G7p2EgbWEgdHLhuq1uIFUgxJHhu4MgdOG6oW8gcmEgVWsKICAgIFVrID0gVVs6LCA6a10KICAgIAogICAgIyA0LiBHaeG7ryBs4bqhaSBrIGjDoG5nIMSR4bqndSB0acOqbiBj4bunYSBtYSB0cuG6rW4gVlQgxJHhu4MgdOG6oW8gcmEgVlRrCiAgICBWVGsgPSBWVFs6aywgOl0KCiAgICAjIDUuIFTDrG0gc+G7kSBJIHThu6sgawogICAgc3VtX3IgPSBucC5zdW0oUyoqMikKICAgIHN1bV9rID0gbnAuc3VtKFNrKioyKQogICAgSSA9IHN1bV9rL3N1bV9yCgogICAgcmV0dXJuIFVrLCBTaywgVlRrLCBJCgojIELDoGkgNCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKZGVmIHRpbmhfdHJ1bmNhdGVkX3N2ZF9JKEEsIEkpOgogICAgIiIiVMOtbmggdG/DoW4gdHJ1bmNhdGVkIFNWRCBj4bunYSBtYSB0cuG6rW4gQSB24bubaSBJLiIiIgoKICAgICMgMS4gVMOsbSBTVkQgY+G7p2EgbWEgdHLhuq1uIEEKICAgIFUsIFMsIFZUID0gdGluaF9zdmQoQSkKCiAgICAjIDIuIFTDrG0gc+G7kSBrIHThu6sgSQogICAgc3VtX3IgPSBucC5zdW0oUyoqMikKICAgIHN1bV9rID0gMAogICAgaSA9IDAKICAgIHdoaWxlIHN1bV9rL3N1bV9yIDwgSSBhbmQgaSA8IFMuc2hhcGVbMF06CiAgICAgICAgc3VtX2sgKz0gU1tpLCBpXSoqMgogICAgICAgIGkgKz0gMQogICAgayA9IGkKCiAgICAjIDMuIEdp4buvIGzhuqFpIGsgaMOgbmcgdsOgIGsgY+G7mXQgxJHhuqd1IHRpw6puIGPhu6dhIG1hIHRy4bqtbiDOoyDEkeG7gyB04bqhbyB0aMOgbmggzqNrCiAgICBTayA9IFNbOmssIDprXQoKICAgICMgNC4gR2nhu68gbOG6oWkgayBj4buZdCDEkeG6p3UgdGnDqm4gY+G7p2EgbWEgdHLhuq1uIFUgxJHhu4MgdOG6oW8gcmEgVWsKICAgIFVrID0gVVs6LCA6a10KCiAgICAjIDUuIEdp4buvIGzhuqFpIGsgaMOgbmcgxJHhuqd1IHRpw6puIGPhu6dhIG1hIHRy4bqtbiBWVCDEkeG7gyB04bqhbyByYSBWVGsKICAgIFZUayA9IFZUWzprLCA6XQoKICAgIHJldHVybiBVaywgU2ssIFZUaywgawoK