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

xianqian: <p>If we have a tensor like this</p>
<pre><code class="lang-auto">[[True, False, False,False],
[False,False,False,False],
[True,True,False,False],
[[True,True,True,True]]
</code></pre>
<p>The check should return <code>True</code>. But in case there is something like this</p>
<pre><code class="lang-auto">[[True, False, True,True], &lt;--- wrong
[False,False,False,False],
[True,True,False,False],
[[True,True,True,True]]
</code></pre>
<p>should return <code>False</code> or maybe this</p>
<pre><code class="lang-auto">[[False, False, True,True], &lt;--- wrong
[False,True,False,False], &lt;--- wrong
[True,True,False,False],
[[True,True,True,True]]
</code></pre>
<p>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)?</p>

arya47: <p>Do you mean return true only when false is a successor to True?<br>
Can be done easily, i’ve written a naive implementation O(n^2)</p>
<pre><code class="lang-auto">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
</code></pre>
<p>eg use:</p>
<pre><code class="lang-auto">b = torch.tensor(((False, False, False,False),(False,False,False,False),(True,True,False,False),(True,True,True,True)))
check(b)
</code></pre>

xianqian: <p>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.</p>

KFrank: <p>Hi Xianqian!</p>
<aside class="quote no-group" data-username="xianqian" data-post="1" data-topic="132377" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/xianqian/48/30097_2.png" class="avatar"> xianqian:</div>
<blockquote>
<p>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)?</p>
</blockquote>
</aside>
<p><code>cumprod()</code> – for boolean values – will test for “decreasing values”:</p>
<pre><code class="lang-plaintext">&gt;&gt;&gt; import torch
&gt;&gt;&gt; torch.__version__
'1.9.0'
&gt;&gt;&gt;
&gt;&gt;&gt; b1 = torch.tensor ([
...     [True,  False, False, False],
...     [False, False, False, False],
...     [True,  True,  False, False],
...     [True,  True,  True,  True ]
...     ])
&gt;&gt;&gt;
&gt;&gt;&gt; b2 = torch.tensor ([
...     [True,  False, True,  True ],
...     [False, False, False, False],
...     [True,  True,  False, False],
...     [True,  True,  True,  True ]
...     ])
&gt;&gt;&gt;
&gt;&gt;&gt; b3 = torch.tensor ([
...     [True,  False, True,  True ],
...     [False, True,  False, False],
...     [True,  True,  False, False],
...     [True,  True,  True,  True ]
...     ])
&gt;&gt;&gt;
&gt;&gt;&gt; torch.equal (b1, b1.cumprod (1).bool())
True
&gt;&gt;&gt; torch.equal (b2, b2.cumprod (1).bool())
False
&gt;&gt;&gt; torch.equal (b3, b3.cumprod (1).bool())
False
</code></pre>
<p>To see in a little more detail what is going on, consider:</p>
<pre><code class="lang-plaintext">&gt;&gt;&gt; torch.all (torch.eq (b1, b1.cumprod (1).bool()), 1)
tensor([True, True, True, True])
&gt;&gt;&gt; torch.all (torch.eq (b2, b2.cumprod (1).bool()), 1)
tensor([False,  True,  True,  True])
&gt;&gt;&gt; torch.all (torch.eq (b3, b3.cumprod (1).bool()), 1)
tensor([False, False,  True,  True])
</code></pre>
<p>Best.</p>
<p>K. Frank</p>