4

I'm trying the following:

Given a matrix A (x, y ,3) and another matrix B (3, 3), I would like to return a (x, y, 3) matrix in which the 3rd dimension of A is multiplied by the values of B (similar when an RGB image is transformed into gray, only that those "RGB" values are multiplied by a matrix and not scalars)...

Here's what I've tried:

np.multiply(B, A)
np.einsum('ijk,jl->ilk', B, A)
np.einsum('ijk,jl->ilk', A, B)

All of them failed with dimensions not aligned.

What am I missing?

4
  • Which axis of B is sum-reduced? Commented Oct 25, 2017 at 10:47
  • I'm trying to do B * A, where A's 3rd axis is changed Commented Oct 25, 2017 at 10:51
  • So, last axis of B is reduced? Commented Oct 25, 2017 at 10:55
  • Yes............ Commented Oct 25, 2017 at 10:58

2 Answers 2

5

You can use np.tensordot -

np.tensordot(A,B,axes=((2),(1)))

Related post to understand tensordot.

einsum equivalent would be -

np.einsum('ijk,lk->ijl', A, B)

We can also use A.dot(B.T), but that would be looping under the hoods. So, might not be the most preferred one, but it's a compact solution,

Sign up to request clarification or add additional context in comments.

15 Comments

I got no error with these functions! :)) but for some reason I get wrong values...I mean when I try to display the image with the new values I get an error
@DanielY Maybe you were meant to sum-reduce the first axis of B? Then, use : np.tensordot(A,B,axes=((2),(0)))?
@DanielY Also, make sure you are not overflowing and also using uint8 dtype for image displaying.
I get many negative values...I think my B is wrong or upside down...I'll check that. Thanks
When trying tensordot() function I get a result matrix of (3, x, y) instead of (x, y, 3)
|
3

Sorry for the confusion, I think you can do something like this, using simple numpy methods:

First you can reshape A in a way that its fibers (or depth vectors A[:,:,i]) will be placed as columns in matrix C:

C = A.reshape(x*y,3).T

Then using a simple matrix multiplication you can do:

D = numpy.dot(B,C)

Finally bring the result back to the original dimensions:

D.T.reshape([x,y,3])

6 Comments

I'm trying to do B * A, I've tried what you suggested and got operands could not be broadcast together with shapes (3,3) (x, y, 3)
Just told you above, force B to have shape (3,3,1)!
Sorry, I meant error operands could not be broadcast together with shapes (3,3, 1) (x, y, 3)
Ok, I think I got what you mean, but x or y must have dimension 3 isn't it?
Your updated comment did get me the expected result, but so did @Divakar's answer, so thanks a lot but I got what I need :)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.