<p dir="auto">I've run into some unexpected behavior when using <code class="notranslate">numpy.matmul</code>.  For shape (2,2) array <code class="notranslate">ar1</code> and shape (2,N) array <code class="notranslate">ar2</code>, the function's behavior appears to change unexpectedly with the dimension N.</p>
<h3 dir="auto">Reproducing code example:</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np
ar1 = np.array([[1,0.1],[-0.1,1]])
ar2 = np.vstack([np.ones(100),np.zeros(100)])

ans1 = np.matmul(ar1,ar2[:,:7])
ans2 = np.matmul(ar1,ar2[:,:8])"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>
<span class="pl-s1">ar1</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([[<span class="pl-c1">1</span>,<span class="pl-c1">0.1</span>],[<span class="pl-c1">-</span><span class="pl-c1">0.1</span>,<span class="pl-c1">1</span>]])
<span class="pl-s1">ar2</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">vstack</span>([<span class="pl-s1">np</span>.<span class="pl-en">ones</span>(<span class="pl-c1">100</span>),<span class="pl-s1">np</span>.<span class="pl-en">zeros</span>(<span class="pl-c1">100</span>)])

<span class="pl-s1">ans1</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">matmul</span>(<span class="pl-s1">ar1</span>,<span class="pl-s1">ar2</span>[:,:<span class="pl-c1">7</span>])
<span class="pl-s1">ans2</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">matmul</span>(<span class="pl-s1">ar1</span>,<span class="pl-s1">ar2</span>[:,:<span class="pl-c1">8</span>])</pre></div>
<p dir="auto">In the code above, ans1 gives the expected result of</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="array([[ 1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ],
       [-0.1, -0.1, -0.1, -0.1, -0.1, -0.1, -0.1]])"><pre class="notranslate"><code class="notranslate">array([[ 1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ],
       [-0.1, -0.1, -0.1, -0.1, -0.1, -0.1, -0.1]])
</code></pre></div>
<p dir="auto">Similarly, I get the expected result when slicing ar2 with ar2[:,:i] for any <code class="notranslate">i &lt; 8</code>.  However, ans2 is:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="array([[1.1, 1.1, 1.1, 1.1, 0. , 0. , 0. , 0. ],
       [0.9, 0.9, 0.9, 0.9, 0. , 0. , 0. , 0. ]])"><pre class="notranslate"><code class="notranslate">array([[1.1, 1.1, 1.1, 1.1, 0. , 0. , 0. , 0. ],
       [0.9, 0.9, 0.9, 0.9, 0. , 0. , 0. , 0. ]])
</code></pre></div>
<p dir="auto">for other values of <code class="notranslate">i &gt; 8</code>, the behavior becomes stranger.  E.g. <code class="notranslate">i = 10</code> yields:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="array([[ 1.1,  1.1,  1.1,  1.1,  0. ,  0. ,  0. ,  0. ,  1. ,  1. ],
       [ 0.9,  0.9,  0.9,  0.9,  0. ,  0. ,  0. ,  0. , -0.1, -0.1]])"><pre class="notranslate"><code class="notranslate">array([[ 1.1,  1.1,  1.1,  1.1,  0. ,  0. ,  0. ,  0. ,  1. ,  1. ],
       [ 0.9,  0.9,  0.9,  0.9,  0. ,  0. ,  0. ,  0. , -0.1, -0.1]])
</code></pre></div>
<p dir="auto">and <code class="notranslate">i=20</code> yields:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="array([[ 1.1,  1.1,  1.1,  1.1,  0. ,  0. ,  0. ,  0. ,  1.1,  1.1,  1.1,
         1.1,  0. ,  0. ,  0. ,  0. ,  1. ,  1. ,  1. ,  1. ],
       [ 0.9,  0.9,  0.9,  0.9,  0. ,  0. ,  0. ,  0. ,  0.9,  0.9,  0.9,
         0.9,  0. ,  0. ,  0. ,  0. , -0.1, -0.1, -0.1, -0.1]])"><pre class="notranslate"><code class="notranslate">array([[ 1.1,  1.1,  1.1,  1.1,  0. ,  0. ,  0. ,  0. ,  1.1,  1.1,  1.1,
         1.1,  0. ,  0. ,  0. ,  0. ,  1. ,  1. ,  1. ,  1. ],
       [ 0.9,  0.9,  0.9,  0.9,  0. ,  0. ,  0. ,  0. ,  0.9,  0.9,  0.9,
         0.9,  0. ,  0. ,  0. ,  0. , -0.1, -0.1, -0.1, -0.1]])
</code></pre></div>
<p dir="auto">Have I misunderstood the intended behavior here?  This is definitely not reproducing standard matrix multiplication. Thanks for any help!</p>
<p dir="auto">Ben</p>
<h3 dir="auto">Numpy/Python version information:</h3>

<p dir="auto">1.16.4<br>
3.7.3 (default, Mar 27 2019, 22:11:17)<br>
[GCC 7.3.0]</p>
<p dir="auto">If I take an array and create a view using newbyteorder, the output from <code class="notranslate">tostring</code> is not byteswapped:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="In [2]: import numpy as np

