Excel 5 Dimensional arrays - arrays

How do I make a 5D array in excel? I have to later shift it to Matlab as a 5D single array. I have large amounts of EEG data that I need to sort into arrays.

Are you asking for help on VBA, or looking for help on how to encode a 5D array in an Excel sheet? This answer assumes the latter. There are many ways to do this, but here are two options (not necessarily good options, but hopefully they will help you think creatively about the problem).
(1) If the array is sparse, you can store the data in an excel sheet as a list of tuples of the form (dim1, dim2, dim3, dim4, dim5, value), preceded by the dimensionality of the array. For example, your Excel sheet could contain the following data:
5 9 9 7 8
1 2 9 6 4 10.1
4 9 3 7 2 18.9
3 2 1 7 8 19.2
and the corresponding MATLAB array would be defined as follows (assuming you want empty values to be NaNs):
mat = NaN(5, 9, 9, 7, 8);
mat(1, 2, 9, 6, 4) = 10.1;
mat(4, 9, 3, 7, 2) = 18.9;
mat(3, 2, 1, 7, 8) = 19.2;
(2) You can store the array as a simple list of values, again preceded by the array's dimensionality. The list could be indexed canonically based on how MATLAB vectorizes arrays. For example, your Excel sheet could contain the following data:
5 9 9 7 8
11.3
14.2
25.5
18.9
<etc.>
and the corresponding MATLAB array would be defined as follows (again assuming you want empty values to be NaNs):
mat = NaN(5, 9, 9, 7, 8);
mat(1) = 11.3;
mat(2) = 14.2;
mat(3) = 25.5;
mat(4) = 18.9;
<etc.>
Of course, in both cases, you can automate the loading of the matrices from Excel into MATLAB, using MATLAB functions such as xlsread and reshape.
And also there is nothing special about Excel files for the way I'm interpreting your question; if you want to go this route then CSV files might be a better option for storing the data.

Related

What does Array(True/False Array) does in MATLAB? [duplicate]

This question already has an answer here:
Linear indexing, logical indexing, and all that
(1 answer)
Closed 1 year ago.
I am trying to understand what happens in MATLAB for this certain line of code
good_mintratio=handles.mintratio(handles.good)
handles.good is an array with size (48x60) where all the elements are 1. handles.mintratio is also an array with size (48x60) where it contains floats.
I ran the following simple code to understand what it exactly does but I am not quite sure what is really happening.
For this piece of code,
A = [1,2,3; 4,5,6];
B = [1,1,1; 1,1,1];
C=A(B);
This returns C = [1,1,1;1,1,1]
It seems like C is like B but contains the elements of A where the elements of B is the indexes for A.
A = [1,2,3; 4,5,6];
B = [2,1,1; 1,5,1];
C=A(B);
Like, this will make C = [4,1,1;1,3,1]
But
good_mintratio=handles.mintratio(handles.good)
this forms a colmun with size (2880,1). It seems like all the elements got combined in to a single colmun but not sure why the size changed. Also, if handles.good has some 0's (which means false in MATLAB, right?), would that change the result?
When you use indexing by arrays (As in C = A(B);) there are 2 options:
The array B is based on non logical numbers (Double usually): The output is based on the linear indexing of the array A.
The array B is based on logical elements: The output is a vector of the elements where true was in B.
For example:
clear();
mA = reshape(1:9, 3, 3);
mB = randi([1, 9], 3, 3);
mC = logical(randi([0, 1], 3, 3));
mA(mB)
mA(mC)
Then the output:
ans =
5 9 5
9 8 9
8 7 4
ans =
2
5
8

Mean values of a matrix in a matrix on Matlab

This is about matlab.
Let's say I have a matrix like this
A = [1,2,3,4,5;6,7,8,9,10;11,12,13,14,15]‍
Now I want to know how to get a mean value of a small matrix in A.
Like a mean of the matrix located upper left side [1,2;6,7]
The only way I could think of is cut out the part I want to get a value from like this
X = A(1:2,:);
XY = X(:,1:2);
and mean the values column wise Mcol = mean(XY);.
and finally get a mean of the part by meaning Mcol row-wise.
Mrow = mean(Mcol,2);
I don't think this is a smart way to do this so it would be great if someone helps me make it smarter and faster.
Your procedure is correct. Some small improvements are:
Get XY using indexing in a single step: XY = A(1:2, 1:2)
Replace the two calls to mean by a single one on the linearized submatrix: mean(XY(:)).
Avoid creating XY. In this case you can linearize using reshape as follows: mean(reshape(A(1:2, 1:2), 1, [])).
If you want to do this for all overlapping submatrices, im2col from the Image Processing Toolbox may be handy:
submatrix_size = [2 2];
A_sub = im2col(A, submatrix_size);
gives
A_sub =
1 6 2 7 3 8 4 9
6 11 7 12 8 13 9 14
2 7 3 8 4 9 5 10
7 12 8 13 9 14 10 15
that is, each column is one of the submatrices linearized. So now you only need mean(A_sub, 1) to get the means of all submatrices.

