MATLAB: fmincon with three-dimensional data - matlab

I want to estimate three parameters while minimizing the least squares quadratic error with the function fmincon in MATLAB. My objective function looks like:
f = #(a,b,c) sum(sum(sum((M - a - b - c).^2)));
where M is a 3D array with dimensions 20x7x16 and the estimated parameters a, b, c are vectors with dimensions 20x1, 7x1 and 16x1 respectively. In order to estimate it I 'make' them 3D as well by repeating the vector a into the array 20x7x16 and I do the same for b and c. I need the sum of the elements in vector a and b to be 1 as linear constraints. My problems are two:
How should I specify the linear constraints when Aeq is a 2D matrix and beq a vector?
How can I set the starting points for a,b,c so that MATLAB knows that the estimates of them are vectors repeated in this 3D array?
I wanted to unfold the 3D array M into 2D matrix and adjust the the parameters a,b,c but the problem with starting points is still there since I must define them as a vector and not as a matrix.
I would very appreciate your ideas and suggestions. Probably I'm thinking to complicated and there's another way how to do it.
Thank you in advance.

DO NOT REPLICATE a b and c! use bsxfun instead
f = #(a,b,c) sum( reshape( bsxfun( #minus, bsxfun( #minus, bsxfun(#minus, M, a), b' ), permute( c, [2 3 1] ) ), [], 1 ) )
Now your parameters are vecotrs and not replicates of vectors. I believe this will solve all your other problems as well.

Related

What does the operation A'\B' do if A and B are both row vectors of the same size?

[1 2 1]'\[1 2 3]' This is a numerical example. This example gives an answer of 1.333
From the documentation:
x = A\B
If A is a rectangular m-by-n matrix with m ~= n, and B is a matrix with m rows, then A\B returns a least-squares solution to the system of equations A*x= B.
Furthermore the ' compute the conjugate transposed of a matrix. In your case you have two real matrices so you just get the transposed each time.

Multiply coefficients into a matrix after meshgrid-ed in matlab

I have a matrix of A=[60x60],and two coefficients a,b. Since matrix A was moved by a,b, how to multiply the coefficients into matrix A so that I could obtain A_moved? Any function to do it?
Here's part of matlab code implemented:
A=rand(60); %where it's in 2D, A(k1,k2)
a=0.5; b=0.8;
[m, n]=size(A);
[M,N] = meshgrid(1:m,1:n);
X = [M(:), N(:)];
A_moved=A(:)(X)*[a b] %I know this is not valid but you get the idea
In another word A_moved is calculated by A_moved=a*k1+b*k2.
This line of code A_moved=A(:)(X)*[a b] is to represent my idea that a,b multiply back into the original A because X represent correspond coordinates of k1 and k2. The first column represent k1, and second column represent k2. Thus it become A_moved=a*k1+b*k2. But this couldn't get me anyway.
In the end A-moved is a 60x60 matrix which have been multiplied by coefficients a,b correspondingly. To make it clearer,A is the phase of image. a,b moved it phase.
Appreciate any help. Thank you!
Reference paper: Here
EDIT:
As suggested by Noel for better understanding.
A=[2 3;5 7], a=1.5 and b=2.5.
Since A is approximated as a*k1+b*k2
Thus,
A_moved=[1.5*k1_1+2.5k2_1 1.5*k1_2+2.5k2_2; 1.5*k1_2+2.5k2_1 1.5*k1_2+2.5k2_2];
where k1 and k2, If I'm understood correctly is the coordinates of the original A matrix, as defined in X above.
On the chat we found that your problem was matrix algebra related
What you want to obtain in A_moved is the x coordinate multiplied by a contant a plus the y coordinate multiplied by a constant b.
You already have this coordinates in M and N, so you can obtain A_moved as
A_moved = (a*M) + (b*N);
And it will retain same shape as A

Multiply two matrices in Matlab to obtain 3-dimensional matrix

