Matlab: How to combine two vectors in one - arrays

I have two vectors
A = [...] %size 1x320
B = [...] %size 1x192
I would like to combine the two vectors in one but the way I want to combine them is the following:
Take the first 5 elements of vector A then add 3 elements from vector B add the next 5 elements from vector A then add the next element from vector B and so on until the both vectors are combined in one. I think the process should be repeated 64 times since 320/5=64 and 192/3=64.
Is there any built-in Matlab function to do that?

I don't think that there is a built-in function that does exactly that, but the following will do what you want:
A=randi(10,1,320);
B=randi(10,1,192);
C=zeros(1,length(A)+length(B));
for i=1:5
C(i:8:end)=A(i:5:end);
end
for i=6:8
C(i:8:end)=B(i-5:3:end);
end
Then the array C is the combined array.
Edit: Another way to do that, without for loops:
A=randi(10,1,320);
B=randi(10,1,192);
A_new=reshape(A,5,[]);
B_new=reshape(B,3,[]);
C=[A_new;B_new];
C=reshape(C,[1,numel(C)]);
In this solution, by specifying the third parameter in reshape(A,5,[]) to be [], we allow it to adjust the number of columns according to the length of A, given that the number of rows in the reshaped array is 5. In addition, numel(C) is the total number of elements in the array C. So this solution can be easily generalized to higher number of arrays as well.

Related

Calculating standard deviation on data stored in a cell array of cell arrays

