Skip to content

Tensor three-way examples #440

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
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 111 additions & 63 deletions pyttb/tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -506,10 +511,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.]],
<BLANKLINE>
[[1., 1.],
[1., 1.]]])
"""
return self.data.astype(np.float64, order=self.order, copy=True)

Expand All @@ -524,10 +532,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)

Expand All @@ -542,20 +563,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)
Expand All @@ -571,17 +607,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)
Expand Down Expand Up @@ -760,11 +808,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
"""
Expand Down
Loading