WorksComputer Science
Improved basis-change transformations for matrix multiplication
Abstract
To the best of our knowledge, we present a state-of-the-art change-of-basis algorithm for matrix multiplication under the Karstadt–Schwartz-style basis change regime [1]. We do this by introducing basis-change matrices , , and that each require only a single addition and hence give rise to a matrix-multiplication algorithm performing arithmetic operations when multiplying two matrices, with a power of . This improves on the previous best bound, which had last term .
Introduction
The Karstadt–Schwartz-style basis change is a well-studied method, and we will not repeat the method here. For background on the Karstadt–Schwartz-style basis-change method, see [1, 2, 3, 4]. Let be an arbitrary ring, and let , be matrices over this ring. We use column-major vectorization, . Here and below, when counting additions, we will use the convention that a subtraction also counts as an addition, see [4, 5, 6]. Let the matrices , , satisfy
for all matrices , . Moreover, let , , be invertible over . For arbitrary , let , , denote the number of additions required to compute respectively , , and . Finally, denote by , , and the number of additions required to compute respectively , , and for arbitrary , and , with
Theorem 1.1. For an integer-power of 2 we can multiply matrices , in
arithmetic operations.
Proof See Claim 2.9, Claim 2.12, and Corollary 2.15 in [1].
Now consider matrices
with basis-change matrices
It is straightforward to verify that the matrix triple satisfies equation (1.1), and that and are invertible over . Moreover, clearly , giving us the trailing term in equation (1.2).
We can compute and as follows
The linear transformations induced by and can be computed using 3 additions each as follows:
such that
for all . Therefore . The linear transformation induced by can be computed using 6 additions as follows:
such that
for any . From which it follows that .
By Theorem 1.1 we can thus multiply two matrices using a Karstadt–Schwartz-style basis-change in
arithmetic operations, using the basis-change induced by the matrices and defined in equation (1.3).
Verification
The following Python program provides a simple verification of the scheme.

Figure 1. Small verification script (verify.py).
"""
Artisinally hand-crafted code
"""
import numpy as np
import sympy as sp
inv = np.linalg.inv
S = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 1, 1]]).astype(int)
assert(not any(((S @ inv(S).astype(int)) - np.eye(4)).flatten())) # inv over Z sanity
check
U = np.array( [ [1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, -1, 1, 1], [0, 0, 1, 1],
[0, -1, 0, 1], [-1, -1, 1, 1] ]).astype(int)
V = np.array( [ [1, 0, 0, 0], [0, 1, 0, 0], [-1, -1, 1, 1], [0, -1, 1, 1], [0, 0, 1,
1], [0, -1, 0, 1], [0, 0, 1, 0] ]).astype(int)
W = np.array( [ [1, 0, 0, 0], [1, -1, 1, -1], [0, -1, 0, 0], [0, -1, 1, -1], [0, 1, 0,
1], [0, 0, -1, 1], [0, 0, -1, 0] ]).astype(int)
A_vec = sp.Matrix([sp.Symbol(f"A_{j}{i}", commutative=False) for i in range(1,3) for j
in range(1,3)])
B_vec = sp.Matrix([sp.Symbol(f"B_{j}{i}", commutative=False) for i in range(1,3) for j
in range(1,3)])
# sanity check that U,V,W encodes matrix multiplication
print("#" * 32)
hadamard = sp.matrices.dense.matrix_multiply_elementwise
print(f"{sp.simplify(W.T @ hadamard((U @ A_vec), (V @ B_vec)))=}")
U_tilde = U @ inv(S).astype(int)
V_tilde = V @ inv(S).astype(int)
W_tilde = W @ S
print("#" * 32)
print(f"{U_tilde=}")
print(f"{V_tilde=}")
print(f"{W_tilde.T=}")
def compute_U(x):
s_1 = x[3] - x[1] # 1 add
s_2 = s_1 - x[2] # 2 add
s_3 = s_1 - x[0] # 3 add
return sp.Matrix([x[0], x[2], x[1], s_1, x[3], s_2, s_3])
def compute_V(x):
s_1 = x[3] - x[1] # 1 add
s_2 = s_1 - x[2] # 2 add
s_3 = s_1 - x[0] # 3 add
return sp.Matrix([x[0], x[1], s_3, s_1, x[3], s_2, x[2]])
def compute_W(M):
t_1 = M[4] - M[3] # 1 add
t_2 = t_1 - M[1] # 2 add
y_1 = M[0] + M[1] # 3 add
y_2 = t_2 - M[2] # 4 add
y_3 = M[4] - M[6] # 5 add
y_4 = t_2 + M[5] # 6 add
return sp.Matrix([y_1, y_2, y_3, y_4])
print("#" * 32)
x = sp.Matrix([sp.Symbol(f"x_{i}") for i in range(1,5)])
y = sp.Matrix([sp.Symbol(f"x_{i}") for i in range(1,8)])
print(f"Should be a bunch of zeros only:")
print(f"{U_tilde @ x - compute_U(x)=}")
print(f"{V_tilde @ x - compute_V(x)=}")
print(f"{W_tilde.T @ y - compute_W(y)=}")
Declaration of use of generative AI
GPT-6-Astra was used for finding this result. The manuscript is prepared by me, with minor language editing and grammar help from the machine. I take full responsibility for the final manuscript.
References
- [1]Schwartz, O., Vaknin, N.: Pebbling game and alternative basis for high performance matrix multiplication. SIAM Journal on Scientific Computing 45(6), C277–C303 (2023) https://doi.org/10.1137/22M1502719
- [2]Karstadt, E., Schwartz, O.: Matrix multiplication, a little faster. Journal of the ACM 67(1), 1–31 (2020) https://doi.org/10.1145/3364504
- [3]Karstadt, E., Schwartz, O.: Matrix multiplication, a little faster. In: Proceedings of the 29th ACM Symposium on Parallelism in Algorithms and Architectures. SPAA ’17, pp. 101–110. Association for Computing Machinery, New York, NY, USA (2017). https://doi.org/10.1145/3087556.3087579 . https://doi.org/10.1145/3087556.3087579
- [4]Nielsen, H.: A 52-Addition, Rank-23 Scheme for Exact 3 × 3 Matrix Multiplication (2026). https://doi.org/10.48550/arXiv.2609.06588 . https://arxiv.org/abs/2609.06588
- [5]Van Zee, F.G., Smith, T.M.: Inducing complex matrix multiplication via the 3m and 4m methods. FLAME Working Note 81, The University of Texas at Austin, Austin, TX, USA (October 2016). https://www.cs.utexas.edu/%7Eflame/pubs/flawn81.pdf
- [6]Bläser, M.: Fast matrix multiplication. Theory of Computing Library, Graduate Surveys 5, 1–60 (2013) https://doi.org/10.4086/toc.gs.2013.005