Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross product of a vector in NumPy

Tags:

python

numpy

Consider the following vectors (essentially2x1 matrices):

a = sc.array([[1], [2], [3]])
>>> a
[[1]
 [2]
 [3]]

b = sc.array([[4], [5], [6]])
>>> b
[[4]
 [5]
 [6]]

The cross product of these vectors can be calculated using numpy.cross(). Why does this not work:

import numpy as np 

np.cross(a, b)
ValueError: incompatible dimensions for cross product
(dimension must be 2 or 3)

but this does?:

np.cross(a.T, b.T)
[[-3  6 -3]]
like image 769
Ingo Avatar asked Feb 12 '12 17:02

Ingo


2 Answers

To compute the cross product using numpy.cross, the dimension (length) of the array dimension which defines the two vectors must either by two or three. To quote the documentation:

If a and b are arrays of vectors, the vectors are defined by the last axis of a and b by default, and these axes can have dimensions 2 or 3.

Note that the last axis is the default. In your example:

In [17]: a = np.array([[1], [2], [3]])

In [18]: b = np.array([[4], [5], [6]])

In [19]: print a.shape,b.shape
(3, 1) (3, 1)

the last axis is only of length 1, so the cross product is not defined. However, if you use the transpose, the length along the last axis is 3, so it is valid. You could also do:

In [20]: np.cross(a,b,axis=0)
Out[20]: 
array([[-3],
       [ 6],
       [-3]])

which tells cross that the vectors are defined along the first axis, rather than the last axis.

like image 127
talonmies Avatar answered Sep 23 '22 07:09

talonmies


In numpy we often use 1d arrays to represent vectors, and we treat it as either a row vector or a column vector depending on the context, for example:

In [13]: a = np.array([1, 2, 3])

In [15]: b = np.array([4, 5, 6])

In [16]: np.cross(a, b)
Out[16]: array([-3,  6, -3])

In [17]: np.dot(a, b)
Out[17]: 32

You can store vectors as 2d arrays, this is most useful when you have a collection of vectors you want to treat in a similar way. For example if I want to cross 4 vectors in a with 4 vectors in b. By default numpy assumes the vectors are along the last dimensions but you can use the axisa and axisb arguments to explicitly specify that the vectors are along the first dimension.

In [26]: a = np.random.random((3, 4))

In [27]: b = np.random.random((3, 4))

In [28]: np.cross(a, b, axisa=0, axisb=0)
Out[28]: 
array([[-0.34780508,  0.54583745, -0.25644455],
       [ 0.03892861,  0.18446659, -0.36877085],
       [ 0.36736545,  0.13549752, -0.32647531],
       [-0.46253185,  0.56148668, -0.10056834]])
like image 44
Bi Rico Avatar answered Sep 24 '22 07:09

Bi Rico