0

I am trying to minimize sum((A-r*B).^2) in Matlab where A and B are matrices and r is the scalar I am manipulating. I tried the following code:

f = @(r) sum((A-r*B).^2);
Answer = fminbnd(f,lowrange,highrange);

But I get an error.

Jimmy Xiao
  • 156
  • 5
  • What is the error you're getting? – MrAzzaman Sep 29 '14 at 02:37
  • Operands to the || and && operators must be convertible to logical scalar values. Error in fminbnd (line314) - if ( (fu <= fw || (w == xf) ) – Jimmy Xiao Sep 29 '14 at 02:38
  • Can you give a small runnable example that shows this error. Using random 5x5 matrices for `A` and `B`, and minimising between 0 and 10, I got a different error because your objective function doesn't return a scalar. – David Sep 29 '14 at 04:25
  • @David - You are correct. It looks like the OP is trying to minimize the sum of squared differences, but with the input to `sum` as a matrix, this will return an array of row sums for each column. The OP needs to wrap this with another `sum` to get this to work as `fminbnd` is expecting a function that outputs a single value. Nice catch! – rayryeng Sep 29 '14 at 04:34

2 Answers2

2

If A and B are matrices, then sum((A - r*B).^2) will not give you a single value. This will give you an array of values. If the input to sum is a matrix, the output of sum will give you an array where each element is the sum along the rows for each column in your matrix.

The function you are specifying to fminbnd must evaluate to a single value. I'm assuming you want to determine the sum of squared differences in your function, and so you need to wrap your sum with another sum. As such, try this instead:

f = @(r) sum(sum((A-r*B).^2));
Answer = fminbnd(f,lowrange,highrange);

The function f will now find the difference between matrices A and B which is weighted by r, square these differences and then add up all of these differences together.

Try that and see if it works.

rayryeng
  • 102,964
  • 22
  • 184
  • 193
0

If you don't need to impose limits on the possible values of the optimized scalar r, then you should be able to solve this equation directly without searching for the minimum. If A and B are vectors, use:

    ropt=(B'*B)^(-1)*B'*A;

If A and B are arrays and you want to minimize the sum of squared residuals of all elements of the arrays then I believe the following will work (same formula, but convert A and B to vectors).

    ropt=(B(:)'*B(:))^(-1)*B(:)'*A(:);

Examples:

    b=[1;2;3]
    a=2*b;
    ropt=(b'*b)^(-1)*b'*a

returns ropt=2.0000, as desired

Similarly, for a matrix:

    b=magic(3);
    a=2*b;
    ropt=(b(:)'*b(:))^(-1)*b(:)'*a(:)

also returns ropt=2.0000. This should work fine even if there isn't a perfect solution, as there is in the examples above.

Brendan
  • 1
  • 1