I am working with some matlab code I inhereted from another person, I dont understand the meaning of the line q =[q; qi']. I feel like i should be able to just remove it, so that q = distribuc...
function [ q ] = ObtainHistogramForEachTarget( state, numberOfTargets, image, q )
for i=1 : numberOfTargets
qi = distribucion_color_bin_RGB2(state(i).xPosition,state(i).yPosition,state(i).size,image,2);
q = [q; qi'];
end
end
Can anyone explain this to me?
MATLAB has several built-in functions to manipulate matrices. The special character, ', for prime denotes the transpose of a matrix.
The statement A = [ 1 2 3;4 5 6;7 8 9]' produces the matrix
A =
1 4 7
2 5 8
3 6 9
hope this helps
From Matlab's help
help ctranspose
' Complex conjugate transpose.
X' is the complex conjugate transpose of X.
B = ctranspose(A) is called for the syntax A' (complex conjugate
transpose) when A is an object.
The [X ; Y] syntax concatenates two matrices vertically. So that line is adding the just-computed results to the already computed q. If you simply reassigned q, you would be discarding all the computations the function had already done each time through the loop.
The forward apostrophe ' does a complex conjugate and transposes a matrix. I would guess that distribucion_color_bin_RGB2 probably returns a real-valued column vector, and the author wanted to flip it to horizontal before appending it to the results matrix.
As #ja72 pointed out, it's better style to use .' (just transpose) by default and ' only when you actually mean a complex conjugate, even if you expect your data to be real.
usually A' is the transpose of matrix A, but it is conjugate transpose. it works for real matrix, doesn't work for complex matrix
transpose(A) is the real transpose function, both work for R matrix and C matrix.
I usually use A', it's easy, but I changed my habit until I face bug in FFT transformation
I came across the same problem and tested it using octave(matlab in ubuntu), and found that to a just complex number a, a' means its conjugate.
octave:2> a = 1 + 1j
a = 1 + 1i
octave:3> a'
ans = 1 - 1i
Besides, to a complex matrix A:
octave:6> A = [1 + 2j 1 - 2j ; 2 - 1j 2 + 1j]
A =
1 + 2i 1 - 2i
2 - 1i 2 + 1i
octave:7> A'
ans =
1 - 2i 2 + 1i
1 + 2i 2 - 1i
Related
The code (written in Octave) is:
x=1:2:5;
y=1:1:3;
z=1:0.1:1.2;
f=[x+y+z,x.^2+z;sin(x.*y.*z),cos(x)];
h=x(2)-x(1);
xFor=x(1:end-1);
dffor=(f(2:end)-f(1:end-1))/h;
f(2)
dffor
The output I get is
Hello World
ans = 0.84147
dffor = -1.07926 2.62926 -2.89423 4.44423 4.77985 -5.54500 13.59500 -12.95817
I do not understand some of the code. What does f(2) evaluate?
I actually want to get the numerical derivative of the matrix with respect to x. I thought this was the method of forward differences. Also, why am I getting a [1x11] matrix as the output for dffor, which is supposed to be the numerical differentiation matrix?
first, f is a 2D matrix in your code (size [2,6]) and I assume you meant to have a vector (size [1,12]).
dffor is indeed the forward diff. and it has 11 elements (rather than 12 as f) because it has the differences between each consequent pair of f: each element is used twice except for the first and last: (10*2 + 1 + 1)/2 = 11.
f(2) is just the second element of f which equals x(2) + y(2) + z(2)
I have a column vector A. When A is a scalar I can use the colon operator to generate a vector like so
B = A-m:n:A+p
However, what I want to do is different. I want the result B to look like so,
[A-m, A-m+1 ... A ... , A+n-1, A+n]
I know I can accomplish this by using repmat on -m:n:p followed with a bsxfun added with the original A matrix.
Is there a more direct method?
If you just want to copy a handful instances of column vector v, you can always use
B = [v, v, v, ... v];
Or for row vector
B = [v ; v ; v ; ... v];
One easy vectorized way is this:
NewMatrix = diag(A)*ones(length(A),m+n+1) + ones(length(A),m+n+1)*diag(-m:1:n)
not a one-liner...
>> a=[1;2];
>> r=3:2:10;
>> repmat(a,1,size(r,2))+repmat(r,size(a,1),1)
ans =
4 6 8 10
5 7 9 11
In an attempt to speed up for loops (or eliminate all together), I've been trying to pass matrices into functions. I have to use sine and cosine as well. However, when I attempt to find the integral of a matrix where the elements are composed of sines and cosines, it doesn't work and I can't seem to find a way to make it do so.
I have a matrix SI that is composed of sines and cosines with respect to a variable that I have defined using the Symbolic Math Toolbox. As such, it would actually be even better if I could just pass the SI matrix and receive a matrix of values that is the integral of the sine/cosine function at every location in this matrix. I would essentially get a square matrix back. I am not sure if I phrased that very well, but I have the following code below that I have started with.
I = [1 2; 3 4];
J = [5 6; 7 8];
syms o;
j = o*J;
SI = sin(I + j);
%SI(1,1) = sin(5*o + 1)
integral(#(o) o.*SI(1,1), 0,1);
Ideally, I would want to solve integral(#(o) o*SI,0,1) and get a matrix of values. What should I do here?
Given that A, B and C are all N x N matrices, for the moment, let's assume they're all 2 x 2 matrices to make the example I'm illustrating more succinct to understand. Let's also define o as a mathematical symbol based on your comments in your question above.
syms o;
A = [1 2; 3 4];
B = [5 6; 7 8];
C = [9 10; 11 12];
Let's also define your function f according to your comments:
f = o*sin(A + o*B + C)
We thus get:
f =
[ o*sin(5*o + 10), o*sin(6*o + 12)]
[ o*sin(7*o + 14), o*sin(8*o + 16)]
Remember, for each element in f, we take the corresponding elements in A, B and C and add them together. As such, for the first row and first column of each matrix, we have 1, 5 and 9. As such, A + o*B + C for the first row, first column equates to: 1 + 5*o + 9 = 5*o + 10.
Now if you want to integrate, just use the int command. This will find the exact integral, provided that the integral can be solvable in closed form. int also can handle matrices so it will integrate each element in the matrix. You can call it like so:
out = int(f,a,b);
This will integrate f for each element from the lower bound a to the upper bound b. As such, supposing our limits were from 0 to 1 as you said. Therefore:
out = int(f,0,1);
We thus get:
out =
[ sin(15)/25 - sin(10)/25 - cos(15)/5, sin(18)/36 - sin(12)/36 - cos(18)/6]
[ sin(21)/49 - sin(14)/49 - cos(21)/7, sin(24)/64 - sin(16)/64 - cos(24)/8]
Bear in mind that out is defined in the symbolic math toolbox. If you want the actual numerical values, you need to cast the answer to double. Therefore:
finalOut = double(out);
We thus get:
finalOut =
0.1997 -0.1160
0.0751 -0.0627
Obviously, this can generalize for any size M x N matrices, so long as they all share the same dimensions.
Caveat
sin, cos, tan and the other related functions have their units in radians. If you wish for the degrees equivalent, append a d at the end of the function (i.e. sind, cosd, tand, etc.)
I believe this is the answer you're after. Good luck!
This question already has an answer here:
effective way of transformation from 2D to 1D vector
(1 answer)
Closed 9 years ago.
I would like to use the (:) operator and the transpose at the same time. Is this possible? Basically I would like to do something like
output = A'(:)
except that this does not work. Does anyone know a workaround?
Thanks!
Immo
The : operator in this case is shorthand for reshaping the matrix into a vector. You can work around the limitation of where you use the operator by using the reshape function explicitly:
octave> A = [1 2;3 4]
A =
1 2
3 4
octave> B=A'
B =
1 3
2 4
octave> C=B(:)
C =
1
2
3
4
octave> D=reshape(A',[],1) #% vectorize transpose in one line
D =
1
2
3
4
Try with:
output = reshape( A.', numel(A), 1);
>> A = rand(4,3);
>> output = reshape( A.', numel(A), 1);
A =
0.447213 0.046896 0.679087
0.903294 0.768745 0.651481
0.701071 0.122534 0.611390
0.535844 0.478595 0.772810
output =
0.447213
0.046896
0.679087
0.903294
0.768745
0.651481
0.701071
0.122534
0.611390
0.535844
0.478595
0.772810
Beware that reshape reads the matrices accessing along columns so you may not need to transpose the matrix A.
Also, remember that the operator ' is the hermitian operator, namely, conjugated of the transposed, whereas .' is simply transposition, which you could also get by transpose(A).
You may want to do everything in a single line without re-typing all every time. One solution is creating a function handles as boop:
>> boop = #(x) reshape( transpose(x), numel(x), 1)
>> output = boop(A)
output =
0.447213
0.046896
0.679087
0.903294
0.768745
0.651481
0.701071
0.122534
0.611390
0.535844
0.478595
0.772810
I'm desperately trying to avoid a for loop in Matlab, but I cannot figure out how to do it. Here's the situation:
I have two m x n matrices A and B and two vectors v and w of length d. I want to outer multiply A and v so that I get an m x n x d matrix where the (i,j,k) entry is A_(i,j) * v_k, and similarly for B and w.
Afterward, I want to add the resulting m x n x d matrices, and then take the mean along the last dimension to get back an m x n matrix.
I'm pretty sure I could handle the latter part, but the first part has me completely stuck. I tried using bsxfun to no avail. Anyone know an efficient way to do this? Thanks very much!
EDIT: This revision comes after the three great answers below. gnovice has the best answer to the question I asked without a doubt. However,the question that I meant to ask involves squaring each entry before taking the mean. I forgot to mention this part originally. Given this annoyance, both of the other answers work well, but the clever trick of doing algebra before coding doesn't help this time. Thanks for the help, everyone!
EDIT:
Even though the problem in the question has been updated, an algebraic approach can still be used to simplify matters. You still don't have to bother with 3-D matrices. Your result is just going to be this:
output = mean(v.^2).*A.^2 + 2.*mean(v.*w).*A.*B + mean(w.^2).*B.^2;
If your matrices and vectors are large, this solution will give you much better performance due to the reduced amount of memory required as compared to solutions using BSXFUN or REPMAT.
Explanation:
Assuming M is the m-by-n-by-d matrix that you get as a result before taking the mean along the third dimension, this is what a span along the third dimension will contain:
M(i,j,:) = A(i,j).*v + B(i,j).*w;
In other words, the vector v scaled by A(i,j) plus the vector w scaled by B(i,j). And this is what you get when you apply an element-wise squaring:
M(i,j,:).^2 = (A(i,j).*v + B(i,j).*w).^2;
= (A(i,j).*v).^2 + ...
2.*A(i,j).*B(i,j).*v.*w + ...
(B(i,j).*w).^2;
Now, when you take the mean across the third dimension, the result for each element output(i,j) will be the following:
output(i,j) = mean(M(i,j,:).^2);
= mean((A(i,j).*v).^2 + ...
2.*A(i,j).*B(i,j).*v.*w + ...
(B(i,j).*w).^2);
= sum((A(i,j).*v).^2 + ...
2.*A(i,j).*B(i,j).*v.*w + ...
(B(i,j).*w).^2)/d;
= sum((A(i,j).*v).^2)/d + ...
sum(2.*A(i,j).*B(i,j).*v.*w)/d + ...
sum((B(i,j).*w).^2)/d;
= A(i,j).^2.*mean(v.^2) + ...
2.*A(i,j).*B(i,j).*mean(v.*w) + ...
B(i,j).^2.*mean(w.^2);
Try reshaping the vectors v and w to be 1 x 1 x d:
mean (bsxfun(#times, A, reshape(v, 1, 1, [])) ...
+ bsxfun(#times, B, reshape(w, 1, 1, [])), 3)
Here I am using [] in the argument to reshape to tell it to fill that dimension in based on the product of all the other dimensions and the total number of elements in the vector.
Use repmat to tile the matrix in the third dimension.
A =
1 2 3
4 5 6
>> repmat(A, [1 1 10])
ans(:,:,1) =
1 2 3
4 5 6
ans(:,:,2) =
1 2 3
4 5 6
etc.
You still don't have to resort to any explicit loops or indirect looping using bsxfun et al. for your updated requirements. You can achieve what you want by a simple vectorized solution as follows
output = reshape(mean((v(:)*A(:)'+w(:)*B(:)').^2),size(A));
Since OP only says that v and w are vectors of length d, the above solution should work for both row and column vectors. If they are known to be column vectors, v(:) can be replaced by v and likewise for w.
You can check if this matches Lambdageek's answer (modified to square the terms) as follows
outputLG = mean ((bsxfun(#times, A, reshape(v, 1, 1, [])) ...
+ bsxfun(#times, B, reshape(w, 1, 1, []))).^2, 3);
isequal(output,outputLG)
ans =
1