How to sum the values of an MxN cell array? - matlab

How can I make the sum of values in an MxN cell array? I used cellfun('sum',CellArray{i})
in which, i refers to the MxN index of the CellArray. But because I used it in a loop to count the number of blocks, it gives me error for being out of index.
What's the right way to do that please?

I don't know if I got your problem entirely right. You just want the total sum of all elements of a cell array? Assuming they are doubles, you first need to transform your cell array into a matrix, and then you can use the normal sum function.
% example data
xCell = num2cell( magic(10) )
gives you a a 10x10 cell array with some magic numbers from 1 to 100.
The following creates a column-vector of all cell contents and sums them up:
S = sum([xCell{:}])
S =
5050
which is the result good ol' Mr. Gauss didn't need Matlab for.
Alternatively if you're interested in the sum of all single rows or columns, you can use:
S = sum(cell2mat(xCell),dimension) % dimension = 1 or 2 (or 3)
regarding your comment in your follow-up question, that you actually have complex doubles:
use:
S = sum( real( [xCell{:}] ) )

Related

Removing rows based on a condition (Matlab)

I am trying to remove rows from a matrix based on a condition. I have a 371000x5 double matrix, and a 371000x1 vector of dummies (1 and 0). I want to remove each row from the original matrix, where the value of the vector of dummies is 1.
I have tried the following, but it is taking very long:
for i = 1:size(matrix_num,1)
if missing_matrix(i,1) >=0
matrix_num(i,:) = [];
end
end
My Matlab has been busy for over 30 minutes now, so I am not even sure if the code is right. Is there a more efficient way to do this?
Additionally, I have to do the same action on a cell matrix (categorical data). Should I expect any huge difference from the numerical matrix?
The programmatic way of doing this is:
new_matrix = old_matrix(missing_vector==1,:)
for keeping lines with missing_vector 1
new_matrix = old_matrix(missing_vector==0,:)
for removing lines with missing_vector 1
For educational values, if you want the loop to work, don't do that row by row. Your solution causes the matrix to be copied and re-allocated on every row removed.
So, you would be better off if you calculate the resulting matrix size in advance:
new_matrix = zeros(sum(missing_vector), 5)
and then your iteration would work:
index_new=1
for index_old = 1:size(old_matrix,1)
if missing_vector(index_old) ==0
new_matrix(index_new,:) = old_matrix(index_old,:);
end
end
Try compact MATLAB code
matrix_num(missing_matrix>=0,:)=[]
Note : You must make a vector for missing_matrix variable. If this variable is matrix, you need other form of code .
As I know, you can use it in cell array too.

Access multiple elements and assign to each selected element a different value

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....).

How to sum up values in corresponding indexes of cells?

I have a 1x24 cell array called chaining, whose each cell contains a 119x119 matrix:
I want to find the sum of each corresponding elements of all the cells, and store them in a matrix called result. That is, the (j,k)th element of result should contains the sum of the (j,k)th elements of all the matrices in the cell array chaining.
The code I wrote to do this is:
for j=1:size(chaining,2)
for k=1:size(chaining,2)
result(j,k) = sum(chaining{1,:}(j,k));
end
end
But this gives error because apparently MATLAB can't aggregate cell arrays for some reason (i.e., the chaining{1,:} part).
Could anyone please show me how to go about doing this?
how about
result = sum( cat(3, chaining{:}), 3 );
What just happened here?
First, we convert the cell array into a 3D array by "stacking" the 2D cell elements on the third dimension:
cat(3, chaining{:})
Once we have a 3D array of size 119-by-119-by-24 we can sum along the third dimension and get result of size 119-by-119:
sum( ..., 3 );
For more info see cat and sum help pages.
BTW,
If you insist on chaining{1,:}(jj,kk) type of solution (not recommended), you might find subsref command useful.

Fastest way of finding repeated values in different cell arrays of different size

