Skip to content

Example tensor for cp_als needs to have CP structure #363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tgkolda opened this issue Dec 17, 2024 · 2 comments · May be fixed by #392
Open

Example tensor for cp_als needs to have CP structure #363

tgkolda opened this issue Dec 17, 2024 · 2 comments · May be fixed by #392

Comments

@tgkolda
Copy link
Collaborator

tgkolda commented Dec 17, 2024

The example being used to demo cp_als in https://pyttb.readthedocs.io/en/latest/tutorial/algorithm_cp_als.html is just a random tensor. Random tensors do not have CP structure, so this is not a good example to use. Either use the amino acids data or create a small tensor with structure.

@dmdunla
Copy link
Collaborator

dmdunla commented Jan 31, 2025

@tgkolda To date, we have tried to provide synthetic data in pyttb to avoid requiring users to download external data. So below is an attempt at generating the data, followed by questions on suggestions for the remainder of the tutorial.

Here is a change that creates an example of a small tensor with CP structure:

# Pick the rank and shape
R = 3
tensor_shape = (6, 8, 10)

# Set seed for reproducibility
np.random.seed(0)

# Create a low-rank dense tensor from a Kruskal tensor
factor_matrices = [np.random.rand(s,R) for s in tensor_shape]
X = ttb.ktensor(factor_matrices).to_tensor()

Using cp_als to compute a rank-R CP decompositions (on the next line in the tutorial) ...

# Compute a solution with final ktensor stored in M1
np.random.seed(0)  # Set seed for reproducibility
short_tutorial = 10  # Cut off solve early for demo
(M1, M1_init, M1_out) = ttb.cp_als(X, R, maxiters=short_tutorial)

produces the following output, illustrating that we can recover the structure:

CP_ALS:
 Iter 0: f = 1.000000e+00 f-delta = 1.0e+00
 Iter 1: f = 1.000000e+00 f-delta = 1.7e-08
 Final f = 1.000000e+00

I like this example because I think that illustrating that cp_als can recover the low-rank CP structure almost exactly when knowing the true rank of the input tensor is useful for beginner users. However, the remainder of the tutorial would need to be refactored, as the aim is to illustrate the impact of using different initializations and more computation to achieve a better decomposition.

Questions:

  1. Would adding noise to X (maybe as X_noisy) suffice to illustrate the concepts in the current tutorial?
  2. Or should we consider some other input tensors to use to illustrate these ideas (e.g., rank-(R+1), then compute rank-R CP decompositions)?
  3. Or should we refactor the whole tutorial to tell a different story?
  4. Or should we consider using external data (which currently is available in MATLAB *.mat format, for which loading has not been fully address yet in pyttb)?

@dmdunla
Copy link
Collaborator

dmdunla commented Jan 31, 2025

Nevermind, there was an error in my updated code. I was creating a ttb.tensor with low-rank CP structure by creating a random ttb.ktensor. Then I ran ttb.cp_als using random initialization and the problem was solved in a single step. But the reason for that was that I set the np.random.seed() to the same value before the data creation and the call for cp_als, thus the initial guess was the actual solution. Ugh!

I'll make the updates to the initial problem and commit the changes for now.

The long term solution is to address Issue #312 so we can generate data more readily in the tutorial and documentation.

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 a pull request may close this issue.

2 participants