Issue 1:
matmul (aka @) is extremely slow when one of the two arrays is the real or imaginary part of a complex array extracted with .real or .imag.

This was already observed in this issue, but was not marked as a bug, while I think this should be.

Reproducing code example:

Consider the following benchmark.

import numpy as np
from timeit import repeat

A = np.random.rand(200, 1000) + 0j
B = np.random.rand(1000, 50000)

def time(stmt):
print(f'testing {stmt}')
res = repeat(stmt, globals={'A':A,'B':B, 'np':np}, number=1, repeat=10)
res = np.array(res)*1000
print(f'{np.mean(res):.0f} ms ± {np.std(res):.0f} ms per loop (mean ± std. dev. of 10 runs, 1 loop each)')

time('A @ B')
time('A.real @ B')
time('A.imag @ B')
time('A.astype(np.float64()) @ B')
time('A.real.astype(np.float64()) @ B')
time('A.real.copy() @ B')

On my PC the results are:

testing A @ B
1046 ms ± 73 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)

testing A.real @ B
21980 ms ± 4978 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)

testing A.imag @ B
18140 ms ± 970 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)

testing A.astype(np.float64()) @ B
<string>:6: ComplexWarning: Casting complex values to real discards the imaginary part
161 ms ± 16 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)

testing A.real.astype(np.float64()) @ B
166 ms ± 12 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)

testing A.real.copy() @ B
150 ms ± 11 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)

Note how the most trivial/elegant/obvious solution A.real @ B (and A.imag @ B depending on what you have to do) is 120 times slower than A.real.copy() @ B

Also A@B is much slower, but I suspect this has to be with the fact that in this case A is complex bringing matmul on a different path, even if A.imag is all 0.

NumPy/Python version information:

import sys, numpy; print(numpy.__version__, sys.version)
1.18.1 3.7.4 (default, Aug 9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)]

Issue 2:
Describe the issue:

Hi there,

Let me go straight to the point. I have a list of arrays which I want to apply np.argsort() to. I was finding wrong answers using the axis option, so I tried to debug it with a simple loop, printing everything.

The results clearly don't match expectations in some rows, and frankly it's very weird. I am pasting the code (and output in a comment) below.

Thanks in advance.

Reproduce the code example:

mat = np.array([[0.00514059, 0.00506887, 0.00574913, 0.00531327, 0.00518162],
[0.00494017, 0.00489627, 0.00566709, 0.00454714, 0.00499841],
[0.00493342, 0.00488984, 0.00564926, 0.00505881, 0.00494269],
[0.00491196, 0.00488021, 0.00528805, 0.00511658, 0.00481696],
[0.00487965, 0.00483828, 0.00538671, 0.004878 , 0.00493741]])

for m in mat:
print(m)
print(np.argsort(m)

'''
[0.00514059 0.00506887 0.00574913 0.00531327 0.00518162]
[1 0 4 3 2]
[0.00494017 0.00489627 0.00566709 0.00454714 0.00499841]
[3 1 0 4 2]
[0.00493342 0.00488984 0.00564926 0.00505881 0.00494269]
[1 0 4 3 2]
[0.00491196 0.00488021 0.00528805 0.00511658 0.00481696]
[4 1 0 3 2]
[0.00487965 0.00483828 0.00538671 0.004878 0.00493741]
[1 3 0 4 2]
'''

Error message:

No response

NumPy/Python version information:

1.20.3 3.9.7 (default, Aug 31 2021, 13:28:12)

[GCC 11.1.0]