The problem is the following:
I have a cell array of the form indx{jj} where each jj is an array of 1xNjj, meaning they all have different size. In my case max(jj)==3, but lets consider a general case for the shake of it.
How would you find the value(s) repeated in all the jj i the fastest way?
I can guess how to do it with several for loops, but is there a "one (three?) liner"?
Simple example:
indx{1}=[ 1 3 5 7 9];
indx{2}=[ 2 3 4 1];
indx{3}=[ 1 2 5 3 3 5 4];
ans=[1 3];
One possibility is to use a for loop with intersect:
result = indx{1}; %// will be changed
for n = 2:numel(indx)
result = intersect(result, indx{n});
end
Almost no-loop approach (almost because cellfun essentially uses loop(s) inside it, but it's effect here is minimal as we are using it to find just the number of elements in each cell) -
lens = cellfun(#numel,indx);
val_ind = bsxfun(#ge,lens,[1:max(lens)]');
vals = horzcat(indx{:});
mat1(max(lens),numel(lens))=0;
mat1(val_ind) = vals;
unqvals = unique(vals);
out = unqvals(all(any(bsxfun(#eq,mat1,permute(unqvals,[1 3 2]))),2));
Another possibility that I could suggest, though Luis Mendo's answer is very good, is to take all of the vectors in your cell array and remove the duplicates. This can be done through cellfun, and specifying unique as the function to operate on. You'd have to set the UniformOutput flag to false as we are outputting a cell array at each index. You also have to be careful in that each cell array is assumed to be all row vectors, or all column vectors. You can't mix the way the arrays are shaped or this method won't work.
Once you do this, concatenate all of the vectors into a single array through cell2mat, then do a histogram through histc. You'd specify the edges to be all of the unique numbers in the single array created before. Note that you'd have to make an additional call to unique on the output single array before proceeding. Once you calculate the histogram, for any entries with a bin count equal to the total number of elements in your cell array (which is 3 in your case), then these are values that you see in all of your cells. As such:
A = cell2mat(cellfun(#unique, indx, 'uni', 0));
edge_values = unique(A);
h = histc(A, edge_values);
result = edge_values(h == numel(indx));
With the unique call for each cell array, if a number appears in every single cell, then the total number of times you see this number should equal the total number of cells you have.

How to extract a row of a matrix

In every other language if I have a matrix, if I call a mono-dimensional index, the result will be an array.I don't know why in Matlab if you take a single index of a matrix, you'll get a single element, that's stupid.
Anyway in C:
mat[4][4];
mat[0] is an array.
In Matlab:
mat=[1 2; 3 4];
How do I take the first row of the matrix? mat(1) is 1, not [1 2].
EDIT: There is another problem, I have a problem with this function:
function str= split(string, del)
index=1;
found=0;
str=['' ; ''];
for i=1:length(string)
if string(i)==del
found=1;
index=1;
elseif found==1
str(2,index)=string(i);
index=index+1;
else
str(1,index)=string(i);
index=index+1;
end
end
end
This returns sometimes a matrix and sometimes an array.
For example if I use split('FF','.') I get 'FF' as result, but what if I want to return a matrix? I can't even choose the dimensione of the matrix, in this context a weak typed language is a big disvantage.
You have to say which columns you want. : stands for all indices in a dimension, so to take first row
mat(1,:)
It is not stupid, but useful. If you address a matrix with only one index, it implicitly gets converted to a vector. This gives you the option to use linear indices (see sub2ind).
This will extract the second row
vector = mat(2,:)
And This will extract the second column
vector = mat(:,2)
You can use
vector = mat(end,:)
To extract the last row
Hope this helps you
From Matrix Indexing in MATLAB:
When you index into the matrix A using only one subscript, MATLAB
treats A as if its elements were strung out in a long column vector,
by going down the columns consecutively
I just hope it doesn't look stupid to you anymore (along with the right answers from angainor and Marwan)