How to check if a boolean tensor has decreasing values in each rows?

If we have a tensor like this

[[True, False, False,False],
[False,False,False,False],
[True,True,False,False],
[[True,True,True,True]]

The check should return True. But in case there is something like this

[[True, False, True,True], <--- wrong
[False,False,False,False],
[True,True,False,False],
[[True,True,True,True]]

should return False or maybe this

[[False, False, True,True], <--- wrong
[False,True,False,False], <--- wrong
[True,True,False,False],
[[True,True,True,True]]

How can one implement such a check in pytorch (I specifically meant not using a for loop because that won’t be a feasible check in a full fledged code)?

Do you mean return true only when false is a successor to True?
Can be done easily, i’ve written a naive implementation O(n^2)

def check(t):
  for i in range(t.shape[0]):
    flag = False
    for j in range(t.shape[1]):
      if t[i][j].item() == False:
        flag = True
      if t[i][j].item() == True:
        if flag == True:
          return False
  return True

eg use:

b = torch.tensor(((False, False, False,False),(False,False,False,False),(True,True,False,False),(True,True,True,True)))
check(b)

Thanks but no I want to include it in a pytorch source code, it would slow things up to a large extent. I want to have this check in pytorch vectorized code.

Hi Xianqian!

cumprod() – for boolean values – will test for “decreasing values”:

>>> import torch
>>> torch.__version__
'1.9.0'
>>>
>>> b1 = torch.tensor ([
...     [True,  False, False, False],
...     [False, False, False, False],
...     [True,  True,  False, False],
...     [True,  True,  True,  True ]
...     ])
>>>
>>> b2 = torch.tensor ([
...     [True,  False, True,  True ],
...     [False, False, False, False],
...     [True,  True,  False, False],
...     [True,  True,  True,  True ]
...     ])
>>>
>>> b3 = torch.tensor ([
...     [True,  False, True,  True ],
...     [False, True,  False, False],
...     [True,  True,  False, False],
...     [True,  True,  True,  True ]
...     ])
>>>
>>> torch.equal (b1, b1.cumprod (1).bool())
True
>>> torch.equal (b2, b2.cumprod (1).bool())
False
>>> torch.equal (b3, b3.cumprod (1).bool())
False

To see in a little more detail what is going on, consider:

>>> torch.all (torch.eq (b1, b1.cumprod (1).bool()), 1)
tensor([True, True, True, True])
>>> torch.all (torch.eq (b2, b2.cumprod (1).bool()), 1)
tensor([False,  True,  True,  True])
>>> torch.all (torch.eq (b3, b3.cumprod (1).bool()), 1)
tensor([False, False,  True,  True])

Best.

K. Frank

2 Likes