Indexing data in matlab - matlab

I have imported a lot of data from an excel spreadsheet so that I have a 1x27 matrix.
I have imported data from excel using this
filename = 'for_matlab.xlsx';
sheet = 27;
xlRange = 'A1:G6';
all_data = {};
for i=1:sheet,
all_data{i} = xlsread(filename, i, xlRange);
end
However each element of this all_data matrix (which is 1x27) contains my data but I'm having trouble accessing individual elements.
i.e.
all_data{1}
Will give me the entire matrix but I need to perform multiplications on individual elements of this data
also
all_data(1)
just gives '5x6 double', i.e. the matrix dimensions.
Does anybody know how I can divide all elements of each row by the third element in each row and do this for all of my 'sub-matrices' (for want of a better word)

Assuming that all_data is a cell array and that each cell contains a matrix (with at least three columns):
result = cellfun(#(x) bsxfun(#rdivide, x, x(:,3)), all_data, 'uniformoutput', 0);

You are mixing terminology in matlab. what you have is 1x27 CELLS each of them containing a matrix.
If you access all_data{1} it will give you the whole matrix stored in the first cell.
If you want to access the elemets of that matrix then you need to do: all_data{1}(2,4). This example access the 2,4 element of the matrix in the first cell.
Definitely Luis Mendo has solved you problem, but be aware of the differences of Cells and matrixes in Matlab!

Okay I have found the answer now.
Basically you have to use both types of brackets because the data types are different
i.e. all_data{1}(1:4) or something like that anyway.
Cheers

Related

How to sum a matrix with unaligned elements?

I am trying to sum in the second dimension a matrix QI in Matlab. The trick is, the columns contain a series of increasing numbers, but not all columns have the same number of elements (i.e. numel(QI(:,1)) ~= numel(QI(:,2)) and so on). For the sake of clarity, I attach a picture of it. Note that I padded the missing areas with 0, so the previous condition becomes nnz(QI(:,1)) ~= nnz(QI(:,2)).
One initial strategy that I thought of was to treat this as an image and construct a mask for each different gradient level, but that seems like a tedious job.
Anyone has a better idea on how to do this? I should also mention that I am able to freely modify how QI is generated, but I'd rather not if there is a solution for this problem.
EDIT:
Hopefully the new colored image should give a better understanding.
FYI, each column was previously stored in a cell array without the trailing zeros. Then I extracted the columns one by one and stored them in a matrix in order to perform the summation, padding the extra zeros whenever the length isn't the same.
Generally these column data should have the same number of rows, but sometimes that's not the case, and even worse, they do not allign properly.
I'm starting to think if it's better to rework the code that generate the cell arrays rather than this matrix. Thoughts?
Thank you,
edit: following you comment, I modified the answer. Be aware that your data cannot be really "aligned" because they have not the same number of value.
A way would be to use a cell as a storage for your measures.
valueMissing = 0; % here you can put the defauld value you want
% transform you matrix in a cell
QICell = arrayfun(#(x) QI(QI(:,x)!=valueMissing,x), 1:size(QI,2),'UniformOutput', false);
Now you can sum the last element of the vectors inside the cell
QIsum = sum(cellfun(#(x) x(end), QICell))
Or reorder the vectors so that your last element are "aligned"
QICellReordered = cellfun(#(x) x(end:-1:1),QICell, 'UniformOutput',false);
Then you can make all possible sums:
m = min(cellfun(#numel, QICellReordered));
QIsum = zeros(m,1);
for i=1:m
QIsum(i) = sum(cellfun(#(x) x(i), QICellReordered));
end
% reorder QISum to your original order
QIsum = QIsum(end:-1:1);
I hope this help !

How to populate an array within an array in MATLAB and how to access them?

For example
A = {{1,2},{23,34},{45,4},...}
How to create such a data type in MATLAB
How to access the i-th element and the elements within it?
For Ex. A[2] should return {23,34} and A[2].1 should return 23.
A = {{1,2},{23,34},{45,4},...}
is valid MATLAB syntax, if you are trying to make a cell array of cell arrays. However, you'd probably want to store vectors rather than arrays in your array:
A = {[1,2],[23,34],[45,4],...}
Access them like A{2} or A(2) but far more likely the first one. If you want an individual element then A{2}(1)
But if every one of your cells is going to contain a 2 element vector then you will have a much easier time just using a 2D matrix:
A = [1,2;23,34;45,4;,...]
And and now access the entire row i.e. A(2,:) or for an individual element A(2,1)

MATLAB: If this value of 5x5 cell with vectors [106x1] are different to zeroes,count them e put the count in a matrix

I have matchcounts (5x5)cell, every cell has a vector of double [106x1]. The vectors of double have zeros and non zero values. I want to find non zero values for every cell, count them and put the result in a matrix.
I tried with this code:
a{i,j}(k,1)=[];
for k=1:106
for i=1:5
for j=1:5
if (matchcounts{i,j}(k,1))~=0
a{i,j}=a{i,j}(k,1)+1;
end
end
end
end
and others but it's not correct! Can you help me? Thanks
While it is possible to fix your answer above, I recommend to change the data structure to have a much simpler solution possible. Instead of having a 2D cell array which holds 1D data, choose a single 3D data structure.
For an optimal solution you would change your previous code code to directly write the 3D-matrix, instead of converting it. To get started, this code converts it so you can already see how the data structure should look like:
%convert to matrix
for idx=1:numel(matchcounts)
matchcounts{idx}=permute(matchcounts{idx},[3,2,1]);
end
matchcounts=cell2mat(matchcounts);
And finding the nonzero elements:
a=(matchcounts~=0)
To index the result, instead of a{k,l}(m,1) you use a(k,l,m)
To give you some rule to avoid complicated data structures in the future. Use cell arrays only for string data and data of different size. Whenever you have a cell array which contains only vectors or matrices of the same size, it should be a multidimensional matrix.

creating a new matrix from a cell array after evaluating one column.

I have a cell array of 447*1 Dimensions. The cell array has 2Dimensional arrays of different dimensions of type double. I want to check a particular value in that cell array compare and on that basis store it in a new Matrix.
So for example my my starting cell array is Y{447*1} . My first cell contains an array of
5*10 and second array contains data of 22*10 . I want to evaluate the second column
of this array and then store it in a new Matrix.
I did this for one set of data and the code looks something like this.
A = [y{2,1}(1:20,2),y{4,1}(1:20,2),y{6,1}(1:20,2),y{8,1}(1:20,2),...
y{10,1}(1:20,2),y{12,1}(1:20,2),y{14,1}(1:20,2),y{16,1}(1:20,2),...
y{18,1}(1:20,2),y{20,1}(1:20,2),y{22,1}(1:20,2),y{24,1}(1:20,2),...
y{26,1}(1:20,2),y{28,1}(1:20,2),y{30,1}(1:20,2)];
But I want to automate the thing. Please help how this can be done.
Something along the lines of:
Temp = cellfun(#(x) x(1:20,2),Y(1:2:end,1), 'UniformOutput', false);
A = cat(2,Temp{:});
Should work if I am reading your question right - it should replicate your example anyway.
You can then change the dimensions of the #(x) function x(1:20,2) to take out different values from your cell array, and use different cell indexing for Y(:,1) to pick different parts of Y.

How can I create an array of handles / pointers to matrices in Matlab?

I have a bunch of related matrices of different sizes, and would like to be able to incrementally access them. Is there an easy way to create a vector of handles or pointers to these matrices in Matlab? Or is this not the way I am supposed to do it?
For example, here I want to assign to the vector indexed with i, which will be a handle to the matrices of different size.
rows = [1:6];
columns = [10:2:20];
for i=1:6
vector_of_pointers(i) = ones(rows(i),columns(i));
end
In Matlab, there aren't really pointers.
Instead, you can collect the arrays in a cell array, like so
rows = [1:6];
columns = [10:2:20];
for i=1:6
arrayOfArrays{i} = ones(rows(i),columns(i));
end
To access, say, array #3, you write arrayOfArrays{3}, and if you want its second row only, you write arrayOfArrays{3}(2,:).
You can also create your array using ARRAYFUN
arrayOfArrays = arrayfun(#(u,v)ones(u,v),rows,columns,'uniformOutput',false)