So I'm working with sparse matrix and I have to find out different info about a very big one (10^6 size) and I need to find out the mean of the outlinks. Just to be sure I think mean is what you get from 3+4+5/3=4, 4 is the mean.
I thought of something like this:
[row,col] = find(A(:,2),1,'first')
and then I would do 1/numberInThatIndex or something similar, since it's a S-matrix (pretty sure it's called that).
And I would iterate column by column but for some reason it's not giving me the first number in each column, if I do find(A(:,1),1,'first') it does give me the first in the first column, but not in the second if I change it to A(:,2).
I'd also need something to store that index to access the value, I thought of a 2xN vector but I guess it's not the best idea. I mean, find is going to give me index, but I need the value in that index, and then store that or show it. Not sure if I'm explaining myself properly but I'm trying, sorry about that.
Just to be clear both when I input A(:,1) and A(:,2) it gives me index from the first column, and I do not want that, I want first element found from each column, so I can calculate the mean out of the number in that index.
edit: allright it seems like that indeed does work, but when I was checking the results I was putting 3817 instead of 3871 that was the given answer and so I found a 0 when I wanted something that's not a zero. Not sure if I should delete all of this.
To solve your problem, you can do the following:
numberNonZerosPerColumn = sum(S~=0,1);
meanValue = nanmean(1./numberNonZerosPerColumn);
Count the number of nonzero elements in every column n(i)
Compute the values v(i) that are stored there, which are defined by v(i) := 1/n(i)
Take the mean of those values where n(i) is not zero (i.e. summing all those values, where v(i) is not NaN and divide by the number of columns that contain at least one zero)
If you want to treat columns without any nonzero entry as v(i):= 0, but still use them in your mean, you can use:
numberNonZerosPerColumn = sum(S~=0,1);
meanValue = nansum(1./numberNonZerosPerColumn)/size(S,2);
Related
My goal is to create a random, 20 by 5 array of integers, sort them by increasing order from top to bottom and from left to right, and then calculate the mean in each of the resulting 20 rows. This gives me a 1 by 20 array of the means. I then have to find the column whose mean is closest to 0. Here is my code so far:
RandomArray= randi([-100 100],20,5);
NewArray=reshape(sort(RandomArray(:)),20,5);
MeanArray= mean(transpose(NewArray(:,:)))
X=min(abs(x-0))
How can I store the column number whose mean is closest to 0 into a variable? I'm only about a month into coding so this probably seems like a very simple problem. Thanks
You're almost there. All you need is a find:
RandomArray= randi([-100 100],20,5);
NewArray=reshape(sort(RandomArray(:)),20,5);
% MeanArray= mean(transpose(NewArray(:,:))) %// gives means per row, not column
ColNum = find(abs(mean(NewArray,1))==min(abs(mean(NewArray,1)))); %// gives you the column number of the minimum
MeanColumn = RandomArray(:,ColNum);
find will give you the index of the entry where abs(mean(NewArray)), i.e. the absolute values of the mean per column equals the minimum of that same array, thus the index where the mean of the column is closest to 0.
Note that you don't need your MeanArray, as it transposes (which can be done by NewArray.', and then gives the mean per column, i.e. your old rows. I chucked everything in the find statement.
As suggested in the comment by Matthias W. it's faster to use the second output of min directly instead of a find:
RandomArray= randi([-100 100],20,5);
NewArray=reshape(sort(RandomArray(:)),20,5);
% MeanArray= mean(transpose(NewArray(:,:))) %// gives means per row, not column
[~,ColNum] = min(abs(mean(NewArray,1)));
MeanColumn = RandomArray(:,ColNum);
I got the following error while working with a MATLAB program:
Error using - Matrix dimensions must agree
I noticed that the sizes of the matrices I'm trying to subtract from each other were:
firstMatrix --> 425x356
secondMatrix --> 426x356
How can I make them of equal size and go ahead and do my subtraction process?
I tried reshape, but the number of elements here seem to have to be equal.
Thanks.
I think both answers are missing the key point. Blithely subtracting two arrays of different size forgets that those arrays are NOT just numbers. The numbers must mean something. Else, they are just meaningless.
As well, simply deleting a row from the beginning or end may well be wrong, or padding with zeros. Only you know what the numbers mean, and why those arrays are not the same size. So only you can decide what is the proper action.
It might be right to pad, delete, interpolate, do any of these things. Or you might realize there is a bug in your code that created these arrays.
Your matrices have a different number of elements, so there's no point using reshape here (since it maintains the total number of elements). You'll have to discard one of the lines in the larger matrix before doing the subtraction:
For instance, you can discard the last line:
firstMatrix - secondMatrix(1:end - 1, :)
or discard the first line:
firstMatrix - secondMatrix(2:end, :)
Alternatively, you can pad the smaller matrix with default values (e.g NaN or zeroes), as suggested in another answer.
You're missing a row in firstMatrix
So can try:
firstMatrix=[firstMatrix;zeros(1,356)];
This will add a row of zeros at end of firstMatrix making it of 426x356
I'm trying to find the first 1 in each column of a matrix without using a for or a while. Say I have
-->A
A =
1. 0. 0. 0.
0. 0. 1. 1.
1. 0. 1. 1.
1. 1. 0. 0.
then I would like to obtain [1,4,2,2] (I can assume there is always a 1 somewhere in each column). The thing is when I use find(A), it gives me [1,3,4,8,10,11,14,15].
I was told not to use loops but matrix operations because scilab handles the last ones better.
Thank you in advance!
With such a small matrix performance could be fast enough with a for loop and probably more readible. But one solution avoiding the use of for loops could be as following.
//Find all rows and cols of the ones in A
[row,col] = find(A);
//Get all row positions that are in a new column index
disp( row( find([1,diff(col)]) ));
I think a more readible solution would be something like the following:
//For each column
for col=1:4
//Find only the first occurence
disp(find(A(:,col),1));
end
As mentioned, with such a small matrix readibility should be a higher priority. You could measure performance of both (or other) solutions by profiling.
If you like to read more about some performance enhancing techniques have a look here.
I'm trying to find a way to find the sets of coordinates of the maximum value/s in a matrix of size [8,8], where the values in the matrix vary from 0 to 6 (generated through the rest of the script/function).
i.e. a matrix of zeros(8,8) where the value 1 is in [3,3], [3,5] and [5,3].
and I want to get returned something along the lines of ([3,3],[3,5],[5,3])
I have tried using things such as ind2sub, etc but with no luck (I keep getting things returned like [I,J] = [ [0,0,3,0,5,0,0,0] , [1,1,1,1,1,1,1,1] ])
Any ideas?
If more clarification is needed, just point out where you need it and I'd be glad to do so.
The problem you've been having with max so far is because it operates on one dimension. If you call it on a matrix, using its default parameters, it will return a single maximum element (and indices) for each column of the matrix. In your case, you want all maximums, and the global maximum at that.
Try this:
[I,J] = find(M == max(M(:)))
First, max(M(:)) finds the maximum element, then we construct a logical matrix M == max(M(:)) showing which elements are the maximum. Finally, you can use find to get the co-ordinates of those (if necessary).
I have a 161*32 matrix (labelled "indpic") in MATLAB and I'm trying to find the frequency of a given number appearing in a row. So I think that I need to analyse each row separately for each value, but I'm incredibly unsure about how to go about this (I'm only new to MATLAB). This also means I'm incredibly useless with loops and whatnot as well.
Any help would be greatly appreciated!
If you want to count the number of times a specific number appears in each row, you can do this:
sum(indpic == val, 2)
where indpic is your matrix (e.g image) and val is the desired value to be counted.
Explanation: checking equality of each element with the value produces a boolean matrix with "1"s at the locations of the counted value. Summing each row (i.e summing along the 2nd dimension results in the desired column vector, where each element being equal to the number of times val is repeated in the corresponding row).
If you want to count how many times each value is repeated in your image, this is called a histogram, and you can use the histc command to achieve that. For example:
histc(indpic, 1:256)
counts how many times each value from 1 to 256 appears in image indpic.
Like this,
sum(indpic(rownum,:) == 7)
obviously change 7 to whatever.
You can just write
length(find(indpic(row_num,:)==some_value))
and it will give you the number of elements equal to "some_value" in the "row_num"th row in matrix "indpic"