I have a huge matrix in MATLAB. Now some rows contain only zeros.
Can I use the function find to find all the rows which contain only zeros ?
You can use any to find any rows that have non-zeros and then negate the result. We use the second input to specify that we want to apply the operation across the columns (the 2nd dimension).
row_has_all_zeros = ~any(data, 2)
If you want the indices instead of the logical array, just apply find to the result:
indices = find(row_has_all_zeros);
If you need, you can obtain more speed (depending on your dataset) by first looking for partial zero rows (in this example length 10) and computing further with the selection of rows.
row_has_first10_zeros = sum(data(:,1:10),2);
row_has_all_zeros = sum(data(~rows,:),2);
indices = find(~row_has_first10_zeros)
indices = indices(~row_has_all_zeros)
n = length(matrix);
This line will give you the number of rows in a matrix.
ids = setdiff(1:n,find(sum(matrix,2)));
ids will give you the row numbers(indexes) which contain only zeros.
Related
My matlab code is attempting to find the indices in a 601 by 1 matrix that correspond to a given value but says the left and right sides have a different number of elements
pH_fine = pH(1):0.01:pH(end);
pH_labvals = [7.72,9.87,7.4,7.63,7.06,6.85,8.29,9.37,11.1];
index_labvals = [];
a = find(pH_fine == 8); %This works perfectly
for i = 1:length(pH_labvals)
index_labvals(i) = find(pH_fine == pH_labvals(i)); %This throws an error
end
Your problem is that the find(pH_fine == pH_labvals(i)) on the right side sometimes doesn't find any match, and returns an empty result for an index, specifically a 1-by-0 row vector. This doesn't match the size of the left side, which is indexing a 1-by-1 element from your vector index_labvals.
You need to check first if the result of find is empty, and decide what you will put in the index vector in that case, like a 0 or NaN. You will also need to deal with find giving you a vector of indices if pH_labvals has the same value repeated. If you simply want to remove repeated values, you could use unique like so:
pH_labvals = unique(pH_labvals, 'stable');
If you're wondering why you're getting an empty result from find, you should read through this post about the perils of floating-point comparison. One possible solution, assuming pH_labvals contains non-repeated values with 2 decimal places of precision, is to first round your pH_fine vector to 2 decimal places:
pH_fine = round(pH(1):0.01:pH(end), 2);
This should allow you to avoid the errors from floating-point comparison.
An alternative approach is to use interp1 for table lookup:
pH = [1,14]; % Not sure what values you use here, it doesn't matter for the example.
pH_fine = pH(1):0.01:pH(end);
pH_labvals = [7.72,9.87,7.4,7.63,7.06,6.85,8.29,9.37,11.1];
index_labvals = interp1(pH_fine,1:numel(pH_fine),pH_labvals,'nearest')
Here, we're finding the nearest index within pH_fine that matches each of the values in pH_labvals. 1:numel(pH_fine) are the indices into pH_fine.
Note that there's no need for a loop, as interp1 will lookup all pH_labvals at once.
I need to know if there is any efficient way of doing the following in MATLAB.
I have several big sparse matrices, the size of each one is roughly 9000000x9000000.
I need to access multiple element of such matrix and assign to each selected element a different value stored in another array. I'll give an example:
What I have:
SPARSE MATRIX of size 9000000x9000000
Matrix with the list of indexes and values I want to access, this is a matrix like this:
[row1, col1, value1;
row2, col2, value2;
...
rowN, colN, valueN]
Where N is the length of such matrix.
What I need:
Assign to the SPARSE MATRIX the corresponding value to the corresponding index, this is:
SPARSE_MATRIX(row1, col1) = value1
SPARSE_MATRIX(row2, col2) = value2
...
SPARSE_MATRIX(rowN, colN) = valueN
Thanks in advance!
EDIT:
Thank you to both for answering, I think I did not explain myself well, I'll try again.
I already have a large SPARSE MATRIX of about 9000000 rows x 9000000 columns, it is a SPARSE MATRIX filled with zeros.
Then I have another array or matrix, let's call it M with N number of rows, where N could take values from 0 to 9000000; and 3 columns. The first two columns are used to index an element of my SPARSE MATRIX, and the third column stores the value I want to transfer to the SPARSE MATRIX, this is, given a random row of M, i:
SPARSE_MATRIX(M(i, 1), M(i, 2)) = M(i, 3)
The idea is to do that for all the rows, I have tried it with common indexing:
SPARSE_MATRIX(M(:, 1), M(:, 2)) = M(:, 3)
Now I would like to do this assignation for all the rows in M as fast as possible, because if I use a loop or common indexing it takes ages (I am using a 7th Gen i7 processor with 16 GB of RAM). And I also need to keep the zeros in the SPARSE_MATRIX.
EDIT 2: SOLVED! Thank you Metahominid, I was not thinking through, but yes the sparse function does solve my problem, I just think my brain circuits were shortcircuited yesterday and was unable to see through it hahaha. Thank you to both anyway!
Regards!
You can construct a sparse matrix like this.
A = sparse(i,j,v)
S = sparse(i,j,v) generates a sparse matrix S from the triplets i, j,
and v such that S(i(k),j(k)) = v(k). The max(i)-by-max(j) output
matrix has space allotted for length(v) nonzero elements. sparse adds
together elements in v that have duplicate subscripts in i and j.
So you can simply construct the row vector, column vector and value vector.
I am answering in part because I cannot comment. You question seems a little confusing to me. The sparse() function in MATLAB does just this.
You can enter your arrays of indices and values directly into the interface, or declare a sparse matrix of zeros and set each individually.
Given your data format make three vectors, ROWS = [row1; ...; rown], COLS = [col1; ...; coln], and DATA = [val1; ... valn]. I am assuming that your size is the overall size of the full matrix and not the sparse portion.
Then
A = sparse(ROWS, COLS, DATA) will do just what you want. You can even specify the original matrix size.
A = sparse(ROWS, COLS, DATA, 90...., 90....).
Consider A an m by n matrix. I want to split A column wise by randomly picking NumOfRandomColumn columns.
I have used this code to generate a vector of random indexes and extract the firs section:
indexes=randsample(1:MatrixColumnNumber, NumOfRandomColumn);
firstSection=A(:,indexes);
How do I extract the second section, that is , the indexes not in 'indexes'?
This did not work:
secondSection=A(:,~indexes);
This should work:
notselected = 1:MatrixColumnNumber;
notselected(indexes) = [];
secondSection = A(:,notselected);
It's basically a way to form the difference set between 1:N and your selected index set. This can also be done with setdiff but I remember setdiff as being slower than the above.
I get an image, let say
img=imread('test.jpg')
how can I count all pixel values in each row for a projection on a 1D signal to the right and the pixel values of each column for a projection to the bottom.
does it mean I need to find sum or the pixel in row and column.
what is the statement to sum row pixel and column pixel?
is this statement for sum of row pixel : sum_all = sum(img(:)); if so, what is the statement for sum of column pixel?
you should check the documentation for the sum function in matlab. The second argument specifies the dimension to sum. if dimension=1, then you're summing the rows. If dimension=2, then you want to sum the columns. Therefore, you have the simple code:
% Sum the rows
sum_rows = sum(img);
% Alternate form to sum the rows
sum_rows = sum(img, 1);
% sum the columns
sum_cols = sum(img, 2);
You can slice an n-dimensional array using the img(:,x) notation. the : indicates that you want all of the indexes from that pixel. You could also do img(a:b,x) if you want a subset of one row.
Using this method, you can sum one row of an image as sum(img(:,n)) where n is the row you want to sum. Likewise, for columns, it would be sum(img(n,:)).
I have done the following:
img=imread('test4.jpg');
sum_row = sum(img,2);
this gives me the sum for every row,,,
sum_col = sum(img,1);
this gives me the sum for every column,,,
is that correct?
Yes I got it correct,
so let say i have 2 values here at the end,
what does it mean by If there are periodic highs or lows?
I have created a function that should be able to read in any mxn matrix and gives me the maximum value of the entire matrix (not just per column) and what its indices are.
function [ BIGGEST ] = singlemax( x )
[Largest_values row]=max(x)
[biggest_number column] = max(max(x))
end
This function gives me all the information I need, however it is not very clean as it gets messy the larger the matrix.
The real problem area is printing out the row in which the maxima is located.
Largest_values =
0.7750 0.9122 0.7672 0.9500 0.6871
row =
3 2 3 2 2
biggest_number =
0.9500
column =
4
This is my print out given a random matrix as an input.With the function I have created I cannot read the indices of my max value in any given array using a created function. If I could somehow relate the maximas from each column and there corresponding row (such as making the results a matrix with the column max on top and the row index on bottom, all within the same respective columns )I could display the row of the absolute maximum.
Here's one approach:
value = max(x(:));
[rowIndex,columnIndex] = ind2sub(size(x),find(x==value));
Read the ind2sub documentation for more details.
Edited to modify so that it finds indices of all occurrences of the maximum value.