Skip to content
Merged
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nipype/algorithms/icc.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def ICC_rep_anova(Y):
X = hstack([x, x0])

# Sum Square Error
predicted_Y = dot(dot(dot(X, pinv(dot(X.T, X))), X.T), Y.flatten("F"))
predicted_Y = X @ (pinv(X.T @ X, hermitian=True) @ (X.T @ Y.flatten("F")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a simulated Y of shape 50 x 10, I get:

In []: %timeit dot(dot(dot(X, pinv(dot(X.T, X))), X.T), Y.flatten("F"))
1.42 ms ± 128 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

Convert to matmul:

In []: %timeit (X @ pinv(X.T @ X) @ X.T) @ Y.flatten("F")
1.4 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

No change. Reorder multiplications:

In []: %timeit X @ (pinv(X.T @ X) @ (X.T @ Y.flatten("F")))
838 µs ± 43.3 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

41% speedup. Use hermetian optimization:

In []: %timeit X @ (pinv(X.T @ X, hermitian=True) @ (X.T @ Y.flatten("F")))
785 µs ± 17.8 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

6% relative speedup for total of 45%.

residuals = Y.flatten("F") - predicted_Y
SSE = (residuals**2).sum()

Expand Down