-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathexact.py
28 lines (28 loc) · 896 Bytes
/
exact.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np
import itertools
import math
from utils import *
def exact(X, K):
D = X.shape[0]
N = X.shape[1]
Bexst = decimal2binary(list(range(2**N)), N);
Qopt = np.zeros((D, K))
Bopt = np.zeros((N, K))
metopt = 0
if K == 1:
for n in range(Bexst.shape[1]):
b = Bexst[:, n, None]
met = np.linalg.norm(X @ b)
if met > metopt:
Qopt = X @ b / np.linalg.norm(X @ b)
metopt = metricL1pca(X, Qopt)
Bopt = b
else:
for idx in itertools.product(range(Bexst.shape[1]), repeat = K):
Bcand = Bexst[:, np.array(idx).astype(np.int)]
met = np.linalg.norm(X @ Bcand , ord = 'nuc')
if met > metopt:
Qopt = procrustes(X @ Bcand)
Bopt = Bcand
metopt = metricL1pca(X, Qopt)
return Qopt, Bopt