1

I try to use svd in my work which will return the vector as below.

A=rand(10,5);
b=rand(10,5,100);
[U, S , V]=svd(A);

What I'm trying to do is to multiply each slice of b with U. With one specific slice, this operation is valid:

c=U'*b(:,:,1);

However when I try to use a vectorized method as below, it return array dimensions mismatch error.

Utran=U.';
c = cellfun(@(x) x.*b,num2cell(Utran,[1 2]),'UniformOutput',false);

I could probably use loop for the first method, but it's not efficient if I have a large matrix. Any idea what's my mistake here?

Gregor Isack
  • 1,111
  • 12
  • 25
  • This can be solved with a simple for loop. Why not? – Ander Biguri Jan 30 '18 at 11:18
  • Well, that 100 slices is just an example, in real world I'm dealing with more than 50K slices. So for future proof, I might want to start vectorize my code :) – Gregor Isack Jan 30 '18 at 11:25
  • 2
    Vectorization != fast. MATLAB's JIT compiler is very good and often for loops are equally fast. – Ander Biguri Jan 30 '18 at 11:26
  • Okay, but I can't compare and make a decision since the vectorized code doesn't work – Gregor Isack Jan 30 '18 at 11:28
  • Especially `cellfun` in many times is slower than for loop... – Adiel Jan 30 '18 at 11:29
  • 1
    @GregorIsack "Premature optimization is the root of all evil"-Donald Knuth. Why optimize a piece of code that you don't know if its critical for your application? – Ander Biguri Jan 30 '18 at 11:29
  • But the function work if you omit the `[1 2]`. Why in the specific slice you did matrix multiplication, and in the cellfun you did element wise multiplication? – Adiel Jan 30 '18 at 11:30
  • @AnderBiguri oh well, make sense haha. – Gregor Isack Jan 30 '18 at 11:31
  • Loops are OK. Vectorize your code if it makes it shorter and more readable. Readable code is the code that is worth most. Optimize your code only if it's a bottleneck. Use `profile` before you optimize anything. And include the non-optimized code if the optimization harms readability. – Cris Luengo Jan 30 '18 at 14:22
  • @CrisLuengo I'm using the 2017b, the latest I presume. Doing that will return an error of "arguments must be 2-D, or at least one argument must be scalar." and `U'.*b` will return mismatch. EDIT: guess I'll stick with loops for now. – Gregor Isack Jan 30 '18 at 14:23
  • BTW: Don't forget to pre-allocate your output array before that loop that you're writing! :) – Cris Luengo Jan 30 '18 at 14:25

1 Answers1

0

The following is a vectorized solution.

Not sure if it's faster than using loops; and even if it is, note that it uses more memorry for intermediate computations:

result = permute(sum(permute(conj(U), [1 3 4 2]).*b), [4 2 3 1]);
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147