4

At the moment, my code is written entirely using numpy arrays, np.array.

Define m as a np.array of 100 values, m.shape = (100,). There is also a multi-dimensional array, C.shape = (100,100).

The operation I would like to compute is

m^T * C * m 

where m^T should be of shape (1,100), m of shape (100,1), and C of shape (100,100).

I'm conflicted how to proceed. If I insist the data types must remain np.arrays, then I should probably you numpy.dot() or numpy.tensordot() and specify the axis. That would be something like

import numpy as np
result = np.dot(C, m)
final = np.dot(m.T, result)

though m.T is an array of the same shape as m. Also, that's doing two individual operations instead of one.

Otherwise, I should convert everything into np.matrix and proceed to use matrix multiplication there. The problem with this is I must convert all my np.arrays into np.matrix, do the operations, and then convert back to np.array.

What is the most efficient and intelligent thing to do?

EDIT:

Based on the answers so far, I think np.dot(m^T, np.dot(C, m)) is probably the best way forward.

ShanZhengYang
  • 16,511
  • 49
  • 132
  • 234
  • 1
    I would stick to arrays and use the (somewhat inconvenient) dot function for now, converting back and forth to matrix is annoying. It is likely that `np.matrix` will be deprecated or strongly discouraged several years from now, since Python 3.5 will now have a [dedicated matrix multiplication operator](https://www.python.org/dev/peps/pep-0465/). – Bas Swinckels Jun 23 '15 at 21:24
  • Given my dimensions, is it wiser to use `np.dot()` or `np.tensordot()`? I'm unsure whether one would need to specify the axis in this case. – ShanZhengYang Jun 23 '15 at 21:28
  • 1
    `tensordot` just reshapes the arrays and does `dot`. Matrix `*` probably does `dot` as well. All will do your calculation in 2 steps. `einsum` is another option, but with these small arrays I don't think it helps. Do some of your own timing tests to measure 'efficiency`. – hpaulj Jun 23 '15 at 22:40

1 Answers1

0

The main advantage of working with matrices is that the *symbol performs a matrix multiplication, whereas it performs an element-wise multiplications with arrays. With arrays you need to use dot. See: Link What are the differences between numpy arrays and matrices? Which one should I use?

If m is a one dimensional array, you don't need to transpose anything, because for 1D arrays, transpose doesn't change anything:

In [28]: m.T.shape, m.shape
Out[28]: ((3,), (3,))
In [29]: m.dot(C)
Out[29]: array([15, 18, 21])

In [30]: C.dot(m)
Out[30]: array([ 5, 14, 23])

This is different if you add another dimension to m:

In [31]: mm = m[:, np.newaxis]

In [32]: mm.dot(C)
--------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-32-28253c9b8898> in <module>()
----> 1 mm.dot(C)

ValueError: objects are not aligned

In [33]: (mm.T).dot(C)
Out[33]: array([[15, 18, 21]])

In [34]: C.dot(mm)
Out[34]: 
array([[ 5],
       [14],
       [23]])
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Ramon Crehuet
  • 3,679
  • 1
  • 22
  • 37