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 :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.