Skip to content

Commit bff079a

Browse files
committed
Fix imports in orthogonalize and add unit tests.
1 parent 5aa81c4 commit bff079a

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

spectral/algorithms/algorithms.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,22 +1271,18 @@ def orthogonalize(vecs, start=0):
12711271
12721272
A new `CxB` containing an orthonormal basis for the given vectors.
12731273
'''
1274-
12751274
(M, N) = vecs.shape
12761275
basis = np.array(np.transpose(vecs))
1277-
eye = identity(N).astype(float)
1278-
if start == 0:
1279-
basis[:, 0] /= math.sqrt(np.dot(basis[:, 0], basis[:, 0]))
1280-
start = 1
1281-
1276+
eye = np.identity(N).astype(float)
12821277
for i in range(start, M):
1283-
v = basis[:, i] / math.sqrt(np.dot(basis[:, i], basis[:, i]))
1278+
if i == 0:
1279+
basis[:, 0] /= np.linalg.norm(basis[:, 0])
1280+
continue
1281+
v = basis[:, i] / np.linalg.norm(basis[:, i])
12841282
U = basis[:, :i]
1285-
P = eye - np.dot(U, np.dot(np.inv(np.dot(np.transpose(U), U)),
1286-
np.transpose(U)))
1287-
basis[:, i] = np.dot(P, v)
1288-
basis[:, i] /= math.sqrt(np.dot(basis[:, i], basis[:, i]))
1289-
1283+
P = eye - U.dot(np.linalg.inv(U.T.dot(U)).dot(U.T))
1284+
basis[:, i] = P.dot(v)
1285+
basis[:, i] /= np.linalg.norm(basis[:, i])
12901286
return np.transpose(basis)
12911287

12921288

spectral/tests/dimensionality.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,36 @@ def test_pca_runs_from_stats(self):
126126
stats = spy.calc_stats(data)
127127
xdata = spy.principal_components(stats).transform(data)
128128

129+
def test_orthogonalize(self):
130+
'''Can correctly create an orthogonal basis from vectors.'''
131+
x = np.linspace(0, np.pi, 1001)
132+
# Create sin and cos vectors of unit length
133+
sin_h = np.sin(x)
134+
sin_h /= np.linalg.norm(sin_h)
135+
cos_h = np.cos(x)
136+
cos_h /= np.linalg.norm(cos_h)
137+
138+
X = np.array([50 * sin_h, 75 * cos_h])
139+
Y = spy.orthogonalize(X)
140+
assert(np.allclose(Y.dot(Y.T), np.array([[1, 0], [0, 1]])))
141+
assert(np.allclose(X.dot(Y.T), np.array([[50, 0], [0, 75]])))
142+
143+
def test_orthogonalize_subset(self):
144+
'''Can correctly create an orthogonal basis from vector subset.'''
145+
x = np.linspace(0, np.pi, 1001)
146+
# Create sin and cos vectors of unit length
147+
sin_h = np.sin(x)
148+
sin_h /= np.linalg.norm(sin_h)
149+
cos_h = np.cos(x)
150+
cos_h /= np.linalg.norm(cos_h)
151+
152+
# First vector in X will already be a unit vector
153+
X = np.array([sin_h, 75 * cos_h])
154+
Y = spy.orthogonalize(X, start=1)
155+
assert(np.allclose(Y.dot(Y.T), np.array([[1, 0], [0, 1]])))
156+
assert(np.allclose(X.dot(Y.T), np.array([[1, 0], [0, 75]])))
157+
158+
129159
def run():
130160
print('\n' + '-' * 72)
131161
print('Running dimensionality tests.')

0 commit comments

Comments
 (0)