Skip to content

Add testing for complex values in CP - #423

Merged
aarmey merged 18 commits into
tensorly:mainfrom
aarmey:complex-test
Jul 20, 2022
Merged

aarmey merged 18 commits into
tensorly:mainfrom
aarmey:complex-test

Conversation

@aarmey

@aarmey aarmey commented Jul 12, 2022 •

Copy link
Copy Markdown
Contributor

Here is a basic test setup for complex valued tensors. I will add comments documenting the failure cases.

Addresses #422

Comment thread tensorly/cp_tensor.py Resolved
Comment thread tensorly/decomposition/tests/test_cp.py Resolved
@aarmey aarmey added the bug label Jul 12, 2022

@yngvem yngvem left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems like I forgot to submit my review last week, so some of my comments may be outdated... I cannot check if that's the case now, as I'm out travelling, but hopefully they should be helpful :)

Comment thread tensorly/random/base.py Resolved
Comment thread tensorly/cp_tensor.py Resolved
Comment thread tensorly/decomposition/tests/test_cp.py Resolved
Comment thread tensorly/cp_tensor.py Resolved
Comment thread tensorly/decomposition/tests/test_cp.py Outdated
@pytest.mark.parametrize("init", ["svd", "random"])
@pytest.mark.parametrize("normalize_factors", [False, True])
@pytest.mark.parametrize("random_state", [1, 1234])
@pytest.mark.parametrize("random_state", [1, 1236])

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I changed the random seed here because the random initialization is pathologically bad. It works fine (and I directly checked the MTTKRP error calculation) but ALS gets trapped without line search or orthogonalization.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's awesome, thanks @aarmey!
I wonder if we could write a small tool to automatically check for such pathological cases?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Interesting idea. It should be clear by looking at cp_lstsq_grad(). It'd be too expensive to run every iteration, but is certainly something you could run at the end to look for issues.

@aarmey
aarmey marked this pull request as ready for review July 18, 2022 15:51
@codecov

codecov Bot commented Jul 18, 2022 •

Copy link
Copy Markdown

Codecov Report

Merging #423 (5336518) into main (37e5bf8) will increase coverage by 0.02%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main     #423      +/-   ##
==========================================
+ Coverage   88.55%   88.58%   +0.02%     
==========================================
  Files         108      108              
  Lines        6423     6428       +5     
==========================================
+ Hits         5688     5694       +6     
+ Misses        735      734       -1     
Impacted Files Coverage Δ
...ly/decomposition/tests/test_constrained_parafac.py 100.00% <ø> (ø)
tensorly/cp_tensor.py 85.08% <100.00%> (ø)
tensorly/decomposition/_cp.py 87.27% <100.00%> (+0.36%) ⬆️
tensorly/decomposition/tests/test_cp.py 100.00% <100.00%> (ø)

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

@JeanKossaifi

JeanKossaifi commented Jul 18, 2022 •

Copy link
Copy Markdown
Member

Thanks @aarmey! I love how you also casually improved the quality of life for the whole library in the process by fixing the test and speeding up the tests for JAX and TF!

@aarmey

aarmey commented Jul 18, 2022

Copy link
Copy Markdown
Contributor Author

If someone can give this a last look, it should be ready and all the tests are passing now.

@JeanKossaifi JeanKossaifi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome, looks good to me!

# mttkrp and factor for the last mode. This is equivalent to the
# inner product <tensor, factorization>
iprod = tl.sum(tl.sum(mttkrp * factors[-1], axis=0))
iprod = tl.sum(tl.sum(mttkrp * tl.conj(factors[-1]), axis=0))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does it have to be the conjugate here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@yngvem had this insight, so he might be able to explain. I confirmed that the results are indeed wrong without this.

@aarmey
aarmey merged commit b672981 into tensorly:main Jul 20, 2022
@aarmey
aarmey deleted the complex-test branch July 20, 2022 02:55
@yngvem

yngvem commented Jul 20, 2022

Copy link
Copy Markdown
Contributor

@aarmey @JeanKossaifi I wasn't able to find the button for submitting my comments after it was merged, so I'm answering the mttkrp-question here :)

Since iprod is supposed to be the inner product of the estimated and true tensor, it should be equal to
$\sum_{ijk} \mathcal{T}_{ijk} \hat{\mathcal{T}}_{ijk}^*$ or $\sum_{ijk} \mathcal{T}_{ijk}^* \hat{\mathcal{T}}_{ijk}$, where the $^*$ denotes conjugation. We have already computed $\sum_{jk} \mathcal{T}_{ij:} \hat{\mathcal{T}}_{ij:}^*$ in the mttkrp, so we need to conjugate the factor matrix of the last mode here to be consistent.

I think we could conjugate the mttkrp instead of the factor matrix, but I would have to check. Anyways, the point is that we need at least one conjugate on that line for there to be a complex inner product

@JeanKossaifi

Copy link
Copy Markdown
Member

Thanks for the clear answer @yngvem! Given that you went through the effort of writing it so nicely, I'd say let's add it to the docstring (in notes) or user guide, what do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants