matlab rearrange (permute) string array - arrays

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.

Related

N-dimensional array indexing in Matlab : find array in middle

I am working with N-dimensional array and have a problem with the array indexing. I have a task to find an (N-1)-dimensional array in the middle N-dimensional array.
Let me explain in detail with 3D array. A is a 3-dimensional array that has split into groups. In each group, there are b - number of 2-dimensional arrays in the group. I have simulated it as:
b=5;
A=rand(2,2,20);
groups = reshape(A, size(A,1), size(A,2),b, []);
groups is 4-dimensional array, the 4-th dimension is a number of groups ( here it 4).
To find a middle in each group I have added the following loop:
for ii=1:size(groups,4) % Loop over all groups/slices
middle(:,:,ii) = groups(:,:,(w-1)/2+1,ii); % 1 2 3 4 5 : the middle is 3
end
middle is 3-dimensional array that collects middle array in each group.
As you see in my example I have used b=5( odd number). My problem is with even number b.
I have tried to implement it as ( rewrite the loop above);
l=rem(w,2);
for ii=1:size(groups,4) % Loop over all groups/slices
if l==1
middle(:,:,ii) = groups(:,:,(w-1)/2+1,ii);
else
middle(:,:,ii) = groups(:,:,(w-1)/2,ii);
end
end
But it doesn't work. Matlab gives me an error in the line l=rem(w,2);
Could you suggest to me how I can fix it? Is there another way to implement it?
You should use floor of ceil to round the index to whichever element you want:
middle_index = floor((w-1)/2+1);
Here, the middle of 4 is 2, using ceil you’d pick index 3.
Next, you can extract the arrays in a single indexing operation:
middle = groups(:,:,middle_index,:);
Finally, use squeeze or reshape to get rid of the 3rd index:
middle = squeeze(middle);

Matlab: How to combine two vectors in one

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.

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

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

array1(1:A)=array2(1:C,D) Fortran 90 what is the function of the colon

I am not 100% what the role of the 1: is here. At which index to start the copy? But then why not two such parameters for the rank 2 array?
To be a little more explicit:
In Fortran90 and up you access a single array value by giving a single index, and access a subarray (a window of the array) by giving a range of indices separated by a colon.
a(1) = 0.
a(2:5) = (/3.14,2.71,1.62,0./)
You can also give a step size.
a(1:5:2) = (/0,2.71,0./)
And finally, you can leave out values and a default will be inserted. So if a runs from index 1 to 5 then I could write the above as
a(::2) = (/0,2.71,0./)
and the 1 and 5 are implied. Obviously, you shouldn't leave these out if it makes the code unclear.
With a multidimensional array, you can mix and match these on each dimension, as in your example.
You're taking a slice of array2, namely the elements in the D'th column from row 1 to C and putting them in the slice of array1 which is elements 1 through A
So both slices are 1-dimensional arrays
Slice may not be the correct term in Fortran

Resources