From bec4fbbcd74473b981c6a6481b55e852752cf1b2 Mon Sep 17 00:00:00 2001 From: Tammy Kolda Date: Wed, 28 May 2025 10:46:40 -0700 Subject: [PATCH 1/7] Changing isequal example from 2-way to 3-way --- pyttb/tensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyttb/tensor.py b/pyttb/tensor.py index 1fe81dd3..a471fda8 100644 --- a/pyttb/tensor.py +++ b/pyttb/tensor.py @@ -760,11 +760,11 @@ def isequal(self, other: Union[tensor, ttb.sptensor]) -> bool: Examples -------- - >>> T1 = ttb.tensor(2 * np.ones((2, 2))) - >>> T2 = 2 * ttb.tensor(np.ones((2, 2))) + >>> T1 = ttb.tensor(2 * np.ones((2, 2, 2))) + >>> T2 = 2 * ttb.tensor(np.ones((2, 2, 2))) >>> T1.isequal(T2) True - >>> T2[0, 0] = 1 + >>> T2[1, 0, 1] = 1 >>> T1.isequal(T2) False """ From 60d72a918e7e5a8b18ffe0f2d6ede87318c1da70 Mon Sep 17 00:00:00 2001 From: Tammy Kolda Date: Wed, 28 May 2025 10:45:44 -0700 Subject: [PATCH 2/7] Changing exp example from 2-way to 3-way --- pyttb/tensor.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pyttb/tensor.py b/pyttb/tensor.py index a471fda8..050ca03d 100644 --- a/pyttb/tensor.py +++ b/pyttb/tensor.py @@ -524,10 +524,23 @@ def exp(self) -> tensor: Examples -------- - >>> T = ttb.tensor(np.array([[1, 2], [3, 4]])) - >>> T.exp().data # doctest: +ELLIPSIS - array([[ 2.7182..., 7.3890... ], - [20.0855..., 54.5981...]]) + >>> T = ttb.tensor(np.arange(8), (2, 2, 2)) # Tensor with entries 0 to 7 + >>> print(T) + tensor of shape (2, 2, 2) with order F + data[:, :, 0] = + [[0 2] + [1 3]] + data[:, :, 1] = + [[4 6] + [5 7]] + >>> print(T.exp()) + tensor of shape (2, 2, 2) with order F + data[:, :, 0] = + [[ 1. 7.3890561 ] + [ 2.71828183 20.08553692]] + data[:, :, 1] = + [[ 54.59815003 403.42879349] + [ 148.4131591 1096.63315843]] """ return ttb.tensor(np.exp(self.data), copy=False) From 482f288d9e4cadf33f4ce72d9ba2d22da9617733 Mon Sep 17 00:00:00 2001 From: Tammy Kolda Date: Wed, 28 May 2025 10:41:18 -0700 Subject: [PATCH 3/7] Changing example to 3-way from 2-way --- pyttb/tensor.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pyttb/tensor.py b/pyttb/tensor.py index 050ca03d..08aff630 100644 --- a/pyttb/tensor.py +++ b/pyttb/tensor.py @@ -506,10 +506,13 @@ def double(self) -> np.ndarray: Examples -------- - >>> T = ttb.tensor(np.ones((2, 2))) + >>> T = ttb.tensor(np.ones(8), (2, 2, 2)) # All-ones 2 x 2 x 2 tensor >>> T.double() - array([[1., 1.], - [1., 1.]]) + array([[[1., 1.], + [1., 1.]], + + [[1., 1.], + [1., 1.]]]) """ return self.data.astype(np.float64, order=self.order, copy=True) From 0cdcf1155e2e838855ca3cb500dd2684450ae8ae Mon Sep 17 00:00:00 2001 From: Tammy Kolda Date: Tue, 27 May 2025 11:46:35 -0700 Subject: [PATCH 4/7] Changed example in tensor.find from 2-way to 3-way --- pyttb/tensor.py | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/pyttb/tensor.py b/pyttb/tensor.py index 08aff630..93e99c3e 100644 --- a/pyttb/tensor.py +++ b/pyttb/tensor.py @@ -558,20 +558,35 @@ def find(self) -> Tuple[np.ndarray, np.ndarray]: Examples -------- - >>> T = ttb.tensor(np.array([[1,2],[3,4]])) - >>> print(T) - tensor of shape (2, 2) with order F - data[:, :] = - [[1 2] - [3 4]] - >>> T_threshold = T > 2 - >>> subs, vals = T_threshold.find() - >>> subs.astype(int) - array([[1, 0], - [1, 1]]) - >>> vals - array([[ True], - [ True]]) + Create a random tensor with approximately 50% zero entries:: + + >>> np.random.seed(6) # reproducibility + >>> sprandint = lambda s: np.where(np.random.rand(np.prod(s)) < 0.5, + ... 0.0, np.random.rand(np.prod(s))) + >>> T = ttb.tensor.from_function(sprandint, (2,2,2)) + >>> print(T) + tensor of shape (2, 2, 2) with order F + data[:, :, 0] = + [[0.33540785 0.43814143] + [0. 0. ]] + data[:, :, 1] = + [[0. 0.6453551] + [0.5788586 0. ]] + + Find the nonzero entries in the tensor:: + + >>> subs, vals = T.find() + >>> print(subs) + [[0 0 0] + [0 1 0] + [1 0 1] + [0 1 1]] + >>> print(vals) + [[0.33540785] + [0.43814143] + [0.5788586 ] + [0.6453551 ]] + """ idx = np.nonzero(np.ravel(self.data, order=self.order))[0] subs = tt_ind2sub(self.shape, idx) From a27d2c3be2b45ae622ff0e30e3f14ee42b4ce662 Mon Sep 17 00:00:00 2001 From: Tammy Kolda Date: Tue, 27 May 2025 11:40:58 -0700 Subject: [PATCH 5/7] Changing example in tensor.to_sptensor from 2-way to 3-way. --- pyttb/tensor.py | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/pyttb/tensor.py b/pyttb/tensor.py index 93e99c3e..bb6ff696 100644 --- a/pyttb/tensor.py +++ b/pyttb/tensor.py @@ -602,17 +602,29 @@ def to_sptensor(self) -> ttb.sptensor: Examples -------- - >>> T = ttb.tensor(np.array([[0, 2], [3, 0]])) - >>> print(T) - tensor of shape (2, 2) with order F - data[:, :] = - [[0 2] - [3 0]] - >>> S = T.to_sptensor() - >>> print(S) - sparse tensor of shape (2, 2) with 2 nonzeros and order F - [1, 0] = 3 - [0, 1] = 2 + Construct a 2x2x2 tensor with some nonzero entries:: + + >>> np.random.seed(3) # reproducibility + >>> sprandint = lambda s: np.random.randint(0, 4, size=np.prod(s)) / 4; + >>> T = ttb.tensor.from_function(sprandint, (2,2,2)) + >>> print(T) + tensor of shape (2, 2, 2) with order F + data[:, :, 0] = + [[0.5 0.25] + [0. 0.75]] + data[:, :, 1] = + [[0. 0. ] + [0. 0.25]] + + Convert to a sparse tensor:: + + >>> S = T.to_sptensor() + >>> print(S) + sparse tensor of shape (2, 2, 2) with 4 nonzeros and order F + [0, 0, 0] = 0.5 + [0, 1, 0] = 0.25 + [1, 1, 0] = 0.75 + [1, 1, 1] = 0.25 """ subs, vals = self.find() return ttb.sptensor(subs, vals, self.shape, copy=False) From 9246c2e77865a72b159c52d70527e865a33d74c1 Mon Sep 17 00:00:00 2001 From: Tammy Kolda Date: Tue, 27 May 2025 11:38:55 -0700 Subject: [PATCH 6/7] Changing example in tensor.contract from 2-way to 3-way --- pyttb/tensor.py | 53 +++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/pyttb/tensor.py b/pyttb/tensor.py index bb6ff696..d5488180 100644 --- a/pyttb/tensor.py +++ b/pyttb/tensor.py @@ -432,30 +432,35 @@ def contract(self, i1: int, i2: int) -> Union[np.ndarray, tensor]: Examples -------- - >>> T = ttb.tensor(np.ones((2, 2))) - >>> T.contract(0, 1) - 2.0 - >>> T = ttb.tensor(np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])) - >>> print(T) - tensor of shape (2, 2, 2) with order F - data[:, :, 0] = - [[1 3] - [5 7]] - data[:, :, 1] = - [[2 4] - [6 8]] - >>> T.contract(0, 1) - tensor of shape (2,) with order F - data[:] = - [ 8. 10.] - >>> T.contract(0, 2) - tensor of shape (2,) with order F - data[:] = - [ 7. 11.] - >>> T.contract(1, 2) - tensor of shape (2,) with order F - data[:] = - [ 5. 13.] + Contract a three-way 2 x 2 x 2 tensor along two dimensions + in three possible ways:: + + >>> T = ttb.tensor(np.ones(8), (2, 2, 2)) # All-ones 2 x 2 x 2 tensor + >>> T.contract(0, 1) + tensor of shape (2,) with order F + data[:] = + [2. 2.] + >>> T = ttb.tensor(np.arange(1, 9), (2, 2, 2)) + >>> print(T) + tensor of shape (2, 2, 2) with order F + data[:, :, 0] = + [[1 3] + [2 4]] + data[:, :, 1] = + [[5 7] + [6 8]] + >>> T.contract(0, 1) + tensor of shape (2,) with order F + data[:] = + [ 5. 13.] + >>> T.contract(0, 2) + tensor of shape (2,) with order F + data[:] = + [ 7. 11.] + >>> T.contract(1, 2) + tensor of shape (2,) with order F + data[:] = + [ 8. 10.] """ if self.shape[i1] != self.shape[i2]: assert False, "Must contract along equally sized dimensions" From 74366c2d4b154e5744762b3346c8c88c4863edd7 Mon Sep 17 00:00:00 2001 From: Tammy Kolda Date: Tue, 27 May 2025 11:32:03 -0700 Subject: [PATCH 7/7] Changing tensor.copy example to be 3-way rather than 2-way. --- pyttb/tensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyttb/tensor.py b/pyttb/tensor.py index d5488180..5b670b09 100644 --- a/pyttb/tensor.py +++ b/pyttb/tensor.py @@ -296,13 +296,13 @@ def copy(self) -> tensor: Observing the difference between a shallow copy and a deep copy. When the original tensor changes, so does the shallow copy, but the deep copy does not:: - >>> T = ttb.tensor(np.ones((3, 2))) + >>> T = ttb.tensor(np.ones(8), (2, 2, 2)) >>> T_shallow = T >>> T_deep = T.copy() - >>> T[0, 0] = 3 - >>> T[0, 0] == T_shallow[0, 0] + >>> T[0, 0, 0] = 3 + >>> T[0, 0, 0] == T_shallow[0, 0, 0] True - >>> T[0, 0] == T_deep[0, 0] + >>> T[0, 0, 0] == T_deep[0, 0, 0] False """ return ttb.tensor(self.data, self.shape, copy=True)