Confuse about Hist default function in matlab - matlab

For example i have an image matrix that looks like this one:
1 2 3
1 5 6
1 5 3
Assume that my intensity goes from 1 to 6, so I need to produce something like an array:
1 : 3
2 : 1
3 : 2
4 : 0
5 : 2
6 : 1
I tried using hist function of matlab but it produced something looks really weried to me.
Can anybosy help me on that? Thank you very much

The key here is to linearize the image matrix using the colon operator, like in hist(a(:)). Calling hist(a) when a is a matrix will compute the histogram of each column.

I suspect that you probably haven't specified the correct histogram bins for hist (by default it creates 10 equally spaced bins). If you're interested in a simple histogram count, consider using histc:
vals = 1:max(A(:));
count = histc(A(:), vals);
where A is your image matrix. vals is the first column in your desired output array, and count is the the second.

Related

Vectorizing cell find and summing in Matlab

Would someone please show me how I can go about changing this code from an iterated to a vectorized implementation to speed up performance in Matlab? It takes approximately 8 seconds per i for i=1:20 on my machine currently.
classEachWordCount = zeros(nwords_train, nClasses);
for i=1:nClasses % (20 classes)
for j=1:nwords_train % (53975 words)
classEachWordCount(j,i) = sum(groupedXtrain{i}(groupedXtrain{i}(:,2)==j,3));
end
end
If context is helpful basically groupedXtrain is a cell of 20 matrices which represent different classes, where each class matrix has 3 columns: document#,word#,wordcount, and unequal numbers of rows (tens of thousands). I'm trying to figure out the count total of each word, for each class. So classEachWordCount should be a matrix of size 53975x20 where each row represents a different word and each column a different label. There's got to be a built-in function to assist in something like this, right?
for example groupedXtrain{1} might start off like:
doc#,word#,wordcount
1 1 3
1 2 1
1 4 3
1 5 1
1 8 2
2 2 1
2 5 4
2 6 2
As is mentioned in the comments, you can use accumarray to sum up the values in the third column for each unique value in the second column for each class
results = zeros(nwords_train, numel(groupedXtrain));
for k = 1:numel(groupedXtrain)
results(:,k) = accumarray(groupedXtrain{k}(:,2), groupedXtrain{k}(:,3), ...
[nwords_train 1], #sum);
end

matlab how to get min value and its index in a matrix

I have a matrix let's say like this
A=[1 3 6 2 0 4
6 8 9 5 1 4
7 2 7 8 9 2]
I want to get the minimal value where the row is given (r) and the column is in an interval ([c.. c+x]). Also I want the index (number of column of it).
I can get the min with
MinVal=min(A(r,c:c+x))
Example
MinVal=min(A(2,3:3+2))
will give me
% MinVal= 1
The index of this MinVal is I= 5 since it is in the 5th column (I know already the row and don't need it).
But how to get this index ?
If I do like this, I don't get what I want
[MinVal,I]=min(A(r,c:c+x))
It might not be the shortest code, but an easy to understand possibility:
Create a mask indicating which variables you use in your submatrix:
M=false(size(A));
M(r,c:c+x)=true; %use the same indexing operation
Convert to linear indices:
M=find(M);
And use it to translate I to indices in the full matrix:
M(I)

Merge two matrix and find the maximum of its attributes

I've two matrix a and b and I'd like to combine the rows in a way that in the first row I got no duplicate value and in the second value, columns in a and b which have the same row value get the maximum value in new matrix. i.e.
a = 1 2 3
8 2 5
b = 1 2 5 7
2 4 6 1
Desired output
c = 1 2 3 5 7
8 4 5 6 1
Any help is welcomed,please.( the case for accumulation is asked here)
Accumarray accepts functions both anonymous as well as built-in functions. It uses sum function as default. But you could change this to any in-built or anonymous functions like this:
In this case you could use max function.
in = horzcat(a,b).';
[uVal,~,idx] = unique(in(:,1));
out = [uVal,accumarray(idx,in(:,2),[],#max)].'
Based upon your previous question and looking at the help file for accumarray, which has this exact example.
[ii, ~, kk] = unique([a(1,:) b(1,:)]);
result = [ ii; accumarray(kk(:), [a(2,:) b(2,:)], [], #max).'];
The only difference is the anonymous function.

Remove duplicates appearing next to each other, but keep it if it appears again later

I have a vector that could look like this:
v = [1 1 2 2 2 3 3 3 3 2 2 1 1 1];
that is, the number of equal elements can vary, but they always increase and decrease stepwise by 1.
What I want is an easy way to be left with a new vector looking like this:
v2 = [ 1 2 3 2 1];
holding all the different elements (in the right order as they appear in v), but only one of each. Preferably without looping, since generally my vectors are about 10 000 elements long, and already inside a loop that's taking for ever to run.
Thank you so much for any answers!
You can use diff for this. All you're really asking for is: Delete any element that's equal to the one in front of it.
diff return the difference between all adjacent elements in a vector. If there is no difference, it will return 0. v(ind~=0) will give you all elements that have a value different than zero. The 1 in the beginning is to make sure the first element is counted. As diff returns the difference between elements, numel(diff(v)) = numel(v)-1.
v = [1 1 2 2 2 3 3 3 3 2 2 1 1 1];
ind = [1 diff(v)];
v(ind~=0)
ans =
1 2 3 2 1
This can of course be done in a single line if you want:
v([1, diff(v)]~=0)
You could try using diff which, for a vector X, returns [X(2)-X(1) X(3)-X(2) ... X(n)-X(n-1)] (type help diff for details on this function). Since the elements in your vector always increase or decrease by 1, then
diff(v)
will be a vector (of size one less than v) with zeros and ones where a one indicates a step up or down. We can ignore all the zeros as they imply repeated numbers. We can convert this to a logical array as
logical(diff(v))
so that we can index into v and access its elements as
v(logical(diff(v)))
which returns
1 2 3 2
This is almost what you want, just without the final number which can be added as
[v(logical(diff(v))) v(end)]
Try the above and see what happens!

select neighbors and find Top n in Matlab [duplicate]

This question already has answers here:
Get the indices of the n largest elements in a matrix
(4 answers)
Closed 8 years ago.
If I have a matrix like this:
sample = [1 0.21852382 0.090085552 0.219984954 0.446286385;
0.21852382 1 0.104580323 0.138429617 0.169216538;
0.090085552 0.104580323 1 0.237582739 0.105637177;
0.219984954 0.138429617 0.237582739 1 0.192753169;
0.446286385 0.169216538 0.105637177 0.192753169 1 ]
I want to find the top 3 max values in every rows in Matlab.
what i do in Matlab?
and is it true? i want to find top-N method in select neighbors.
I would recommend rewording your question. You say you want the top ten max values in every row, but the matrix you gave has only five columns :/
I think that what you are looking for is something like this.
sample = [1 0.21852382 0.090085552 0.219984954 0.446286385;
0.21852382 1 0.104580323 0.138429617 0.169216538;
0.090085552 0.104580323 1 0.237582739 0.105637177;
0.219984954 0.138429617 0.237582739 1 0.192753169;
0.446286385 0.169216538 0.105637177 0.192753169 1 ]
B = sort(sample,2,'descend') % will sort the rows of the array in descending order
C = B(:,1:N) % Select the top N values.
Hope this answers your question.
If that isn't what you want, try [Y,I] = max(matrix,[],desired_dimension) where Y and an array of the is the actual max values (e.g. [1 1 1 1 1]) and I is the index of the max values, (e.g [1 2 3 4 5])
EDIT
If desired_output = [1 1 1 1 1]', (a column vector, note transpose), then the command to do that is max(matrix,[],2) to operate along the second dimension. This behavior is defined in help max.