8000 DOC: advise against use of matrix. by mhvk · Pull Request #10973 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

DOC: advise against use of matrix. #10973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
8000
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/source/reference/arrays.classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ Matrix objects
.. index::
single: matrix

.. note::
It is strongly advised *not* to use the matrix subclass. As described
below, it makes writing functions that deal consistently with matrices
and regular arrays very difficult. Currently, they are mainly used for
interacting with ``scipy.sparse``. We hope to provide an alternative
for this use, however, and eventually remove the ``matrix`` subclass.

:class:`matrix` objects inherit from the ndarray and therefore, they
have the same attributes and methods of ndarrays. There are six
important differences of matrix objects, however, that may lead to
Expand Down
98 changes: 34 additions & 64 deletions doc/source/user/numpy-for-matlab-users.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ Some Key Differences
in linear algebra.
- In NumPy the basic type is a multidimensional ``array``. Operations
on these arrays in all dimensionalities including 2D are element-wise
operations. However, there is a special ``matrix`` type for doing
linear algebra, which is just a subclass of the ``array`` class.
Operations on matrix-class arrays are linear algebra operations.
operations. One needs to use specific functions for linear algebra
(though for matrix multiplication, one can use the ``@`` operator
in python 3.5 and above).

* - MATLAB® uses 1 (one) based indexing. The initial element of a
sequence is found using a(1).
Expand All @@ -50,8 +50,8 @@ Some Key Differences
an excellent general-purpose programming language. While Matlab's
syntax for some array manipulations is more compact than
NumPy's, NumPy (by virtue of being an add-on to Python) can do many
things that Matlab just cannot, for instance subclassing the main
array type to do both array and matrix math cleanly.
things that Matlab just cannot, for instance dealing properly with
stacks of matrices.

* - In MATLAB®, arrays have pass-by-value semantics, with a lazy
copy-on-write scheme to prevent actually creating copies until they
Expand All @@ -63,8 +63,10 @@ Some Key Differences
'array' or 'matrix'? Which should I use?
========================================

NumPy provides, in addition to ``np.ndarray``, an additional matrix type
that you may see used in some existing code. Which one to use?
Historically, NumPy has provided a special matrix type, `np.matrix`, which
is a subclass of ndarray which makes binary operations linear algebra
operations. You may see it used in some existing code instead of `np.array`.
So, which one to use?

Short answer
------------
Expand All @@ -82,6 +84,8 @@ had to use ``dot`` instead of ``*`` to multiply (reduce) two tensors
(scalar product, matrix vector multiplication etc.). Since Python 3.5 you
can use the matrix multiplication ``@`` operator.

Given the above, we intend to deprecate ``matrix`` eventually.

Long answer
-----------

Expand All @@ -91,12 +95,14 @@ for many kinds of numerical computing, while ``matrix`` is intended to
facilitate linear algebra computations specifically. In practice there
are only a handful of key differences between the two.

- Operator ``*``, ``dot()``, and ``multiply()``:
- Operators ``*`` and ``@``, functions ``dot()``, and ``multiply()``:

- For ``array``, **'``*``\ ' means element-wise multiplication**,
and the ``dot()`` function is used for matrix multiplication.
- For ``matrix``, **'``*``\ ' means matrix multiplication**, and the
``multiply()`` function is used for element-wise multiplication.
- For ``array``, **``*`` means element-wise multiplication**, while
**``@`` means matrix multiplication**; they have associated functions
``multiply()`` and ``dot()``. (Before python 3.5, ``@`` did not exist
and one had to use ``dot()`` for matrix multiplication).
- For ``matrix``, **``*`` means matrix multiplication**, and for
element-wise multiplication one has to use the ``multiply()`` function.

- Handling of vectors (one-dimensional arrays)

Expand Down Expand Up @@ -132,15 +138,13 @@ There are pros and cons to using both:

- ``array``