I have two sparse matrices in Matlab, A and B,
and I want to compute a three-dimensional matrix C such that
C(i,j,k) = A(i,j) * B(j,k)
can I do this without a loop?
(Side question: Is there a name for this operation?)
Edit:
Seems my question has already been asked (just for full matrices):
Create a 3-dim matrix from two 2-dim matrices
For full matrices:
You can do it using bsxfun and shiftdim:
C = bsxfun(#times, A, shiftdim(B,-1))
Explanation: Let A be of size M x N and B of size N x P. Applying shiftdim(B,-1) gives a 1 x N x P array. bsxfun implicitly replicates A along the third dimension and shiftdim(B,-1) along the first to compute the desired element-wise product.
Another possibility, usually less efficient than bsxfun, is to repeat the arrays explicity along the desired dimensions, using repmat:
C = repmat(A, [1 1 size(B,2)]) .* repmat(shiftdim(B,-1), [size(A,1) 1 1])
For sparse matrices:
The result cannot be sparse, as sparse ND-arrays are not supported.. But you can do the computations with sparse A and B using linear indexing:
ind1 = repmat(1:numel(A),1,size(B,2));
ind2 = repmat(1:numel(B),size(A,1),1);
ind2 = ind2(:).';
C = NaN([size(A,1),size(A,2),size(B,2)]); %// preallocate with appropriate shape
C(:) = full(A(ind1).*B(ind2)); %// need to use full if C is to be 3D
Answer to your side question: the name for this operation is a hash join.

Turning a (4D matrix * 1D vector) operation into independent (3D matrix * 0D scalar) operations without loops

Is there any way to vectorize the following:
for i = 1:6
te = k(:,:,:,i).*(c(i));
end
I'm trying to multiply a 4D matrix, k, by a vector, c, by breaking it up into independent (3D matrix * scalar) operations. I already have two other unavoidable for loops within a while loop in this function file, and am trying my best to avoid loops.
Any insight on this will be much appreciated!
-SC
You can do this using MTIMESX - a Fast matrix multiplication tool with multidimensional support by James Tursa, found in Matlab's file exchange.
It is as simple as:
C = mtimesx(A,B)
performs the calculation C = A * B
Unless I'm missing something, this is a case for bsxfun:
te=bsxfun(#times, k, permute(c,[3 4 1 2])); % c is a row vector
Or
te=bsxfun(#times, k, permute(c,[3 4 2 1])); % c is a column vector
This is assuming that the 4th dimension of k has the same size as c. If not, then you can use submatrix indexing:
te=bsxfun(#times, k(:,:,:,1:length(c)), permute(c,[3 4 2 1])); % c is a column vector

Linear equations with multidimensional matrices [Modified]

There is a system of 3 linear equations composing of matrices which are represented by RGB image. Say
A = A1*x1 + A2*x2 + A3*x3 ......(Eq 1)
B= A1*x4 + A2*x5 + A3*x6 ........(Eq 2)
C= A1*x7 + A2*x8 + A3*x9 ........(Eq 3)
each are of equal dimension say 3D. I performed the following
A11=rgb2gray(A1);
x11=rgb2gray(x1);
A11 =double(A1) ; x11 = double(x11); b = A1*x1;
opts.UT = true; opts.TRANSA = false;
y1 = linsolve(x1,b,opts);
imshow(y1);
% The objective is to obtain A1,A2,A3
On doing this, following issues have surfaced:
1. Error
The output y1 is not the same as A1, which should have been. Why is it so? Please help
The R,G and B spaces are orthogonal. So you can solve each of those sets independently. The problem here is that mtimes, which is your matrix multiplication operator, doesn't accept 3D inputs.
To solve this, you can loop through each of R, G and B and use linsolve for each of the resulting 2D matrices. Normally, I wouldn't recommend loops for anything in MATLAB, but here, there won't be any discernable overhead as there are only 3 iterations in the loop.
Your answer will not be any different from what it would be if you were to solve them all in one go (if that were possible), because the three spaces are independent.
EDIT
The way you've written your equations, the xi's form the coefficient matrix and Ai's are the unknowns. The system of equations can be written compactly as XY=Z, where X is a 3D matrix composed of the coefficients, xi for each color space,RGB; Y is a 2D matrix, with a vector [A1, A2, A3]' in each color space, and Z is also a 2D matrix with vectors [A, B, C]' in each color space.
Assuming that the colorspace is the last dimension, you can try
[xPixels,yPixels,colorSpace]=size(X);
Y=zeros(yPixels,colorspace);
opts.UT=true; opts.TRANSA=false;
for i=1:colorspace
Y(:,i)=linsolve(X(:,:,i),Z(:,i),opts);
end
You'll have to setup the matrices X, Y and Z according to your problem. It is helpful to keep the looped dimension (in this case, colorspace) as the outermost dimension, as otherwise, you'll have to use squeeze to remove the singleton dimensions.