I have a cell array A Mx3 in size where each entry contains a further cell-array Nx1 in size, for example when M=9 and N=5:
All data contained within in any given cell array is in vector format and of equal length. For example, A{1,1} contains 5 vectors 1x93 in size whilst A{1,2} contains 5 vectors 1x100 in size:
I wish to carry out this procedure on each of the 27 cells:
B = transpose(cell2mat(A{1,1}));
B = sort(B);
C = std(B,0,2); %Calculate standard deviation
Ultimately, the desired outcome would be, for the above example, 27 columns (9x3) containing the standard deviation results (padded with 0 or NaNs to handle differing lengths) printed in the order A{1,1}, A{1,2}, A{1,3}, A{2,1}, A{2,2}, A{2,3} and so forth.
I can do this by wrapping the above code into a loop to iterate over each one of the 27 cells in the correct order however, I was wondering if there was a clever cellfun or more succinct method to accomplish this particularly without the use of a loop?
You should probably realize that cellfun is essentially a glorified for loop over cells. There's simply extra error checking and all that to ensure that the whole thing works. In any case, yes it's possible to do what you're asking in a single cellfun call. Note that I am simply going to apply the same logic as you would have in a for loop with cellfun. Also note that because you're using cell arrays, you have no choice but to iterate over the entire master cell array. However, what you'll want to do is pad each resulting column vector in each output in the final cell array so that they all share the same length. We can do that with another two cellfun calls - one to determine the largest vector length and another to perform the padding operation.
Something like this could work:
% Step #1 - Sort the vectors in each cell array, then find row-wise std
B = cellfun(#(x) std(sort(cell2mat(x).'), 0, 2), A, 'un', 0);
% Step #2 - Determine the largest length vector and pad
sizes = cellfun(#numel, B);
B = cellfun(#(x) [x; nan(max(sizes(:)) - numel(x), 1)], B, 'un', 0);
The first line of code takes each element in A, converts each cell element into a N x 5 column matrix (i.e. cell2mat(x).'), we then sort each column individually with sort, then take the standard deviation row-wise. Because the output is ultimately a vector, we must make sure that the 'UniformOutput' flag is 0, or 'un=0'. Once we complete the standard deviation calculation, we determine the total number of elements for each resulting column vector for all cell elements, determine the largest size then use another cellfun call to pad these vectors so they all match the same size.
To finally get your desired output, you need to transpose the cell array, then unroll the elements in column major order. Remember that MATLAB accesses things in column major, so a common trick to get things in row-major (what you want) as opposed to column major is to first transpose, then unroll in column-major fashion to perform a row-major readout. Doing this in one line is tricky, so you'll need to not only transpose the cell array, you must use reshape to ensure that the elements are read out in row major format, but then ensuring that the result is placed in a row of cells, then call cell2mat so you can piece these vectors together. The final result should be a 27 column matrix where we have pieced all of these vectors together in a single row-wise fashion:
C = cell2mat(reshape(B.', 1, []));

Matlab: Refer to multiple, non consecutive elements

In Matlab is there any way to refer to multiple, non consecutive elements in a 1 dimensional array in the same line, eg. something like:
mean(strength(1:4,17:20))
I want to calculate the mean of 1st to 4th elements and the 17th to 20th elements in an array called strength etc. Except obviously a comma wouldn't work, because that would be double indexing, as if it was a matrix, when it's 1D. Is there another symbol you could use in place of the comma to do this, or would you need another technique to do this?
Like Andras says in his comment, you need a vector of the indices you wish to include in the calculation of the mean:
Just as you would reference the ith value of a vector with strength(i), you can have a vector instead of i, which will give you all of the specified values as another vector:
indexVector = [1:4, 17:20];
values = strength(indexVector);
This will give you a 1D vector of length 8 containing values 1:4 and 17:20 of the original strength vector, which would allow you to use mean(strength).
You can bypass writing these to variables, and just use:
mean(strength([1:4, 17:20]))

matlab rearrange (permute) string array

I have a string array:
size(entries)
ans =
1 19413
I would like to rearrange the array to 4853 rows and 4 columns:
output=permute(entries,[4853 4]);
but get following error:
Error using permute ORDER contains an invalid permutation index.
What is the (probably obvious thing) I am doing wrong? thanks
You currently have 19413 elements, yet you wish to reshape this into a 4853 x 4 matrix that consists of 4853 * 4 = 19412 elements. No function in the world will help you do this because the original and target amount of elements don't match - they're off by one element. If you remove one of the elements...say... the last one, then we're getting somewhere.
Supposing you made a mistake and included that extra element by accident, you don't use permute here, but you use reshape. The second argument to reshape is the amount of elements to spread out for each target dimension, and that's what you're looking for. First remove the extraneous element that appears at the end of the array, then reshape the matrix:
output = reshape(entries(1:end-1),[4853 4]);
I'm 3 years late, but here's to anyone still looking for an answer.
In your case as mentioned above, yes you should use reshape() while minding that you preserve the total number of elements.
You use permute() when you want to reorder the dimensionality of an n-dimensional (ND) matrix.
The ORDER parameter specifies the order of the columns.
For example, if matrix A is LxMxN, the following line would make it MxLxN.
A = permute(A,[2 1 3]);
Hope this clears things.

How can I extract a 1 dimentional row from a multidimentional matrix

I currently have a 3 dimensional matrix and I want to extract a single row (into the third dimension) from it by index (say matrix(2,1,:)). I initially anticipated that the result of this would be a 1 dimensional matrix however what I got was a 1 by 1 by n matrix. Usually this wouldn't be a problem but some of the functions I'm using don't like 3D matrices. For example see the problem replicated below:
threeDeeMatrix=rand(3,3,3);
oneDeeAttempt=threeDeeMatrix(1,1,:);
norm(oneDeeAttempt)
Which returns the error message:
Error using norm
Input must be 2-D.
This is because oneDeeAttempt is
oneDeeAttempt(:,:,1) =
0.8400
oneDeeAttempt(:,:,2) =
0.0700
oneDeeAttempt(:,:,3) =
0.7663
rather than [0.8400 0.0700 0.7663]
How can I strip these extra dimensions? The only solution I can come up with is to use a loop to manually copy the values but that seems a little excessive.
Using permute to rearrange the matrix
The solution (which I found in the final stages of asking this) is to use permute which rearranges the order of the dimensions (similar to a=a' for 2D matrices). Once the unit dimensions are last they are stripped from the matrix and it becomes 1 dimensional.
oneDee=permute(oneDeeAttempt,[3 1 2]) %rearrange so the previous third dimension is now the first
%the matrix is now 3 by 1 by 1 which becomes 3
Using squeeze to remove leading singleton dimensions
As pointed out by Luis Mendo squeeze will very simply remove these leading singleton dimensions without having to worry about which dimensions are non singleton
oneDee=squeeze(oneDeeAttempt);

Multiplying array columns by vector

I'm new to R and I am certain that this is simple yet I can't seem to find an answer. I have an array [36,21,12012], and I need to multiply all of the columns by a vector of the same length to create a new array of the same dimensions.
If v is your vector and a is your array, in your case it would be as simple as v * a, because arrays are built column-wise. But in general, you would use sweep. For example to multiply along the rows, sweep(a, MARGIN=2, STATS=v, FUN='*').

Resources