- ``:)`` Element-wise multiplication is easy: ``A*B``.
- ``:(`` You have to remember that matrix multiplication has its own
operator, ``@``.
- ``:)`` You can treat one-dimensional arrays as *either* row or column
vectors. ``dot(A,v)`` treats ``v`` as a column vector, while
``dot(v,A)`` treats ``v`` as a row vector. This can save you having to
vectors. ``A @ v`` treats ``v`` as a column vector, while
``v @ A`` treats ``v`` as a row vector. This can save you having to
type a lot of transposes.
- ``<:(`` Having to use the ``dot()`` function for matrix-multiply is
messy -- ``dot(dot(A,B),C)`` vs. ``A*B*C``. This isn't an issue with
Python >= 3.5 because the ``@`` operator allows it to be written as
``A @ B @ C``.
- ``:)`` Element-wise multiplication is easy: ``A*B``.
- ``:)`` ``array`` is the "default" NumPy type, so it gets the most
testing, and is the type most likely to be returned by 3rd party
code that uses NumPy.
Expand All @@ -149,6 +153,8 @@ There are pros and cons to using both:
with that.
- ``:)`` *All* operations (``*``, ``/``, ``+``, ``-`` etc.) are
element-wise.
- ``:(`` Sparse matrices from ``scipy.sparse`` do not interact as well
with arrays.

- ``matrix``

Expand All @@ -162,35 +168,17 @@ There are pros and cons to using both:
argument. This shouldn't happen with NumPy functions (if it does
it's a bug), but 3rd party code based on NumPy may not honor type
preservation like NumPy does.
- ``:)`` ``A*B`` is matrix multiplication, so more convenient for
linear algebra (For Python >= 3.5 plain arrays have the same convenience
with the ``@`` operator).
- ``:)`` ``A*B`` is matrix multiplication, so it looks just like you write
it in linear algebra (For Python >= 3.5 plain arrays have the same
convenience with the ``@`` operator).
- ``<:(`` Element-wise multiplication requires calling a function,
``multiply(A,B)``.
- ``<:(`` The use of operator overloading is a bit illogical: ``*``
does not work element-wise but ``/`` does.
- Interaction with ``scipy.sparse`` is a bit cleaner.

The ``array`` is thus much more advisable to use.

Facilities for Matrix Users
===========================

NumPy has some features that facilitate the use of the ``matrix`` type,
which hopefully make things easier for Matlab converts.

- A ``matlib`` module has been added that contains matrix versions of
common array constructors like ``ones()``, ``zeros()``, ``empty()``,
``eye()``, ``rand()``, ``repmat()``, etc. Normally these functions
return ``array``\ s, but the ``matlib`` versions return ``matrix``
objects.
- ``mat`` has been changed to be a synonym for ``asmatrix``, rather
than ``matrix``, thus making it a concise way to convert an ``array``
to a ``matrix`` without copying the data.
- Some top-level functions have been removed. For example
``numpy.rand()`` now needs to be accessed as ``numpy.random.rand()``.
Or use the ``rand()`` from the ``matlib`` module. But the
"numpythonic" way is to use ``numpy.random.random()``, which takes a
tuple for the shape, like other numpy functions.
The ``array`` is thus much more advisable to use. Indeed, we intend to
deprecate ``matrix`` eventually.

Table of Rough MATLAB-NumPy Equivalents
=======================================
Expand All @@ -200,23 +188,6 @@ expressions. **These are not exact equivalents**, but rather should be
taken as hints to get you going in the right direction. For more detail
read the built-in documentation on the NumPy functions.

Some care is necessary when writing functions that take arrays or
matrices as arguments --- if you are expecting an ``array`` and are
given a ``matrix``, or vice versa, then '\*' (multiplication) will give
you unexpected results. You can convert back and forth between arrays
and matrices using

- ``asarray``: always returns an object of type ``array``
- ``asmatrix`` or ``mat``: always return an object of type
``matrix``
- ``asanyarray``: always returns an ``array`` object or a subclass
derived from it, depending on the input. For instance if you pass in
a ``matrix`` it returns a ``matrix``.

These functions all accept both arrays and matrices (among other things
like Python lists), and thus are useful when writing functions that
should accept any array-like object.

In the table below, it is assumed that you have executed the following
commands in Python:

Expand Down Expand Up @@ -309,8 +280,7 @@ Linear Algebra Equivalents
- 2x3 matrix literal

* - ``[ a b; c d ]``
- ``vstack([hstack([a,b]), hstack([c,d])])`` or
``block([[a, b], [c, d])``
- ``block([[a,b], [c,d]])``
- construct a matrix from blocks ``a``, ``b``, ``c``, and ``d``

* - ``a(end)``
Expand Down Expand Up @@ -369,7 +339,7 @@ Linear Algebra Equivalents
- conjugate transpose of ``a``

* - ``a * b``
- ``a.dot(b)`` or ``a@b`` (Python 3.5 or newer)
- ``a @ b``
- matrix multiply

* - ``a .* b``
Expand Down Expand Up @@ -520,7 +490,7 @@ Linear Algebra Equivalents
from each pair

* - ``norm(v)``
- ``sqrt(dot(v,v))`` or ``np.linalg.norm(v)``
- ``sqrt(v @ v)`` or ``np.linalg.norm(v)``
- L2 norm of vector ``v``

* - ``a & b``
Expand Down
10 changes: 5 additions & 5 deletions doc/source/user/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -297,19 +297,19 @@ created and filled with the result.

Unlike in many matrix languages, the product operator ``*`` operates
elementwise in NumPy arrays. The matrix product can be performed using
the ``dot`` function or method::
the ``@`` operator (in python >=3.5) or the ``dot`` function or method::

>>> A = np.array( [[1,1],
... [0,1]] )
>>> B = np.array( [[2,0],
... [3,4]] )
>>> A*B # elementwise product
>>> A * B # elementwise product
array([[2, 0],
[0, 4]])
>>> A.dot(B) # matrix product
>>> A @ B # matrix product
array([[5, 4],
[3, 4]])
>>> np.dot(A, B) # another matrix product
>>> A.dot(B) # another matrix product
array([[5, 4],
[3, 4]])

Expand Down Expand Up @@ -1357,7 +1357,7 @@ See linalg.py in numpy folder for more.
[ 0., 1.]])
>>> j = np.array([[0.0, -1.0], [1.0, 0.0]])

>>> np.dot (j, j) # matrix product
>>> j @ j # matrix product
array([[-1., 0.],
[ 0., -1.]])

Expand Down
0