Torch.argsort Error

pymex: <p>The example of argsort on the documentation page <a href="https://pytorch.org/docs/stable/generated/torch.argsort.html" class="inline-onebox" rel="noopener nofollow ugc">torch.argsort — PyTorch 2.3 documentation</a></p>
<p>has an error on the first line of output. That is, for the first row [ 0.0785,  1.5267, -0.8521,  0.4065], argsort outputs [2, 0, 3, 1].  However, the indices give the descending order, rather than the ascending order.  All other rows are ok.</p>
<p>Here is what is on the documentation page (and inputting the same “a” as given, locally, also replicates the issue):</p>
<blockquote>
<blockquote>
<blockquote>
<p>a = torch.randn(4, 4)<br>
a<br>
tensor([[ 0.0785,  1.5267, -0.8521,  0.4065],<br>
[ 0.1598,  0.0788, -0.0745, -1.2700],<br>
[ 1.2208,  1.0722, -0.7064,  1.2564],<br>
[ 0.0669, -0.2318, -0.8229, -0.9280]])</p>
</blockquote>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p>torch.argsort(a, dim=1)<br>
tensor([[2, 0, 3, 1],<br>
[3, 2, 1, 0],<br>
[2, 1, 0, 3],<br>
[3, 2, 1, 0]])</p>
</blockquote>
</blockquote>
</blockquote>

anantguptadbl: <aside class="quote no-group" data-username="pymex" data-post="1" data-topic="206034">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/p/6de8d8/48.png" class="avatar"> pymex:</div>
<blockquote>
<p>That is, for the first row [ 0.0785, 1.5267, -0.8521, 0.4065], argsort outputs [2, 0, 3, 1]</p>
</blockquote>
</aside>
<p><a class="mention" href="/u/pymex">@pymex</a></p>
<pre><code class="lang-auto">[ 0.0785, 1.5267, -0.8521, 0.4065]
</code></pre>
<p>Output</p>
<pre><code class="lang-auto"> [2, 0, 3, 1]
</code></pre>
<p>is correct by ascending<br>
2 → -0.8521<br>
0 → 0.0785<br>
3 → 0.4065<br>
1 → 1.5267</p>
<p>Is there anything that i am missing?</p>

Narayanan_R: <p>The code is working as it should, perhaps you got confused with the array indices <img src="https://discuss.pytorch.org/images/emoji/apple/sweat_smile.png?v=12" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" loading="lazy" width="20" height="20"></p>

anantguptadbl: <p><a class="mention" href="/u/pymex">@pymex</a><br>
Please read the docs<br>
<a href="https://numpy.org/doc/stable/reference/generated/numpy.argsort.html" class="onebox" target="_blank" rel="noopener nofollow ugc">https://numpy.org/doc/stable/reference/generated/numpy.argsort.html</a></p>
<p>Sometimes it is difficult to wrap your head around argsort. Request you to try out with a 1d array with simple integers</p>

ptrblck: <p>From the <a href="https://pytorch.org/docs/stable/generated/torch.argsort.html#torch.argsort">docs</a>:</p>
<blockquote>
<p>Returns the indices that sort a tensor along a given dimension in ascending order by value.</p>
</blockquote>
<p>which is exactly what it does and what <a class="mention" href="/u/anantguptadbl">@anantguptadbl</a> described:</p>
<pre data-code-wrap="python"><code class="lang-python">x = torch.tensor([ 0.0785,  1.5267, -0.8521,  0.4065])
&gt;&gt;&gt; idx = torch.argsort(x)
&gt;&gt;&gt; print(idx)
tensor([2, 0, 3, 1])
&gt;&gt;&gt; x_sorted = x[idx]
&gt;&gt;&gt; print(x_sorted)
tensor([-0.8521,  0.0785,  0.4065,  1.5267])
</code></pre>
<p>The returned indices sort the tensor in ascending order.<br>
Further:</p>
<blockquote>
<p>This is the second value returned by <a href="https://pytorch.org/docs/stable/generated/torch.sort.html#torch.sort"><code>torch.sort()</code></a>. See its documentation for the exact semantics of this method.</p>
</blockquote>
<p>which is also the case:</p>
<pre data-code-wrap="python"><code class="lang-python">&gt;&gt;&gt; torch.sort(x)
torch.return_types.sort(
values=tensor([-0.8521,  0.0785,  0.4065,  1.5267]),
indices=tensor([2, 0, 3, 1]))
</code></pre>