Initializing multi dimensional arrays in lua/torch

I have gone through a few tutorials about "arrays" in lua/torch and all I see is the word tensors. What exactly are they? How can i initialize a 2d "tensor"? I tried torch.Tensor{1,2,3} which gave me
1
2
3
and torch.Tensor{1,2,3;4,5,6} like in octave/MATLAB but this gave me another column vector
1
2
3
4
5
6
How can I get a 2d "tensor" like the following?
1 2 3
4 5 6
Also, I'm using torch to execute my lua files. Is there no other notation for arrays other than "tensors" i.e. is there no other way we can use to represent a matrix in torch?
torch.Tensor{{1, 2, 3}, {4, 5, 6}}
Have a look at this (or that) for more details on tensors.

Trying to compare elements of on array with every element of another array in matlab

I'm using Matlab, and I'm trying to come up with a vectorized solution for comparing the elements of one array to every element of another array. Specifically I want to find the difference and see if this difference is below a certain threshold.
Ex: a = [1 5 10 15] and b=[12 13 14 15], threshold = 6
so the elements in a that would satisfy the threshold would be 10 and 15 since each value comes within 6 of any of the values in b while 1 and 5 do not. Currently I have a for loop going through the elements of a and subtracting an equivalently sized matrix from b (for 5 it would be a = [5 5 5 5]). This obviously takes a long time so I'm trying to find a vectorized solution. Additionally, the current format I have my data in is actually cells where each cell element has size [1 2], and I have been using the cellfun function to perform my subtraction. I'm not sure if this complicates the solution of each [1 2] block with the [1 2] block of the second cell. A vectorized solution response is fine, there is no need to do the threshold analysis. I just added it in for a little more background.
Thanks in advance,
Manwei Chan
Use bsxfun:
>> ind = any(abs(bsxfun(#minus,a(:).',b(:)))<threshold)
ind =
0 0 1 1
>> a(ind)
ans =
10 15

Easiest way to create arrays based on repeating character positions

I want to group my elements using the repeated segments in the array. The breaking is basically depend on where the repeated segments are, in my real data contains ~10000 elements and I want to know if there is a easier way to do that.
Here is a short example to clarify what I want:
Let's say I have an array,
A=[1 5 3 4 4 4 6 9 8 8 9 5 2];
What I want is to break A into [1 5 3],[6 9], and [9 5 2];
What is the easiest to code this using matlab??
Thanks.
For a vectorized solution, you can find out the places where either forward or backward differences to the neighbor are zero, and then use bwlabel (from the Image Processing Toolbox) and accumarray to gather the data.
A=[1 5 3 4 4 4 6 9 8 8 9 5 2];
d = diff(A)==0;
%# combine forward and backward difference
%# and invert to identify non-repeating elments
goodIdx = ~([d,false]|[false,d]);
%# create list of group labels using bwlabel
groupIdx = bwlabel(goodIdx);
%# distribute the data into cell arrays
%# note that the first to inputs should be n-by-1
B = accumarray(groupIdx(goodIdx)',A(goodIdx)',[],#(x){x})
EDIT
Replace the last two lines of code with the following if you want the repeating elements to appear in the cell array as well
groupIdx = cumsum([1,abs(diff(goodIdx))]);
B = accumarray(groupIdx',A',[],#(x){x})
EDIT2
If you want to be able to split consecutive groups of identical numbers as well, you need to calculate groupIdx as follows:
groupIdx = cumsum([1,abs(diff(goodIdx))|~d.*~goodIdx(2:end)])
Here is a solution that works if I understand the question correctly. It can probably be optimised further.
A=[1 5 3 4 4 4 6 9 8 8 9 5 2];
% //First get logical array of non consecutive numbers
x = [1 (diff(A)~=0)];
for nn=1:numel(A)
if ~x(nn)
if x(nn-1)
x(nn-1)=0;
end
end
end
% //Make a cell array using the logical array
y = 1+[0 cumsum(diff(find(x))~=1)];
x(x~=0) = y;
for kk = unique(y)
B{kk} = A(x==kk);
end
B{:}

Resources