In [3]: x = np.array([1,2,3], dtype=np.int16)
   ...: y = x.byteswap(False)
   ...: z = x.newbyteorder('S')

In [4]: print(x.tostring())
b'\x01\x00\x02\x00\x03\x00'

In [5]: print(y.tostring())
b'\x00\x01\x00\x02\x00\x03'

In [6]: print(z.tostring())
b'\x01\x00\x02\x00\x03\x00'"><pre class="notranslate"><span class="pl-v">In</span> [<span class="pl-c1">2</span>]: <span class="pl-s1">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>

<span class="pl-v">In</span> [<span class="pl-c1">3</span>]: <span class="pl-s1">x</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">int16</span>)
   ...: <span class="pl-s1">y</span> <span class="pl-c1">=</span> <span class="pl-s1">x</span>.<span class="pl-en">byteswap</span>(<span class="pl-c1">False</span>)
   ...: <span class="pl-s1">z</span> <span class="pl-c1">=</span> <span class="pl-s1">x</span>.<span class="pl-en">newbyteorder</span>(<span class="pl-s">'S'</span>)

<span class="pl-v">In</span> [<span class="pl-c1">4</span>]: <span class="pl-en">print</span>(<span class="pl-s1">x</span>.<span class="pl-en">tostring</span>())
<span class="pl-s">b'<span class="pl-cce">\x01</span><span class="pl-cce">\x00</span><span class="pl-cce">\x02</span><span class="pl-cce">\x00</span><span class="pl-cce">\x03</span><span class="pl-cce">\x00</span>'</span>

<span class="pl-v">In</span> [<span class="pl-c1">5</span>]: <span class="pl-en">print</span>(<span class="pl-s1">y</span>.<span class="pl-en">tostring</span>())
<span class="pl-s">b'<span class="pl-cce">\x00</span><span class="pl-cce">\x01</span><span class="pl-cce">\x00</span><span class="pl-cce">\x02</span><span class="pl-cce">\x00</span><span class="pl-cce">\x03</span>'</span>

<span class="pl-v">In</span> [<span class="pl-c1">6</span>]: <span class="pl-en">print</span>(<span class="pl-s1">z</span>.<span class="pl-en">tostring</span>())
<span class="pl-s">b'<span class="pl-cce">\x01</span><span class="pl-cce">\x00</span><span class="pl-cce">\x02</span><span class="pl-cce">\x00</span><span class="pl-cce">\x03</span><span class="pl-cce">\x00</span>'</span></pre></div>
<p dir="auto">I think <code class="notranslate">z.tostring()</code> should match <code class="notranslate">y.tostring()</code> instead?</p>
<p dir="auto">I'm using Numpy 1.11.2 with Python 3.6</p>
<p dir="auto">A related issue is that the <code class="notranslate">data</code> memoryview on <code class="notranslate">z</code> is also not byteswapped, i.e.:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np
from io import BytesIO

x = np.array([1,2,3], dtype=np.int16)
y = x.byteswap(False)
z = x.newbyteorder('S')

for array in [x, y, z]:

    b1 = BytesIO()
    b1.write(array.data)
    b1.seek(0)
    print(b1.read())"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>
<span class="pl-k">from</span> <span class="pl-s1">io</span> <span class="pl-k">import</span> <span class="pl-v">BytesIO</span>

<span class="pl-s1">x</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">int16</span>)
<span class="pl-s1">y</span> <span class="pl-c1">=</span> <span class="pl-s1">x</span>.<span class="pl-en">byteswap</span>(<span class="pl-c1">False</span>)
<span class="pl-s1">z</span> <span class="pl-c1">=</span> <span class="pl-s1">x</span>.<span class="pl-en">newbyteorder</span>(<span class="pl-s">'S'</span>)

<span class="pl-k">for</span> <span class="pl-s1">array</span> <span class="pl-c1">in</span> [<span class="pl-s1">x</span>, <span class="pl-s1">y</span>, <span class="pl-s1">z</span>]:

    <span class="pl-s1">b1</span> <span class="pl-c1">=</span> <span class="pl-v">BytesIO</span>()
    <span class="pl-s1">b1</span>.<span class="pl-en">write</span>(<span class="pl-s1">array</span>.<span class="pl-s1">data</span>)
    <span class="pl-s1">b1</span>.<span class="pl-en">seek</span>(<span class="pl-c1">0</span>)
    <span class="pl-en">print</span>(<span class="pl-s1">b1</span>.<span class="pl-en">read</span>())</pre></div>
<p dir="auto">gives:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="b'\x01\x00\x02\x00\x03\x00'
b'\x00\x01\x00\x02\x00\x03'
b'\x01\x00\x02\x00\x03\x00'"><pre class="notranslate"><code class="notranslate">b'\x01\x00\x02\x00\x03\x00'
b'\x00\x01\x00\x02\x00\x03'
b'\x01\x00\x02\x00\x03\x00'
</code></pre></div>