1
votes

This is my goal, using Python Numpy:

I would like to create a (1000,1000) dimensional array/matrix of dot product values. That means each array/matrix entry is the dot product of vectors 1 through 1000. Constructing this is theoretically simple: one defines a (1,1000) dimensional matrix of vectors v1, v2, ..., v1000

import numpy as np  
vectorvalue = np.matrix([v1, v2, v3, ..., v1000])

and takes the dot product with the transpose, i.e.

matrix_of_dotproducts = np.tensordot(vectorvalue.T, vectorvalue)

And the shape of the array/matrix will be (1000, 1000). The (1,1) entry will be the dot product of vectors (v1,v1), the (1,2) entry will be the dot product of vectors (v1,v2), etc. In order to calculate the dot product with numpy for a three-dimensional vector, it's wise to use numpy.tensordot() instead of numpy.dot()

Here's my problem: I'm not beginning with an array of vector values. I'm beginning with three 1000 element arrays of each coordinate values, i.e. an array of x-coordinates, y-coordinates, and z-coordinates.

xvalues = np.array([x1, x2, x3, ..., x1000])
yvalues = np.array([y1, y2, y3, ..., y1000])
zvalues = np.array([z1, z2, z3, ..., z1000])

Is the easiest thing to do to construct a (3, 1000) numpy array/matrix and then take the tensor dot product for each pair?

v1  = np.array([x1,y1,z1])
v2 = np.array([x2,y2,z2]) 
...

I'm sure there's a more tractable and efficient way to do this...

PS: To be clear, I would like to take a 3D dot product. That is, for vectors

A = (a1, a2, a3) and B = (b1, b2, b3),

the dot product should be

dotproduct(A,B) = a1b1 + a2b2 + a3b3.

2

2 Answers

0
votes

IIUC, you can build the intermediate array as you suggested:

>>> arr = np.vstack([xvalues, yvalues, zvalues]).T
>>> out = arr.dot(arr.T)

Which seems to be what you want:

>>> out.shape
(1000, 1000)
>>> out[3,4]
1.193097281209083
>>> arr[3].dot(arr[4])
1.193097281209083
0
votes

So, you're not far off with your initial thought. There's very little overhead involved in concatenating the arrays, but if you're interested in doing in within numpy, there's a built-in set of functions, vstack, hstack, and dstack that should perform exactly as you wish. (Vertical, horizontal, and depth respectively)

I'll leave it up to you to determine which to you where, but here's an example shamelessly stolen from the docs to help get you started:

>>> a = np.array([1, 2, 3])
>>> b = np.array([2, 3, 4])
>>> np.vstack((a,b))
array([[1, 2, 3],
       [2, 3, 4]])

For reference: vstack docs, hstack docs, and dstack docs

If it feels a little over-the-top to have three separate functions here then you're right! That's why numpy also has the concatenate function. It's just a generalization of vstack, hstack, and dstack that takes an axis argument.

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6]])
>>> np.concatenate((a, b), axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])

Concatenate docs