Skip to content

Commit

Permalink
BUG: Make diag, diagonal return 1-D arrays for matrix arguments.
Browse files Browse the repository at this point in the history
This is an ugly hack to preserve backwards compatibility for code
that uses matrices. It is needed since both diag and diagonal have
been changed to preserve subtypes otherwise.

Note that a.diagonal() still returns matrices when a is a matrix.
  • Loading branch information
charris committed Jan 4, 2015
1 parent 7fbc43b commit ad2d264
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
26 changes: 17 additions & 9 deletions numpy/core/fromnumeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import types
import warnings

import numpy as np
from .. import VisibleDeprecationWarning
from . import multiarray as mu
from . import umath as um
from . import numerictypes as nt
from .numeric import asarray, array, asanyarray, concatenate
from . import _methods


_dt_ = nt.sctype2char


Expand Down Expand Up @@ -1199,9 +1201,9 @@ def diagonal(a, offset=0, axis1=0, axis2=1):
just ignore all of the above.
If you depend on the current behavior, then we suggest copying the
returned array explicitly, i.e., use ``np.diagonal(a).copy()`` instead of
just ``np.diagonal(a)``. This will work with both past and future versions
of NumPy.
returned array explicitly, i.e., use ``np.diagonal(a).copy()`` instead
of just ``np.diagonal(a)``. This will work with both past and future
versions of NumPy.
Parameters
----------
Expand All @@ -1220,11 +1222,13 @@ def diagonal(a, offset=0, axis1=0, axis2=1):
Returns
-------
array_of_diagonals : ndarray
If `a` is 2-D, a 1-D array of the same type as `a` containing the
diagonal is returned (or 2-D matrix for matrix input).
If the dimension of `a` is larger, then an array of diagonals is
returned, "packed" from left-most dimension to right-most (e.g.,
if `a` is 3-D, then the diagonals are "packed" along rows).
If `a` is 2-D and not a matrix, a 1-D array of the same type as `a`
containing the diagonal is returned. If `a` is a matrix, a 1-D
array containing the diagonal is returned in order to maintain
backward compatibility. If the dimension of `a` is greater than
two, then an array of diagonals is returned, "packed" from
left-most dimension to right-most (e.g., if `a` is 3-D, then the
diagonals are "packed" along rows).
Raises
------
Expand Down Expand Up @@ -1273,7 +1277,11 @@ def diagonal(a, offset=0, axis1=0, axis2=1):
[5, 7]])
"""
return asanyarray(a).diagonal(offset, axis1, axis2)
if isinstance(a, np.matrix):
# Make diagonal of matrix 1-D to preserve backward compatibility.
return asarray(a).diagonal(offset, axis1, axis2)
else:
return asanyarray(a).diagonal(offset, axis1, axis2)


def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None):
Expand Down
4 changes: 2 additions & 2 deletions numpy/lib/twodim_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from numpy.core.numeric import (
asanyarray, arange, zeros, greater_equal, multiply, ones, asarray,
where, int8, int16, int32, int64, empty, promote_types
where, int8, int16, int32, int64, empty, promote_types, diagonal,
)
from numpy.core import iinfo

Expand Down Expand Up @@ -307,7 +307,7 @@ def diag(v, k=0):
res[:n-k].flat[i::n+1] = v
return res
elif len(s) == 2:
return v.diagonal(k)
return diagonal(v, k)
else:
raise ValueError("Input must be 1- or 2-d.")

Expand Down
14 changes: 7 additions & 7 deletions numpy/matrixlib/tests/test_numeric.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
from __future__ import division, absolute_import, print_function

import numpy as np
from numpy.testing import assert_equal, TestCase, run_module_suite
from numpy.core import ones
from numpy import matrix, diagonal, diag

class TestDot(TestCase):
def test_matscalar(self):
b1 = matrix(ones((3, 3), dtype=complex))
b1 = np.matrix(np.ones((3, 3), dtype=complex))
assert_equal(b1*1.0, b1)


def test_diagonal():
b1 = matrix([[1,2],[3,4]])
diag_b1 = matrix([[1, 4]])
b1 = np.matrix([[1,2],[3,4]])
diag_b1 = np.matrix([[1, 4]])
array_b1 = np.array([1, 4])

assert_equal(b1.diagonal(), diag_b1)
assert_equal(diagonal(b1), diag_b1)
assert_equal(diag(b1), diag_b1)
assert_equal(np.diagonal(b1), array_b1)
assert_equal(np.diag(b1), array_b1)


if __name__ == "__main__":
Expand Down

0 comments on commit ad2d264

Please sign in to comment.