2

I'm trying to figure out what is going on here, but I'm a little bit baffled. I am getting unexpected results working with a transposed NumPy identity matrix (which should have no effect). For example:

import numpy as np

N = 1000

# case 1:
A = np.eye(N) # the identity matrix
At = A.T # it's transpose
print 'A == At: {}'.format(np.all(A==At)) # should be true
Ad = At.dot(A) # identity * identity = identity
print 'A == Ad: {}'.format(np.all(A==Ad)) # should also be true

Outputs:

A == At: True
A == Ad: False

This is incorrect since the 2nd statement should be true. Now if we do this instead:

import numpy as np

N = 1000

# case 2:
B = np.eye(N) # the identity matrix
Bt = np.copy(B.T) # it's transpose <==== added copy here
print 'B == Bt: {}'.format(np.all(B==Bt)) # should be true
Bd = Bt.dot(B) # identity * identity = identity
print 'B == Bd: {}'.format(np.all(B==Bd)) # should also be true

Outputs:

B == Bt: True
B == Bd: True

This is the desired result. The only difference is the addition of the copy operation in the 2nd case. Another funny thing is that if I set N to a smaller number (say 100 instead of 1000), the answers are correct in both cases.

What is going on?

(Edit: I am running Numpy version '1.11.1', on OS X 10.10.5 with Python 2.7.10 and IPython 4.0.0)

  • 2
    I just ran your code and get ``True`` for both cases. Could it be either machine or numpy version dependent? – alexblae Jan 17 '17 at 12:59
  • Good point @alexblae, I edited my question with my Numpy version and machine information. – frankchannel Jan 17 '17 at 13:09
  • @frankchannel I guess it is a bug in your numpy. – Stop harming Monica Jan 17 '17 at 13:14
  • Do you know where the first incorrect/false value occurs? E.g. `np.argwhere(A!=Ad)[0]` – Alex Riley Jan 17 '17 at 13:14
  • I am using the same version of numpy but with Python 2.7.6 on a Linux machine. Is it possible that A.T is changing the ``dtype`` of the array. Could you print the dtype for ``A , At, Ad``? – alexblae Jan 17 '17 at 13:16
  • @ajcr: np.argwhere(A != Ad)[0] returns: array([128, 128]) – frankchannel Jan 17 '17 at 13:21
  • Looks like a buffer issue: what is `np.getbufsize()`? I think it will be equal to something like `128 * 128` or some multiple of that. – Alex Riley Jan 17 '17 at 13:22
  • @alexblae: A.dtype = dtype('float64'), At.dtype = dtype('float64'), Ad.dtype = dtype('float64'). I also tried upgrading Numpy with pip, but that didn't yield a different result. – frankchannel Jan 17 '17 at 13:23
  • @ajcr: np.getbufsize() = 8192. I'm not sure I've heard of buffer sizes in NumPy? – frankchannel Jan 17 '17 at 13:24
  • Yes; NumPy iterates over arrays chunks at a time, reading values into a temporary buffer. See for instance: http://stackoverflow.com/a/26280846/3923281. Your issue is very probably related to this implementation detail. – Alex Riley Jan 17 '17 at 13:27
  • @ajcr: Thanks for that link. My problem seems quite similar, although it's a little different because I don't try to modify any of the arrays after they are instantiated. So even if At is a 'view' of A, At.dot(A), should still return the correct result (I would guess), since I never try to modify A or At. – frankchannel Jan 17 '17 at 16:14
  • I agree it doesn't completely solve this issue, although I think that it is very likely to be related. I'm unable to replicate the results you get (the arrays are equal for me), but if I find the answer to the issue I'll certainly post back here. – Alex Riley Jan 17 '17 at 16:26

0 Answers0