Skip to content

sptensor.logical_and does not have expected behavior #256

@dmdunla

Description

@dmdunla

sptensor.logical_and behavior is different than in MATLAB, and I am not sure that what the MATLAB version is doing is useful/correct.

Questions: Do we want to match the MATLAB behavior? Do we want to follow numpy/scipy.sparse? If so, what are those behaviors.

Here is the current sptensor.logical_and:

Create a sparse tensor:

>>> S = ttb.sptensor()
>>> S[0,0] = 1; S[1,1] = 2
>>> S
sparse tensor of shape (2, 2) with 2 nonzeros
[0, 0] = 1.0
[1, 1] = 2.0

Compute logical AND with dense tensor that has the same non-zero
pattern but different values:

>>> T = S.to_tensor()
>>> T[0,0] = T[0,0] + 1
>>> S.logical_and(T)
sparse tensor of shape (2, 2) with 2 nonzeros
[0, 0] = 1.0
[1, 1] = 1.0

Compute logical AND with scalar value:

>>> S.logical_and(1.0)
sparse tensor of shape (2, 2) with 2 nonzeros
[0, 0] = True
[1, 1] = False

The output when computing with a tensor is an indicator sparse tensor, whereas it is a boolean sparse tensor for the scalar case. Also, the scalar case is computing the AND as an equality comparison it appears, not just a check for non-zero.

Here is the output from MATLAB:

>> S = sptensor()
S is an all-zero sparse tensor of size [empty tensor]
>> S(1,1) = 1
S is a sparse tensor of size 1 x 1 with 1 nonzeros
	(1,1)     1
>> S(2,2) = 2
S is a sparse tensor of size 2 x 2 with 2 nonzeros
	(1,1)     1
	(2,2)     2
>> T = tensor(S)
T is a tensor of size 2 x 2
	T(:,:) = 
	     1     0
	     0     2
>> T(1,1) = 2
T is a tensor of size 2 x 2
	T(:,:) = 
	     2     0
	     0     2
>> and(S,tensor(S))
ans is a sparse tensor of size 2 x 2 with 2 nonzeros
	(1,1)   1
	(2,2)   1
>> and(S,1.0)
ans is a sparse tensor of size 2 x 2 with 2 nonzeros
	(1,1)     1
	(2,2)     1

The scalar AND is odd in MATLAB, as it checks for either zero or non-zero depending on the scalar input:

>> and(S,0)
ans is an all-zero sparse tensor of size 2 x 2
>> and(S,1)
ans is a sparse tensor of size 2 x 2 with 2 nonzeros
	(1,1)     1
	(2,2)     1
>> and(S,2)
ans is a sparse tensor of size 2 x 2 with 2 nonzeros
	(1,1)     1
	(2,2)     1

The documentation in pyttb should document this behavior (once it matches with MATLAB).

Here are some experiments with numpy and scipy, where I am unable to compute __and__ at all, so I am unsure what the default behavior for those should be:

>>> import numpy as np
>>> A = np.zeros((2,2))
>>> A[0,0] = 1
>>> A & 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
>>> 0 & A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

>>> import scipy.sparse as sp 
>>> B = sp.coo_matrix(A)
>>> B
<2x2 sparse matrix of type '<class 'numpy.float64'>'
        with 1 stored elements in COOrdinate format>
>>> B & 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'coo_matrix' and 'int'
>>> B & A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'coo_matrix' and 'float'
>>> B.toarray()
array([[1., 0.],
       [0., 0.]])
>>> B.toarray() & A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationdoingActively being worked oninvalidThis doesn't seem right

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions