how to separate matrices in an array? - arrays

I want to apply a function for each four matrices, for example start from 1:4 then 5:8 then 9:12 ;13:16,17:20,21:24 and so on in my real data
k = 24; n=3; m = 4
ary=array(1:24, c(n,m,k))
str(ary)
int [1:3, 1:4, 1:24] 1 2 3 4 5 6 7 8 9 10 ...
for each four matrices in ary fun {.........}

If you want to use a for-loop as suggested in the question, just do the following:
Seq <- seq(1, 24, 4)
for (i in Seq){
## i is 1, 5, 9, 13, 17, 21
ary[ , , i:(i+3)] #get's you the array with just four matrices
# do something ...
}

Related

renumbering values to be consecutive

I am working with bioinformatics data. I have a sequence of repetitive numbers that are nonconsecutive in nature. I am trying to find a simple way to renumber them so that they are consecutive.
Ex:
old: 1 1 1 2 2 3 3 5 5 7 7 7 9 9
Desire change
new: 1 1 1 2 2 3 3 4 4 5 5 5 6 6
I'm using R.
One way you can solve this is by using a for loop and keeping track of the current number you are inserting and the value you are replacing.
vec <- c(1, 1, 1, 2, 2, 3, 3, 5, 5, 7, 7, 7, 9, 9)
curr <- vec[1]
rep <- vec[1]
for(i in 1:length(vec)) {
if(vec[i] > rep) {
rep <- vec[i]
curr <- curr + 1
}
if(vec[i] > curr) {
vec[i] <- curr
}
}
# Print the results
for(val in vec) {
print(val)
}
This solution assumes that the numbers are already sorted. If not, you can use the sort method.

Reshape the array along the reverse dimensions

>> A = [ 1 2 3 3 4 5 5 6 7 7 8 9 ];
>>
>> B = reshape(A, 2, 2, 3)
B(:,:,1) =
1 3
2 3
B(:,:,2) =
4 5
5 6
B(:,:,3) =
7 8
7 9
Since reshape can only change the size of the given array in the way of preserving the linear indices, however I would like to reshape the array along the reverse dimensions.
For example, convert A into
>> C = reverse-reshape(A, 2, 2, 3) % not required to be only one function
C(:,:,1) =
1 3
5 7
C(:,:,2) =
2 4
6 8
C(:,:,3) =
3 5
7 9
Is there any better method than writing loops and fill numbers one by one in version R2017b?
You would first reshape with the dimensions in reverse order, then swap the first and third dimensions with permute to reorder the elements so that they are populated in reverse order:
>> B = permute(reshape(A, 3, 2, 2), [3 2 1])
B(:,:,1) =
1 3
5 7
B(:,:,2) =
2 4
6 8
B(:,:,3) =
3 5
7 9
To do this in general independent of the matrix dimensions and assuming it is a 3D matrix, declare an array called dims that contains the output desired matrix size, reverse the elements and supply this into reshape:
dims = [2 2 3];
B = permute(reshape(A, fliplr(dims)), [3 2 1]);
fliplr reverses the elements in a matrix horizontally.

Given an index of choices for each column, construct a 1D array from a 2D array

I have a 2D array such as:
julia> m = [1 2 3 4 5
6 7 8 9 10
11 12 13 14 15]
3×5 Array{Int64,2}:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
I want to pick one value from each column and construct a 1D array.
So for instance, if my choices are
julia> choices = [1, 2, 3, 2, 1]
5-element Array{Int64,1}:
1
2
3
2
1
Then the desired output is [1, 7, 13, 9, 5]. What's the best way to do that? In my particular application, I am randomly generating these values, e.g.
choices = rand(1:size(m)[1], size(m)[2])
Thank you!
This is probably the simplest approach:
[m[c, i] for (i, c) in enumerate(choices)]
EDIT:
If best means fastest for you such a function should be approximately 2x faster than the comprehension for large m:
function selector(m, choices)
v = similar(m, size(m, 2))
for i in eachindex(choices)
#inbounds v[i] = m[choices[i], i]
end
v
end

Matlab - Multidimensional Arrays Confusion

I have this 4 integer value output
example:
out = [ 8 7 6 5 ]
I would to save these 4 values in one place (in row i column j)
Such that when I try to access
array(i,j) I get the 4 values 8 7 6 5
I'm failing miserably. Any help is appreciated
If the number of values is the same for all i, and j, use a 3D array of size MxNx4:
array(1,1,:) = [8 7 6 5];
array(1,2,:) = [11 12 13 14];
You could imagine the four numbers are stacked on top of each other along a "depth" dimension in row i and column j.
array(i,j,:) gives the 1x1x4 array containing the four numbers corresponding to i, j. When accesing each group of four numbers, you may want to use squeeze to remove the singleton dimensions, i.e. to obtain the result as a column vector:
>> squeeze(array(1,1,:))
ans =
8
7
6
5
If the number of values may be different for each i and j, use a 2D cell array:
array{1,1} = [8 7 6 5];
array{1,2} = [11 12];
So array{i,j} gives the vector:
>> array{1,1}
ans =
8 7 6 5

Vectorized Reshaping of Columns in an Array

I have an array A, and want to reshape the last four elements of each column into a 2x2 matrix. I would like the results to be stored in a cell array B.
For example, given:
A = [1:6; 3:8; 5:10]';
I would like B to contain three 2x2 arrays, such that:
B{1} = [3, 5; 4, 6];
B{2} = [5, 7; 6, 8];
B{3} = [7, 9; 8, 10];
I can obviously do this in a for loop using something like reshape(A(end-3:end, ii), 2, 2) and looping over ii. Can anyone propose a vectorized method, perhaps using something similar to cellfun that can apply an operation repeatedly to columns of an array?
The way I do this is to look at the desired indices and then figure out a way to generate them, usually using some form of repmat. For example, if you want the last 4 items in each column, the (absolute) indices into A are going to be 3,4,5,6, then add the number of rows to that to move to the next column to get 9,10,11,12 and so on. So the problem becomes generating that matrix in terms of your number of rows, number of columns, and the number of elements you want from each column (I'll call it n, in your case n=4).
octave:1> A = [1:6; 3:8; 5:10]'
A =
1 3 5
2 4 6
3 5 7
4 6 8
5 7 9
6 8 10
octave:2> dim=size(A)
dim =
6 3
octave:3> n=4
n = 4
octave:4> x=repmat((dim(1)-n+1):dim(1),[dim(2),1])'
x =
3 3 3
4 4 4
5 5 5
6 6 6
octave:5> y=repmat((0:(dim(2)-1)),[n,1])
y =
0 1 2
0 1 2
0 1 2
0 1 2
octave:6> ii=x+dim(1)*y
ii =
3 9 15
4 10 16
5 11 17
6 12 18
octave:7> A(ii)
ans =
3 5 7
4 6 8
5 7 9
6 8 10
octave:8> B=reshape(A(ii),sqrt(n),sqrt(n),dim(2))
B =
ans(:,:,1) =
3 5
4 6
ans(:,:,2) =
5 7
6 8
ans(:,:,3) =
7 9
8 10
Depending on how you generate x and y, you can even do away with the multiplication, but I'll leave that to you. :D
IMO you don't need a cell array to store them either, a 3D matrix works just as well and you index into it the same way (but don't forget to squeeze it before you use it).
I gave a similar answer in this question.

Resources