diff --git a/dev/_downloads/07fcc19ba03226cd3d83d4e40ec44385/auto_examples_python.zip b/dev/_downloads/07fcc19ba03226cd3d83d4e40ec44385/auto_examples_python.zip index 614b5c47..e2ceef4d 100644 Binary files a/dev/_downloads/07fcc19ba03226cd3d83d4e40ec44385/auto_examples_python.zip and b/dev/_downloads/07fcc19ba03226cd3d83d4e40ec44385/auto_examples_python.zip differ diff --git a/dev/_downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip b/dev/_downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip index 83a069f7..8e280ed9 100644 Binary files a/dev/_downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip and b/dev/_downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip differ diff --git a/dev/_images/sphx_glr_plot_cp_line_search_001.png b/dev/_images/sphx_glr_plot_cp_line_search_001.png index f75fcd97..816cdf21 100644 Binary files a/dev/_images/sphx_glr_plot_cp_line_search_001.png and b/dev/_images/sphx_glr_plot_cp_line_search_001.png differ diff --git a/dev/_images/sphx_glr_plot_cp_line_search_thumb.png b/dev/_images/sphx_glr_plot_cp_line_search_thumb.png index f38fc1ac..7bbc3df2 100644 Binary files a/dev/_images/sphx_glr_plot_cp_line_search_thumb.png and b/dev/_images/sphx_glr_plot_cp_line_search_thumb.png differ diff --git a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_001.png b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_001.png index 9219b97f..6f093850 100644 Binary files a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_001.png and b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_001.png differ diff --git a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_002.png b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_002.png index 144e961e..7c30417a 100644 Binary files a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_002.png and b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_002.png differ diff --git a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_003.png b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_003.png index 2849a6cc..d14deb26 100644 Binary files a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_003.png and b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_003.png differ diff --git a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_004.png b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_004.png index 994fa9f0..440dbc4e 100644 Binary files a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_004.png and b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_004.png differ diff --git a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_005.png b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_005.png index 71648287..b0d91f01 100644 Binary files a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_005.png and b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_005.png differ diff --git a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_006.png b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_006.png index 04bd9617..6d831461 100644 Binary files a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_006.png and b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_006.png differ diff --git a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_thumb.png b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_thumb.png index 6fa1f4f5..f6e08095 100644 Binary files a/dev/_images/sphx_glr_plot_guide_for_constrained_cp_thumb.png and b/dev/_images/sphx_glr_plot_guide_for_constrained_cp_thumb.png differ diff --git a/dev/_images/sphx_glr_plot_image_compression_001.png b/dev/_images/sphx_glr_plot_image_compression_001.png index d85ab2fc..6e7c58ba 100644 Binary files a/dev/_images/sphx_glr_plot_image_compression_001.png and b/dev/_images/sphx_glr_plot_image_compression_001.png differ diff --git a/dev/_images/sphx_glr_plot_image_compression_thumb.png b/dev/_images/sphx_glr_plot_image_compression_thumb.png index 27dc6064..0924757b 100644 Binary files a/dev/_images/sphx_glr_plot_image_compression_thumb.png and b/dev/_images/sphx_glr_plot_image_compression_thumb.png differ diff --git a/dev/_images/sphx_glr_plot_nn_cp_hals_001.png b/dev/_images/sphx_glr_plot_nn_cp_hals_001.png index adbe49f7..cab1942a 100644 Binary files a/dev/_images/sphx_glr_plot_nn_cp_hals_001.png and b/dev/_images/sphx_glr_plot_nn_cp_hals_001.png differ diff --git a/dev/_images/sphx_glr_plot_nn_cp_hals_thumb.png b/dev/_images/sphx_glr_plot_nn_cp_hals_thumb.png index 67a567b0..bc6e0948 100644 Binary files a/dev/_images/sphx_glr_plot_nn_cp_hals_thumb.png and b/dev/_images/sphx_glr_plot_nn_cp_hals_thumb.png differ diff --git a/dev/_images/sphx_glr_plot_nn_tucker_001.png b/dev/_images/sphx_glr_plot_nn_tucker_001.png index 844950aa..587f38ad 100644 Binary files a/dev/_images/sphx_glr_plot_nn_tucker_001.png and b/dev/_images/sphx_glr_plot_nn_tucker_001.png differ diff --git a/dev/_images/sphx_glr_plot_nn_tucker_thumb.png b/dev/_images/sphx_glr_plot_nn_tucker_thumb.png index 14171a22..7738bd40 100644 Binary files a/dev/_images/sphx_glr_plot_nn_tucker_thumb.png and b/dev/_images/sphx_glr_plot_nn_tucker_thumb.png differ diff --git a/dev/_images/sphx_glr_plot_permute_factors_001.png b/dev/_images/sphx_glr_plot_permute_factors_001.png index 732a6fdd..ff43e6cd 100644 Binary files a/dev/_images/sphx_glr_plot_permute_factors_001.png and b/dev/_images/sphx_glr_plot_permute_factors_001.png differ diff --git a/dev/_images/sphx_glr_plot_permute_factors_thumb.png b/dev/_images/sphx_glr_plot_permute_factors_thumb.png index be3b621b..bef6e809 100644 Binary files a/dev/_images/sphx_glr_plot_permute_factors_thumb.png and b/dev/_images/sphx_glr_plot_permute_factors_thumb.png differ diff --git a/dev/_modules/tensorly/tenalg/core_tenalg/mttkrp.html b/dev/_modules/tensorly/tenalg/core_tenalg/mttkrp.html index 6417cdb6..3cc236c1 100644 --- a/dev/_modules/tensorly/tenalg/core_tenalg/mttkrp.html +++ b/dev/_modules/tensorly/tenalg/core_tenalg/mttkrp.html @@ -145,7 +145,9 @@
from .n_mode_product import multi_mode_dot
+from ._khatri_rao import khatri_rao
from ... import backend as T
+from ...base import unfold
# Author: Jean Kossaifi
@@ -171,24 +173,61 @@ Source code for tensorly.tenalg.core_tenalg.mttkrp
Notes
-----
- This is a variant of::
+ Default unfolding_dot_khatri_rao implementation.
- unfolded = unfold(tensor, mode)
- kr_factors = khatri_rao(factors, skip_matrix=mode)
- mttkrp2 = tl.dot(unfolded, kr_factors)
+ Implemented as the product between an unfolded tensor
+ and a Khatri-Rao product explicitly formed. Due to matrix-matrix
+ products being extremely efficient operations, this is a
+ simple yet hard-to-beat implementation of MTTKRP.
- Multiplying with the Khatri-Rao product is equivalent to multiplying,
- for each rank, with the kronecker product of each factor.
- In code::
+ If working with sparse tensors, or when the CP-rank of the CP-tensor is comparable to, or larger than,
+ the dimensions of the input tensor, however, this method requires a lot
+ of memory, which can be harmful when dealing with large tensors. In this
+ case, please use the memory-efficient version of MTTKRP.
- mttkrp_parts = []
- for r in range(rank):
- component = tl.tenalg.multi_mode_dot(tensor, [f[:, r] for f in factors], skip=mode)
- mttkrp_parts.append(component)
- mttkrp = tl.stack(mttkrp_parts, axis=1)
- return mttkrp
+ To use the slower memory efficient version, run
- This can be done by taking n-mode-product with the full factors
+ >>> from tensorly.tenalg.core_tenalg.mttkrp import unfolding_dot_khatri_rao_memory
+ >>> tl.tenalg.register_backend_method("unfolding_dot_khatri_rao", unfolding_dot_khatri_rao_memory)
+ >>> tl.tenalg.use_dynamic_dispatch()
+
+ """
+ weights, factors = cp_tensor
+ kr_factors = khatri_rao(factors, weights=weights, skip_matrix=mode)
+ mttkrp = T.dot(unfold(tensor, mode), T.conj(kr_factors))
+ return mttkrp
+
+
+
+def unfolding_dot_khatri_rao_memory(tensor, cp_tensor, mode):
+ """mode-n unfolding times khatri-rao product of factors
+
+ Parameters
+ ----------
+ tensor : tl.tensor
+ tensor to unfold
+ factors : tl.tensor list
+ list of matrices of which to the khatri-rao product
+ mode : int
+ mode on which to unfold `tensor`
+
+ Returns
+ -------
+ mttkrp
+ dot(unfold(tensor, mode), khatri-rao(factors))
+
+ Notes
+ -----
+ Implemented as a sequence of Tensor-times-vectors products between a tensor
+ and a Khatri-Rao product. The Khatri-Rao product is never computed explicitly,
+ rather each column in the Khatri-Rao product is contracted with the tensor. This
+ operation is implemented in Python and without making of use of parallelism, and it
+ is therefore in general slower than the naive MTTKRP product.
+ When the CP-rank of the CP-tensor is comparable to, or larger than,
+ the dimensions of the input tensor, this method however requires much less
+ memory.
+
+ This method can also be implemented by taking n-mode-product with the full factors
(faster but more memory consuming)::
projected = multi_mode_dot(tensor, factors, skip=mode, transpose=True)
@@ -198,22 +237,6 @@ Source code for tensorly.tenalg.core_tenalg.mttkrp
index = tuple([slice(None) if k == mode else i for k in range(ndims)])
res.append(projected[index])
return T.stack(res, axis=-1)
-
-
- The same idea could be expressed using einsum::
-
- ndims = tl.ndim(tensor)
- tensor_idx = ''.join(chr(ord('a') + i) for i in range(ndims))
- rank = chr(ord('a') + ndims + 1)
- op = tensor_idx
- for i in range(ndims):
- if i != mode:
- op += ',' + ''.join([tensor_idx[i], rank])
- else:
- result = ''.join([tensor_idx[i], rank])
- op += '->' + result
- factors = [f for (i, f) in enumerate(factors) if i != mode]
- return tl_einsum(op, tensor, *factors)
"""
mttkrp_parts = []
weights, factors = cp_tensor
@@ -227,8 +250,7 @@ Source code for tensorly.tenalg.core_tenalg.mttkrp
if weights is None:
return T.stack(mttkrp_parts, axis=1)
else:
- return T.stack(mttkrp_parts, axis=1) * T.reshape(weights, (1, -1))
-
+ return T.stack(mttkrp_parts, axis=1) * T.reshape(weights, (1, -1))
Total running time of the script: (0 minutes 1.723 seconds)
+Total running time of the script: (0 minutes 1.444 seconds)
-<matplotlib.colorbar.Colorbar object at 0x7f884c658e20>
+![samples, antigens, receptors](../../_images/sphx_glr_plot_covid_002.png)
<matplotlib.colorbar.Colorbar object at 0x7f5568575690>
From the results, we can see that serum COVID-19 immunity separates into two distinct signals,
@@ -314,7 +314,7 @@
References
https://www.sciencedirect.com/science/article/pii/S0092867420314598
-Total running time of the script: (0 minutes 6.886 seconds)
+Total running time of the script: (0 minutes 4.097 seconds)
-Total running time of the script: (0 minutes 3.524 seconds)
+Total running time of the script: (0 minutes 1.435 seconds)