1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
|
.. _numpy-for-matlab-users:
======================
NumPy for Matlab users
======================
Introduction
============
MATLAB® and NumPy/SciPy have a lot in common. But there are many
differences. NumPy and SciPy were created to do numerical and scientific
computing in the most natural way with Python, not to be MATLAB® clones.
This page is intended to be a place to collect wisdom about the
differences, mostly for the purpose of helping proficient MATLAB® users
become proficient NumPy and SciPy users.
.. raw:: html
<style>
table.docutils td { border: solid 1px #ccc; }
</style>
Some Key Differences
====================
.. list-table::
* - In MATLAB®, the basic data type is a multidimensional array of
double precision floating point numbers. Most expressions take such
arrays and return such arrays. Operations on the 2-D instances of
these arrays are designed to act more or less like matrix operations
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. 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).
:ref:`See note INDEXING <numpy-for-matlab-users.notes>`
- Python uses 0 (zero) based indexing. The initial element of a
sequence is found using a[0].
* - MATLAB®'s scripting language was created for doing linear algebra.
The syntax for basic matrix operations is nice and clean, but the API
for adding GUIs and making full-fledged applications is more or less
an afterthought.
- NumPy is based on Python, which was designed from the outset to be
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 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
are actually needed. Slice operations copy parts of the array.
- In NumPy arrays have pass-by-reference semantics. Slice operations
are views into an array.
'array' or 'matrix'? Which should I 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
------------
**Use arrays**.
- They are the standard vector/matrix/tensor type of numpy. Many numpy
functions return arrays, not matrices.
- There is a clear distinction between element-wise operations and
linear algebra operations.
- You can have standard vectors or row/column vectors if you like.
Until Python 3.5 the only disadvantage of using the array type was that you
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
-----------
NumPy contains both an ``array`` class and a ``matrix`` class. The
``array`` class is intended to be a general-purpose n-dimensional array
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.
- Operators ``*`` and ``@``, functions ``dot()``, and ``multiply()``:
- 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)
- For ``array``, the **vector shapes 1xN, Nx1, and N are all different
things**. Operations like ``A[:,1]`` return a one-dimensional array of
shape N, not a two-dimensional array of shape Nx1. Transpose on a
one-dimensional ``array`` does nothing.
- For ``matrix``, **one-dimensional arrays are always upconverted to 1xN
or Nx1 matrices** (row or column vectors). ``A[:,1]`` returns a
two-dimensional matrix of shape Nx1.
- Handling of higher-dimensional arrays (ndim > 2)
- ``array`` objects **can have number of dimensions > 2**;
- ``matrix`` objects **always have exactly two dimensions**.
- Convenience attributes
- ``array`` **has a .T attribute**, which returns the transpose of
the data.
- ``matrix`` **also has .H, .I, and .A attributes**, which return
the conjugate transpose, inverse, and ``asarray()`` of the matrix,
respectively.
- Convenience constructor
- The ``array`` constructor **takes (nested) Python sequences as
initializers**. As in, ``array([[1,2,3],[4,5,6]])``.
- The ``matrix`` constructor additionally **takes a convenient
string initializer**. As in ``matrix("[1 2 3; 4 5 6]")``.
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. ``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.
- ``:)`` ``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.
- ``:)`` Is quite at home handling data of any number of dimensions.
- ``:)`` Closer in semantics to tensor algebra, if you are familiar
with that.
- ``:)`` *All* operations (``*``, ``/``, ``+``, ``-`` etc.) are
element-wise.
- ``:(`` Sparse matrices from ``scipy.sparse`` do not interact as well
with arrays.
- ``matrix``
- ``:\\`` Behavior is more like that of MATLAB® matrices.
- ``<:(`` Maximum of two-dimensional. To hold three-dimensional data you
need ``array`` or perhaps a Python list of ``matrix``.
- ``<:(`` Minimum of two-dimensional. You cannot have vectors. They must be
cast as single-column or single-row matrices.
- ``<:(`` Since ``array`` is the default in NumPy, some functions may
return an ``array`` even if you give them a ``matrix`` as an
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 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. Indeed, we intend to
deprecate ``matrix`` eventually.
Table of Rough MATLAB-NumPy Equivalents
=======================================
The table below gives rough equivalents for some common MATLAB®
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.
In the table below, it is assumed that you have executed the following
commands in Python:
::
from numpy import *
import scipy.linalg
Also assume below that if the Notes talk about "matrix" that the
arguments are two-dimensional entities.
General Purpose Equivalents
---------------------------
.. list-table::
:header-rows: 1
* - **MATLAB**
- **numpy**
- **Notes**
* - ``help func``
- ``info(func)`` or ``help(func)`` or ``func?`` (in Ipython)
- get help on the function *func*
* - ``which func``
- `see note HELP <numpy-for-matlab-users.notes>`__
- find out where *func* is defined
* - ``type func``
- ``source(func)`` or ``func??`` (in Ipython)
- print source for *func* (if not a native function)
* - ``a && b``
- ``a and b``
- short-circuiting logical AND operator (Python native operator);
scalar arguments only
* - ``a || b``
- ``a or b``
- short-circuiting logical OR operator (Python native operator);
scalar arguments only
* - ``1*i``, ``1*j``, ``1i``, ``1j``
- ``1j``
- complex numbers
* - ``eps``
- ``np.spacing(1)``
- Distance between 1 and the nearest floating point number.
* - ``ode45``
- ``scipy.integrate.solve_ivp(f)``
- integrate an ODE with Runge-Kutta 4,5
* - ``ode15s``
- ``scipy.integrate.solve_ivp(f, method='BDF')``
- integrate an ODE with BDF method
Linear Algebra Equivalents
--------------------------
.. list-table::
:header-rows: 1
* - MATLAB
- NumPy
- Notes
* - ``ndims(a)``
- ``ndim(a)`` or ``a.ndim``
- get the number of dimensions of an array
* - ``numel(a)``
- ``size(a)`` or ``a.size``
- get the number of elements of an array
* - ``size(a)``
- ``shape(a)`` or ``a.shape``
- get the "size" of the matrix
* - ``size(a,n)``
- ``a.shape[n-1]``
- get the number of elements of the n-th dimension of array ``a``. (Note
that MATLAB® uses 1 based indexing while Python uses 0 based indexing,
See note :ref:`INDEXING <numpy-for-matlab-users.notes>`)
* - ``[ 1 2 3; 4 5 6 ]``
- ``array([[1.,2.,3.], [4.,5.,6.]])``
- 2x3 matrix literal
* - ``[ a b; c d ]``
- ``block([[a,b], [c,d]])``
- construct a matrix from blocks ``a``, ``b``, ``c``, and ``d``
* - ``a(end)``
- ``a[-1]``
- access last element in the 1xn matrix ``a``
* - ``a(2,5)``
- ``a[1,4]``
- access element in second row, fifth column
* - ``a(2,:)``
- ``a[1]`` or ``a[1,:]``
- entire second row of ``a``
* - ``a(1:5,:)``
- ``a[0:5]`` or ``a[:5]`` or ``a[0:5,:]``
- the first five rows of ``a``
* - ``a(end-4:end,:)``
- ``a[-5:]``
- the last five rows of ``a``
* - ``a(1:3,5:9)``
- ``a[0:3][:,4:9]``
- rows one to three and columns five to nine of ``a``. This gives
read-only access.
* - ``a([2,4,5],[1,3])``
- ``a[ix_([1,3,4],[0,2])]``
- rows 2,4 and 5 and columns 1 and 3. This allows the matrix to be
modified, and doesn't require a regular slice.
* - ``a(3:2:21,:)``
- ``a[ 2:21:2,:]``
- every other row of ``a``, starting with the third and going to the
twenty-first
* - ``a(1:2:end,:)``
- ``a[ ::2,:]``
- every other row of ``a``, starting with the first
* - ``a(end:-1:1,:)`` or ``flipud(a)``
- ``a[ ::-1,:]``
- ``a`` with rows in reverse order
* - ``a([1:end 1],:)``
- ``a[r_[:len(a),0]]``
- ``a`` with copy of the first row appended to the end
* - ``a.'``
- ``a.transpose()`` or ``a.T``
- transpose of ``a``
* - ``a'``
- ``a.conj().transpose()`` or ``a.conj().T``
- conjugate transpose of ``a``
* - ``a * b``
- ``a @ b``
- matrix multiply
* - ``a .* b``
- ``a * b``
- element-wise multiply
* - ``a./b``
- ``a/b``
- element-wise divide
* - ``a.^3``
- ``a**3``
- element-wise exponentiation
* - ``(a>0.5)``
- ``(a>0.5)``
- matrix whose i,jth element is (a_ij > 0.5). The Matlab result is an
array of 0s and 1s. The NumPy result is an array of the boolean
values ``False`` and ``True``.
* - ``find(a>0.5)``
- ``nonzero(a>0.5)``
- find the indices where (``a`` > 0.5)
* - ``a(:,find(v>0.5))``
- ``a[:,nonzero(v>0.5)[0]]``
- extract the columms of ``a`` where vector v > 0.5
* - ``a(:,find(v>0.5))``
- ``a[:,v.T>0.5]``
- extract the columms of ``a`` where column vector v > 0.5
* - ``a(a<0.5)=0``
- ``a[a<0.5]=0``
- ``a`` with elements less than 0.5 zeroed out
* - ``a .* (a>0.5)``
- ``a * (a>0.5)``
- ``a`` with elements less than 0.5 zeroed out
* - ``a(:) = 3``
- ``a[:] = 3``
- set all values to the same scalar value
* - ``y=x``
- ``y = x.copy()``
- numpy assigns by reference
* - ``y=x(2,:)``
- ``y = x[1,:].copy()``
- numpy slices are by reference
* - ``y=x(:)``
- ``y = x.flatten()``
- turn array into vector (note that this forces a copy)
* - ``1:10``
- ``arange(1.,11.)`` or ``r_[1.:11.]`` or ``r_[1:10:10j]``
- create an increasing vector (see note :ref:`RANGES
<numpy-for-matlab-users.notes>`)
* - ``0:9``
- ``arange(10.)`` or ``r_[:10.]`` or ``r_[:9:10j]``
- create an increasing vector (see note :ref:`RANGES
<numpy-for-matlab-users.notes>`)
* - ``[1:10]'``
- ``arange(1.,11.)[:, newaxis]``
- create a column vector
* - ``zeros(3,4)``
- ``zeros((3,4))``
- 3x4 two-dimensional array full of 64-bit floating point zeros
* - ``zeros(3,4,5)``
- ``zeros((3,4,5))``
- 3x4x5 three-dimensional array full of 64-bit floating point zeros
* - ``ones(3,4)``
- ``ones((3,4))``
- 3x4 two-dimensional array full of 64-bit floating point ones
* - ``eye(3)``
- ``eye(3)``
- 3x3 identity matrix
* - ``diag(a)``
- ``diag(a)``
- vector of diagonal elements of ``a``
* - ``diag(a,0)``
- ``diag(a,0)``
- square diagonal matrix whose nonzero values are the elements of
``a``
* - ``rand(3,4)``
- ``random.rand(3,4)``
- random 3x4 matrix
* - ``linspace(1,3,4)``
- ``linspace(1,3,4)``
- 4 equally spaced samples between 1 and 3, inclusive
* - ``[x,y]=meshgrid(0:8,0:5)``
- ``mgrid[0:9.,0:6.]`` or ``meshgrid(r_[0:9.],r_[0:6.]``
- two 2D arrays: one of x values, the other of y values
* -
- ``ogrid[0:9.,0:6.]`` or ``ix_(r_[0:9.],r_[0:6.]``
- the best way to eval functions on a grid
* - ``[x,y]=meshgrid([1,2,4],[2,4,5])``
- ``meshgrid([1,2,4],[2,4,5])``
-
* -
- ``ix_([1,2,4],[2,4,5])``
- the best way to eval functions on a grid
* - ``repmat(a, m, n)``
- ``tile(a, (m, n))``
- create m by n copies of ``a``
* - ``[a b]``
- ``concatenate((a,b),1)`` or ``hstack((a,b))`` or
``column_stack((a,b))`` or ``c_[a,b]``
- concatenate columns of ``a`` and ``b``
* - ``[a; b]``
- ``concatenate((a,b))`` or ``vstack((a,b))`` or ``r_[a,b]``
- concatenate rows of ``a`` and ``b``
* - ``max(max(a))``
- ``a.max()``
- maximum element of ``a`` (with ndims(a)<=2 for matlab)
* - ``max(a)``
- ``a.max(0)``
- maximum element of each column of matrix ``a``
* - ``max(a,[],2)``
- ``a.max(1)``
- maximum element of each row of matrix ``a``
* - ``max(a,b)``
- ``maximum(a, b)``
- compares ``a`` and ``b`` element-wise, and returns the maximum value
from each pair
* - ``norm(v)``
- ``sqrt(v @ v)`` or ``np.linalg.norm(v)``
- L2 norm of vector ``v``
* - ``a & b``
- ``logical_and(a,b)``
- element-by-element AND operator (NumPy ufunc) :ref:`See note
LOGICOPS <numpy-for-matlab-users.notes>`
* - ``a | b``
- ``logical_or(a,b)``
- element-by-element OR operator (NumPy ufunc) :ref:`See note LOGICOPS
<numpy-for-matlab-users.notes>`
* - ``bitand(a,b)``
- ``a & b``
- bitwise AND operator (Python native and NumPy ufunc)
* - ``bitor(a,b)``
- ``a | b``
- bitwise OR operator (Python native and NumPy ufunc)
* - ``inv(a)``
- ``linalg.inv(a)``
- inverse of square matrix ``a``
* - ``pinv(a)``
- ``linalg.pinv(a)``
- pseudo-inverse of matrix ``a``
* - ``rank(a)``
- ``linalg.matrix_rank(a)``
- matrix rank of a 2D array / matrix ``a``
* - ``a\b``
- ``linalg.solve(a,b)`` if ``a`` is square; ``linalg.lstsq(a,b)``
otherwise
- solution of a x = b for x
* - ``b/a``
- Solve a.T x.T = b.T instead
- solution of x a = b for x
* - ``[U,S,V]=svd(a)``
- ``U, S, Vh = linalg.svd(a), V = Vh.T``
- singular value decomposition of ``a``
* - ``chol(a)``
- ``linalg.cholesky(a).T``
- cholesky factorization of a matrix (``chol(a)`` in matlab returns an
upper triangular matrix, but ``linalg.cholesky(a)`` returns a lower
triangular matrix)
* - ``[V,D]=eig(a)``
- ``D,V = linalg.eig(a)``
- eigenvalues and eigenvectors of ``a``
* - ``[V,D]=eig(a,b)``
- ``V,D = np.linalg.eig(a,b)``
- eigenvalues and eigenvectors of ``a``, ``b``
* - ``[V,D]=eigs(a,k)``
-
- find the ``k`` largest eigenvalues and eigenvectors of ``a``
* - ``[Q,R,P]=qr(a,0)``
- ``Q,R = scipy.linalg.qr(a)``
- QR decomposition
* - ``[L,U,P]=lu(a)``
- ``L,U = scipy.linalg.lu(a)`` or ``LU,P=scipy.linalg.lu_factor(a)``
- LU decomposition (note: P(Matlab) == transpose(P(numpy)) )
* - ``conjgrad``
- ``scipy.sparse.linalg.cg``
- Conjugate gradients solver
* - ``fft(a)``
- ``fft(a)``
- Fourier transform of ``a``
* - ``ifft(a)``
- ``ifft(a)``
- inverse Fourier transform of ``a``
* - ``sort(a)``
- ``sort(a)`` or ``a.sort()``
- sort the matrix
* - ``[b,I] = sortrows(a,i)``
- ``I = argsort(a[:,i]), b=a[I,:]``
- sort the rows of the matrix
* - ``regress(y,X)``
- ``linalg.lstsq(X,y)``
- multilinear regression
* - ``decimate(x, q)``
- ``scipy.signal.resample(x, len(x)/q)``
- downsample with low-pass filtering
* - ``unique(a)``
- ``unique(a)``
-
* - ``squeeze(a)``
- ``a.squeeze()``
-
.. _numpy-for-matlab-users.notes:
Notes
=====
\ **Submatrix**: Assignment to a submatrix can be done with lists of
indexes using the ``ix_`` command. E.g., for 2d array ``a``, one might
do: ``ind=[1,3]; a[np.ix_(ind,ind)]+=100``.
\ **HELP**: There is no direct equivalent of MATLAB's ``which`` command,
but the commands ``help`` and ``source`` will usually list the filename
where the function is located. Python also has an ``inspect`` module (do
``import inspect``) which provides a ``getfile`` that often works.
\ **INDEXING**: MATLAB® uses one based indexing, so the initial element
of a sequence has index 1. Python uses zero based indexing, so the
initial element of a sequence has index 0. Confusion and flamewars arise
because each has advantages and disadvantages. One based indexing is
consistent with common human language usage, where the "first" element
of a sequence has index 1. Zero based indexing `simplifies
indexing <https://groups.google.com/group/comp.lang.python/msg/1bf4d925dfbf368?q=g:thl3498076713d&hl=en>`__.
See also `a text by prof.dr. Edsger W.
Dijkstra <https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html>`__.
\ **RANGES**: In MATLAB®, ``0:5`` can be used as both a range literal
and a 'slice' index (inside parentheses); however, in Python, constructs
like ``0:5`` can *only* be used as a slice index (inside square
brackets). Thus the somewhat quirky ``r_`` object was created to allow
numpy to have a similarly terse range construction mechanism. Note that
``r_`` is not called like a function or a constructor, but rather
*indexed* using square brackets, which allows the use of Python's slice
syntax in the arguments.
\ **LOGICOPS**: & or \| in NumPy is bitwise AND/OR, while in Matlab &
and \| are logical AND/OR. The difference should be clear to anyone with
significant programming experience. The two can appear to work the same,
but there are important differences. If you would have used Matlab's &
or \| operators, you should use the NumPy ufuncs
logical\_and/logical\_or. The notable differences between Matlab's and
NumPy's & and \| operators are:
- Non-logical {0,1} inputs: NumPy's output is the bitwise AND of the
inputs. Matlab treats any non-zero value as 1 and returns the logical
AND. For example (3 & 4) in NumPy is 0, while in Matlab both 3 and 4
are considered logical true and (3 & 4) returns 1.
- Precedence: NumPy's & operator is higher precedence than logical
operators like < and >; Matlab's is the reverse.
If you know you have boolean arguments, you can get away with using
NumPy's bitwise operators, but be careful with parentheses, like this: z
= (x > 1) & (x < 2). The absence of NumPy operator forms of logical\_and
and logical\_or is an unfortunate consequence of Python's design.
**RESHAPE and LINEAR INDEXING**: Matlab always allows multi-dimensional
arrays to be accessed using scalar or linear indices, NumPy does not.
Linear indices are common in Matlab programs, e.g. find() on a matrix
returns them, whereas NumPy's find behaves differently. When converting
Matlab code it might be necessary to first reshape a matrix to a linear
sequence, perform some indexing operations and then reshape back. As
reshape (usually) produces views onto the same storage, it should be
possible to do this fairly efficiently. Note that the scan order used by
reshape in NumPy defaults to the 'C' order, whereas Matlab uses the
Fortran order. If you are simply converting to a linear sequence and
back this doesn't matter. But if you are converting reshapes from Matlab
code which relies on the scan order, then this Matlab code: z =
reshape(x,3,4); should become z = x.reshape(3,4,order='F').copy() in
NumPy.
Customizing Your Environment
============================
In MATLAB® the main tool available to you for customizing the
environment is to modify the search path with the locations of your
favorite functions. You can put such customizations into a startup
script that MATLAB will run on startup.
NumPy, or rather Python, has similar facilities.
- To modify your Python search path to include the locations of your
own modules, define the ``PYTHONPATH`` environment variable.
- To have a particular script file executed when the interactive Python
interpreter is started, define the ``PYTHONSTARTUP`` environment
variable to contain the name of your startup script.
Unlike MATLAB®, where anything on your path can be called immediately,
with Python you need to first do an 'import' statement to make functions
in a particular file accessible.
For example you might make a startup script that looks like this (Note:
this is just an example, not a statement of "best practices"):
::
# Make all numpy available via shorter 'num' prefix
import numpy as num
# Make all matlib functions accessible at the top level via M.func()
import numpy.matlib as M
# Make some matlib functions accessible directly at the top level via, e.g. rand(3,3)
from numpy.matlib import rand,zeros,ones,empty,eye
# Define a Hermitian function
def hermitian(A, **kwargs):
return num.transpose(A,**kwargs).conj()
# Make some shortcuts for transpose,hermitian:
# num.transpose(A) --> T(A)
# hermitian(A) --> H(A)
T = num.transpose
H = hermitian
Links
=====
See http://mathesaurus.sf.net/ for another MATLAB®/NumPy
cross-reference.
An extensive list of tools for scientific work with python can be
found in the `topical software page <https://scipy.org/topical-software.html>`__.
MATLAB® and SimuLink® are registered trademarks of The MathWorks.
|