Skip to content

Commit d5e89c0

Browse files
committed
add vectorized computation. some cleanup.
1 parent ac9fbcd commit d5e89c0

1 file changed

Lines changed: 39 additions & 67 deletions

File tree

src/aspire/abinitio/commonline_nug.py

Lines changed: 39 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ def __init__(
101101
self.Nstep_yI = Nstep_yI
102102
self.verbose = verbose
103103

104-
# Handle symmetry
104+
# Handle symmetry.
105+
# Get from source if not provided. Warn on mismatch if provided.
105106
if symmetry is None:
106107
logger.info(
107108
f"Symmetry not provided. Using Source symmetry: {str(self.src.symmetry_group)}"
@@ -174,8 +175,6 @@ def fij(alpha, gamma, i, j):
174175
"""
175176
Evaluate the pairwise common-line loss used to approximate NUG Fourier coefficients.
176177
177-
For a relative orientation parameterized by ZYZ Euler angles, the common-line
178-
loss f_ij depends only on the first and third angles, alpha and gamma.
179178
This function samples the corresponding polar Fourier rays from images i and j,
180179
compares them over all candidate 1D shifts, and returns the minimum shifted
181180
L1 mismatch.
@@ -398,7 +397,7 @@ def admm_sym_J(self, C, verbose):
398397
bE[k + 1 + d0[k + 1] + d1[k] : k + 1 + d0[k + 1] + d1[k + 1]] = xp.eye(
399398
k + 2
400399
).T.reshape(-1)
401-
bE = xp.repeat(bE[:, np.newaxis], N, axis=1)
400+
bE = xp.repeat(bE[:, None], N, axis=1)
402401
P = []
403402
for k in range(1, Lmax + 1):
404403
dk = 2 * k + 1
@@ -781,65 +780,41 @@ def ADMM_preprocessing(self, C):
781780
bEq = xp.zeros(17, dtype=np.float64)
782781
bEq[:16] = xp.eye(4, dtype=np.float64).reshape(-1) / 4
783782
bEq[-1] = 1
784-
bEq = xp.repeat(bEq[:, xp.newaxis], N * (N - 1) // 2, axis=1)
783+
bEq = xp.repeat(bEq[:, None], N * (N - 1) // 2, axis=1)
785784

786-
# AI and bI
785+
# Compute AI and bI
787786
W0, W1, Ngrid = self.compute_fejer_weights()
788-
AI_mat_offdiag = np.zeros((Ngrid, D0 + D1), dtype=np.float64)
789-
for p in range(Ngrid):
790-
w0 = np.zeros(D0, dtype=np.float64)
791-
w1 = np.zeros(D1, dtype=np.float64)
792-
for k in range(1, Lmax + 1):
793-
w0[d0[k - 1] : d0[k]] = (
794-
(Lmax - k + 2)
795-
* (Lmax - k + 1)
796-
* (k + 0.5)
797-
* W0[k - 1][p].T.reshape(-1)
798-
)
799-
w1[d1[k - 1] : d1[k]] = (
800-
(Lmax - k + 2)
801-
* (Lmax - k + 1)
802-
* (k + 0.5)
803-
* W1[k - 1][p].T.reshape(-1)
804-
)
805-
# this needs double checking (Ruiyi)
806-
AI_mat_offdiag[p, : d0[-1]] = w0
807-
AI_mat_offdiag[p, d0[-1] :] = w1
808787

809-
# Vectorized version, added by Josh
810-
# AI_mat_offdiag_new = np.zeros((Ngrid, D0 + D1))
811-
# for k in range(1, Lmax + 1):
812-
# scale = (Lmax - k + 2) * (Lmax - k + 1) * (k + 0.5)
788+
# AI_mat_offdiag computation has been vectorized, but originally
789+
# had the note by block1: this needs double checking (Ruiyi)
790+
AI_mat_offdiag = np.zeros((Ngrid, D0 + D1), dtype=np.float64)
791+
for k in range(1, Lmax + 1):
792+
scale = (Lmax - k + 2) * (Lmax - k + 1) * (k + 0.5)
813793

814-
# block0 = scale * W0[k - 1].transpose(0, 2, 1).reshape(Ngrid, -1)
815-
# block1 = scale * W1[k - 1].transpose(0, 2, 1).reshape(Ngrid, -1)
794+
block0 = scale * W0[k - 1].transpose(0, 2, 1).reshape(Ngrid, -1)
795+
block1 = scale * W1[k - 1].transpose(0, 2, 1).reshape(Ngrid, -1)
816796

817-
# AI_mat_offdiag_new[:, d0[k - 1]:d0[k]] = block0
818-
# AI_mat_offdiag_new[:, d0[-1] + d1[k - 1]:d0[-1] + d1[k]] = block1
797+
AI_mat_offdiag[:, d0[k - 1] : d0[k]] = block0
798+
AI_mat_offdiag[:, d0[-1] + d1[k - 1] : d0[-1] + d1[k]] = block1
819799

800+
# AI_mat_diag computation has been vectorized, but originally
801+
# had the note by block1: this needs double checking (Ruiyi)
820802
AI_mat_diag = np.zeros((Ngrid, D0 + D1), dtype=np.float64)
821-
for p in range(Ngrid):
822-
w0 = np.zeros(D0, dtype=np.float64)
823-
w1 = np.zeros(D1, dtype=np.float64)
824-
for k in range(1, Lmax + 1):
825-
w0[d0[k - 1] : d0[k]] = (
826-
(Lmax - k + 2)
827-
* (Lmax - k + 1)
828-
* (k + 0.5)
829-
* (0.5 * W0[k - 1][p] + 0.5 * W0[k - 1][p].T).T.reshape(-1)
830-
)
831-
w1[d1[k - 1] : d1[k]] = (
832-
(Lmax - k + 2)
833-
* (Lmax - k + 1)
834-
* (k + 0.5)
835-
* (0.5 * W1[k - 1][p] + 0.5 * W1[k - 1][p].T).T.reshape(-1)
836-
)
837-
# this needs double checking (Ruiyi)
838-
AI_mat_diag[p, : d0[-1]] = w0
839-
AI_mat_diag[p, d0[-1] :] = w1
840-
AI_mat_diag = xp.asarray(AI_mat_diag) / 1
841-
AI_mat_offdiag = xp.asarray(AI_mat_offdiag) / 1
842-
bI = -(Lmax + 2) * (Lmax + 1) / 2 / 1
803+
for k in range(1, Lmax + 1):
804+
scale = (Lmax - k + 2) * (Lmax - k + 1) * (k + 0.5)
805+
806+
W0_sym = 0.5 * (W0[k - 1] + W0[k - 1].transpose(0, 2, 1))
807+
W1_sym = 0.5 * (W1[k - 1] + W1[k - 1].transpose(0, 2, 1))
808+
809+
block0 = scale * W0_sym.transpose(0, 2, 1).reshape(Ngrid, -1)
810+
block1 = scale * W1_sym.transpose(0, 2, 1).reshape(Ngrid, -1)
811+
812+
AI_mat_diag[:, d0[k - 1] : d0[k]] = block0
813+
AI_mat_diag[:, d0[-1] + d1[k - 1] : d0[-1] + d1[k]] = block1
814+
815+
AI_mat_diag = xp.asarray(AI_mat_diag)
816+
AI_mat_offdiag = xp.asarray(AI_mat_offdiag)
817+
bI = -(Lmax + 2) * (Lmax + 1) / 2
843818

844819
# largest eigenvalue for AIAIT
845820
Lambda = self.largest_eigenvalue(AI_mat_offdiag, Ngrid, N)
@@ -1302,23 +1277,20 @@ def LS_D(W1, W2, W3, W4, Br, Bi):
13021277
DXijmD = np.diag(Di.conj()) @ Xijm @ np.diag(Dj)
13031278
wj = ws[j]
13041279
W1 = (
1305-
wi[:, 0][:, np.newaxis] @ wj[:, 0][:, np.newaxis].T
1306-
+ Jk @ wi[:, 0][:, np.newaxis] @ wj[:, 0][:, np.newaxis].T @ Jk
1280+
wi[:, 0][:, None] @ wj[:, 0][:, None].T
1281+
+ Jk @ wi[:, 0][:, None] @ wj[:, 0][:, None].T @ Jk
13071282
)
13081283
W2 = (
1309-
wi[:, -1][:, np.newaxis] @ wj[:, 0][:, np.newaxis].T
1310-
+ Jk @ wi[:, -1][:, np.newaxis] @ wj[:, 0][:, np.newaxis].T @ Jk
1284+
wi[:, -1][:, None] @ wj[:, 0][:, None].T
1285+
+ Jk @ wi[:, -1][:, None] @ wj[:, 0][:, None].T @ Jk
13111286
)
13121287
W3 = (
1313-
wi[:, 0][:, np.newaxis] @ wj[:, -1][:, np.newaxis].T
1314-
+ Jk @ wi[:, 0][:, np.newaxis] @ wj[:, -1][:, np.newaxis].T @ Jk
1288+
wi[:, 0][:, None] @ wj[:, -1][:, None].T
1289+
+ Jk @ wi[:, 0][:, None] @ wj[:, -1][:, None].T @ Jk
13151290
)
13161291
W4 = (
1317-
wi[:, -1][:, np.newaxis] @ wj[:, -1][:, np.newaxis].T
1318-
+ Jk
1319-
@ wi[:, -1][:, np.newaxis]
1320-
@ wj[:, -1][:, np.newaxis].T
1321-
@ Jk
1292+
wi[:, -1][:, None] @ wj[:, -1][:, None].T
1293+
+ Jk @ wi[:, -1][:, None] @ wj[:, -1][:, None].T @ Jk
13221294
)
13231295
Br = np.real(4 * DXijmD)
13241296
Bi = np.imag(4 * DXijmD)

0 commit comments

Comments
 (0)