Skip to content

Conversation

@Albly
Copy link
Contributor

@Albly Albly commented Sep 3, 2025

Fixes #607

Introduction

Consider the singular value decomposition (SVD) of a complex-valued matrix $\mathbf{X} \in \mathbb{C}^{M \times N}$ truncated to rank $R$:
$$\mathbf{X} = \mathbf{U}\mathbf{S}\mathbf{V}^H, \quad \mathbf{U}\in\mathbb{C}^{M×R}, \mathbf{S}\in \mathbb{R}^{R×R}, \mathbf{V}^H \in \mathbb{C}^{R×N}$$
It is known that SVD is invariant under multiplication of each pair of singular vectors by a complex exponential $C_r = e^{j\phi(r)}$. In other words, for the $r$-th singular component we can replace: $\mathbf{u}_r \leftarrow C_r \cdot \mathbf{u}_r$ and $\mathbf{v}_r^H \leftarrow C_r^* \cdot \mathbf{v}_r^H$ without affecting the reconstruction accuracy.

Problem description

According to the documentation of the svd_flip function, its purpose is to eliminate the arbitrary phase of singular vectors by aligning them with the element of largest magnitude. In other words, the correction factor for each $r$ is chosen as:
$$C_r = \mathrm{sign}(z)^*,\quad z = \mathbf{u}_r(\mathrm{argmax}(|\mathbf{u}_r|))$$
Where $\mathrm{sign}(z) = z/|z|$.
But in current version the conjugate operation is missed.

Why it worked for numpy<2.0

Before Numpy 2.0, the definition of the complex sign function was different: $sign(z) = z/ \sqrt{zz}$ equvalent to (sign(x.real) + 0j if x.real != 0 else sign(x.imag) + 0j) which always evaluates to either $1$ or $-1$. Since both the left and right singular vectors were multiplied by the same $\pm 1$ factor, the overall decomposition remained consistent, and the missing conjugation had no visible effect.

@JeanKossaifi
Copy link
Member

JeanKossaifi commented Sep 8, 2025

Thank you @Albly, this is a great fix (and explanation!)! Do you think any documentation (a short comment) could be useful? Or perhaps a reference? Perhaps a small unit-test to test this?

@codecov
Copy link

codecov bot commented Sep 8, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.07%. Comparing base (2c51714) to head (983e497).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #608   +/-   ##
=======================================
  Coverage   88.07%   88.07%           
=======================================
  Files         132      132           
  Lines        7915     7943   +28     
=======================================
+ Hits         6971     6996   +25     
- Misses        944      947    +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Albly
Copy link
Contributor Author

Albly commented Sep 22, 2025

Thank you @JeanKossaifi for the feedback!
Regarding the tests, I actually found two possible ways to improve them and prevent the reported problem:

  • There was no check with complex-valued tensors in the test_tt_decomposition.py test file. After reviewing the project history, I decided to fix it in the same way as test_cp.py does. (4e2ff5a)

  • The svd_interface did not have a check, but it’s mostly about verifying the svd_flip function, since the SVD itself should already be tested in each backend. So, I added one more test for checking the SVD approximation. This might be useful if new functions are added to svd_interface. (ea28781)

Both tests fails if described bug exists.

@JeanKossaifi
Copy link
Member

Apologies for the delay in merging @Albly, thanks a lot for the great PR!

@JeanKossaifi JeanKossaifi merged commit 647c0b8 into tensorly:main Nov 16, 2025
7 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tensor Train fails to approximate complex-valued tensors (error grows with rank)

2 participants