I would like to implement a diagonal matrix apply function that is created by providing the diagonal d first, and then doing a bunch of matrix-vector multiplications with x. Of course I wouldn’t want to create an actual matrix because all that’s needed is a elementwise vector multiplication.
Now, some users are going to provide a diagonal d of shape (k,), some of shape (k,1). Also, x can have shapes (k,) and (k,1). I would like the apply() method to behave just like the * for numpy matrices in that the result has the same shape as the input x.
Hence the question: In Python/Numpy, is there a non-iffy way to elementwise-multiply two np.arrays x and y of shapes (k,) or (k,1) (in any combination) such that the resulting array has the shape of x?
I experimented a little with [:,None],
x = np.empty((4,1))
y = np.empty(4)
(x * y).shape # (4,4) -- nope
(y * y).shape # (4,) -- yes
(x * y[:,None]).shape # (4, 1) -- yes
(y * y[:,None]).shape # (4,4) -- nope
and I could certainly wrap my code in if len(x.shape)==...:, but that doesn’t feel very pythonic.
Suggestions?
Now that I understand your question, my suggestion would be simply to reshape. Calling
reshapereturns a view, so it doesn’t incur any big copying costs or anything like that. Simply reshape the arrays, multiply, and reshape again:Or more concisely, as you and rroowwllaanndd pointed out:
The substance of my previous suggestion remains below.
It’s worth noting that if you multiply a numpy array of shape
(1, 4)with an array of shape(4,)you get something close to what you want.This doesn’t have the shape of
a, but it does have the shape ofa.T. You could always callTon the result again. This will work on arrays of shape(5,)too, because the transpose operation on a 1-d array causes no change. So perhaps you could do this:But of course this causes the opposite problem if you pass an array of shape
(1, 5):So
transposed_multdoes the exact thing you asked for in your original post, but if you need any further flexibility, it won’t work as expected. And indeed, it seems you need additional flexibility.