pymex: <aside class="quote no-group" data-username="pymex" data-post="4" data-topic="206034">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/p/6de8d8/48.png" class="avatar"> pymex:</div>
<blockquote>
<p>2 → 0.0785<br>
0 → 1.5267<br>
3 → -0.8521<br>
1 → 0.4065</p>
<p>In other words:<br>
0 → 1.5267<br>
1 → 0.4065<br>
2 → 0.0785<br>
3 → -0.8521</p>
</blockquote>
</aside>
<p><a class="mention" href="/u/ptrblck">@ptrblck</a> The indices map as above.  Is this not what occurs when as noted when you write:</p>
<p>x = torch.tensor([ 0.0785,  1.5267, -0.8521,  0.4065])</p>
<blockquote>
<blockquote>
<blockquote>
<p>idx = torch.argsort(x)<br>
print(idx)<br>
tensor([2, 0, 3, 1])</p>
</blockquote>
</blockquote>
</blockquote>
<p>In that case, when you traverse the indices from 0 to 3, how then does the mapping yield the values in ascending order when the mapping, as noted above, shows the values descending. Perhaps you can clarify this issue.</p>

wzsmith: <p><code>argsort()</code> returns the the ordering of the <em>original</em> list’s indeces.</p>
<p>In your example, after running <code>idx = torch.argsort(x)</code>, the value of <code>idx</code> is <code>tensor([2, 0, 3, 1])</code>. This indicates that the sorted elements of <code>x</code> should appear in the following order: <code>x[2], x[0], x[3], x[1]</code>. With original values of,</p>
<pre><code class="lang-auto">x = [0.0785, 1.5267, -0.8521, 0.4065]
#       0       1        2       3
</code></pre>
<p>the sorted order should be:</p>
<pre data-code-wrap="python"><code class="lang-python">x[idx] = [-0.8521, 0.0785, 0.4065, 1.5267]
#             2       0       3       1
</code></pre>

ptrblck: <p>Check my posted code snippets, which shows:</p>
<pre data-code-wrap="python"><code class="lang-python">&gt;&gt;&gt; x_sorted = x[idx]
&gt;&gt;&gt; print(x_sorted)
tensor([-0.8521,  0.0785,  0.4065,  1.5267])
</code></pre>
<p>and matches what the docs say:</p>
<blockquote>
<p>Returns the indices that sort a tensor along a given dimension in ascending order by value.</p>
</blockquote>
<p>and which was already clarified multiple times.</p>

ptrblck: <p>I don’t think you are understanding the documentation and I don’t know how to explain it any further besides reciting what the simple sentence in the docs already states.<br>
The returned indices sort the passed input tensor as clearly described. The same indices are returned via <code>torch.sort</code> and correspond to the sorted values.<br>
Three different users tried to explain this behavior, so unsure how to further help.</p>
<p>For others in case you are visiting this topic: the docs are correct and do not need any changes.</p>

pymex: <p>Ok. The confusing part is the documentation.  At first glance, the last three rows give the impression that the indices of the elements are those of the sorted input tensor.  After all, three rows give this impression and one row seems out of sync. However, that is not the case.</p>
<p>The documentation requires further digging by saying that the indices are the “second value returned by torch.sort(). See its documentation”  After looking this up, it becomes clear that the indices are the “are the indices of the elements in the original input tensor” rather than the sorted tensor.</p>
<p>It would be well to simply state in the documentation that the returned indices are the “indices of the elements in the original input tensor” rather than saying “second value returned by torch.sort(). See its documentation”.  After all, I’ve seen this same issue brought up before in other posts (but the replies and answers were not clear). A simple fix would be to directly state this fact on the page rather than require additional digging. It is a better practice to be as clear as possible up front rather than to require readers to dig further than needed, especially when three of the four rows give a different impression of what the expected output should be. It makes one row seem wrong.</p>