how do I combine only the vectors - Matlab - arrays

How do I combine all the vectors in small subsets of vectors in Matlab?
a= [5 6 7] b = [8 9 10] c=[11 12 13] d=[14 15 16] e=[17 18 19]
a combine with b and c:
Outcome:
M1= [ 5 6 7 8 9 10 11 12 13]
a with b and d:
M2 = [5 6 7 8 9 10 14 15 16]
and so on .....

This answer covers the case for an arbitrary number of vectors. The vectors are assumed to be row vectors of equal length.
Let your example data be defined as
a = [5 6 7]; b = [8 9 10]; c = [11 12 13]; d = [14 15 16]; e = [17 18 19];
vectors = {a, b, c, d, e}; %// cell array with any number of row vectors of equal size
n = 3; %// desired subset size
Then: generate all combinations of indices, use that to index into vectors, concatenate into one big row vector, and reshape that to obtain the desired result:
combs = nchoosek(1:numel(vectors), n);
result = reshape([vectors{combs.'}], numel(vectors{1})*n, []).';
This gives a matrix whose first row is your M1, second row is M2 etc:
result =
5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 14 15 16
5 6 7 8 9 10 17 18 19
5 6 7 11 12 13 14 15 16
5 6 7 11 12 13 17 18 19
5 6 7 14 15 16 17 18 19
8 9 10 11 12 13 14 15 16
8 9 10 11 12 13 17 18 19
8 9 10 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19

You can use the cat function:
res = cat(2,a,b,c);
or simply the [] syntax:
res = [a b c];
In both cases, res will contain [5 6 7 8 9 10 11 12 13].
Best,

Use nchoosek.
a = [5 6 7]; b = [8 9]; c = [11 12 13]; d = [14 15 16]; e = [17 18 19];
N = 3;
x = {a,b,c,d,e};
y = nchoosek(x,N);
And you have all the combination of your arrays taken N at a time in a cell array. Each row i of the cell x is a combination, so to have it back as a row vector just do
horzcat(y{i,:})
Or, if you want to get them all and put them in a cell array of size n_combs
n_combs = size(y,1);
out = cell(0,n_combs);
for i = 1 : n_combs
out{i} = horzcat(1, y{i,:});
end
There is no constraint on the size of the arrays that you want to combine, e.g., you can combine
a = [5 7]; b = [8 9]; c = [11]; d = [20 14 15 16]; e = [17 18 19];
However, if you must put together all the combination in a matrix, then the arrays have to be of the same size. In this case Luis Mendo's answer does the job.
Finally, if repetitions are allowed use nmultichoosek instead of nchoosek.

Related

Is there a way to rotate 3D arrays in Julia?

I am trying to rotate a 3D array in julia as if it represents a physical object in 3D space. Essentially, I want to know if there is a way to rotate an array by increments of 90 degrees along the x-, y-, and/or the z-axis.
In 2D it would be something like this if I were to rotate counter-clockwise...
1 2 3 3 6 9
4 5 6 -----> 2 5 8
7 8 9 1 4 7
I would want the same logic to apply in 3D as well.
Any help is appreciated.
For two-dimensional Matrices you have functions such as rotl90, rotr90 and rot180. Those can be combined with mapslices to get the desired effect. For an example below is a rotation over dimensions 1 and 2 for each cut of array in the dimension 3.
julia> A=collect(reshape(1:27,3,3,3))
3×3×3 Array{Int64,3}:
[:, :, 1] =
1 4 7
2 5 8
3 6 9
[:, :, 2] =
10 13 16
11 14 17
12 15 18
[:, :, 3] =
19 22 25
20 23 26
21 24 27
julia> mapslices(rotr90,A,dims=[1,2])
3×3×3 Array{Int64,3}:
[:, :, 1] =
3 2 1
6 5 4
9 8 7
[:, :, 2] =
12 11 10
15 14 13
18 17 16
[:, :, 3] =
21 20 19
24 23 22
27 26 25

Take 1D slice between two points in 2D MATLAB array

I'm trying to write a function that given 2 points in a 2D MATLAB array will return a 1D array of the elements connecting the points.
So arr=[1 2 3 4 5;6 7 8 9 10;11 12 13 14 15;16 17 18 19 20;21 22 23 24 25 ]
and the points between arr(4,2) and arr(1,5) would be returned as [17 13 9 5].
For example, although I'm fine with points being interpolated if required.
If it helps this is how I do it in Python
length = int(np.hypot(x1-x0, y1-y0))
xx, yy = np.linspace(x0, x1, length), np.linspace(y0, y1, length)
zi = arr[xx.astype(np.int), yy.astype(np.int)]
You could use interp2:
lets say we'd like to sample 20 evenly space points from (1.3, 2.4) to (4.6, 3.5)
arr=[ 1 2 3 4 5;
6 7 8 9 10;
11 12 13 14 15;
16 17 18 19 20;
21 22 23 24 25 ]
[x, y] = meshgrid(1:5,1:5)
xx = linspace (1.3, 4.6, 20)
yy = linspace (2.4, 3.5, 20)
interp2(x,y,arr, xx,yy)
gives:
8.30000000000000
8.76315789473684
9.22631578947368
9.68947368421053
10.15263157894737
10.61578947368421
11.07894736842105
11.54210526315790
12.00526315789474
12.46842105263158
12.93157894736842
13.39473684210526
13.85789473684211
14.32105263157895
14.78421052631579
15.24736842105263
15.71052631578947
16.17368421052632
16.63684210526316
17.10000000000000
You can see how the line follows your mesh:
mesh(x,y,arr)
hold on
plot3(xx,yy,interp2(x,y,arr, xx,yy))

Matlab: repeat and concatenate rows and cols into new array

I have two 4-by-4 arrays:
a1 = [ 1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16 ]
a2 = [ 17 18 19 20; 21 22 23 24; 25 26 27 28; 29 30 31 32 ]
I need to create 16-by-8 array C:
1 2 3 4 17 18 19 20
1 2 3 4 21 22 23 24
1 2 3 4 25 26 27 28
1 2 3 4 29 30 31 32
5 6 7 8 17 18 19 20
5 6 7 8 21 22 23 24
5 6 7 8 25 26 27 28
5 6 7 8 29 30 31 32
9 10 11 12 17 18 19 20
9 10 11 12 21 22 23 24
9 10 11 12 25 26 27 28
9 10 11 12 29 30 31 32
13 14 15 16 17 18 19 20
13 14 15 16 21 22 23 24
13 14 15 16 25 26 27 28
13 14 15 16 29 30 31 32
The left half (from 1st to 4th column) of the result array C should repeat 4 times i-th row of the array a1, the right half (from 5th to 8th column) should repeat 4 times the array a2.
Below is my code.
p=4
n=4
for i=1:n
b=n*i;
a=n*(i-1)+1;
for j=1:p
for k=a:b
C(k,j)=a1(i,j);
end;
end;
end;
for i=1:n
b=n*i;
a=n*(i-1)+1;
for j=p+1:2*p
l=1;
for k=a:b
C(k,j)=a2(l,j-p);
l=l+1;
end;
end;
end;
C;
size_C=size(C)
Question. Is it possible to create result array C without for-loop? Which functions can I use?
Yes it's possible.
One way of doing it is by using kron and repmat
C = [ kron(a1, ones(4,1)) repmat(a2, 4, 1)]
Perhaps the 4 should be derived from the size of one of the matrixes
You can use ndgrid to generate the row indices and then concatenate:
[ii, jj] = ndgrid(1:size(a2,1), 1:size(a1,1));
C = [a1(jj,:) a2(ii,:)];
With focus on performance, here's one using reshape and repmat -
% Store sizes
M = size(a1,1);
N = size(a2,1);
% Get the replicated version for a1 and a2 separately
parte1 = reshape(repmat(reshape(a1,1,M,[]),[N,1,1]),M*N,[])
parte2 = repmat(a2,[M,1]);
% Do columnar concatenatation for final output
out = [parte1 parte2]
Sample run on a generic case -
a1 = % 3 x 4 array
5 2 6 9
7 4 7 6
9 8 6 1
a2 = % 2 x 5 array
7 7 1 9 2
6 8 8 7 9
out =
5 2 6 9 7 7 1 9 2
5 2 6 9 6 8 8 7 9
7 4 7 6 7 7 1 9 2
7 4 7 6 6 8 8 7 9
9 8 6 1 7 7 1 9 2
9 8 6 1 6 8 8 7 9

Extract equally spaced subarrays from an array

I have an array:
v = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
I want to extract multiple arrays of length 3 equally spaced by 6 elements, starting at the fifth element of v, and then combine them together:
v1 = [5 6 7];
v2 = [11 12 13];
v3 = [17 18 19];
v_combined = [5 6 7 11 12 13 17 18 19];
Are there any simple ways to do this without using a for loop?
You can do it using logical indexing. You need to create an index mask like this
idx = [0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0]
which you can create like this:
idx = false(size(v))
k = 5
idx(k:end) = ~mod(floor((0:numel(v)-k)/3),2)
And finally
v_combined = v(idx)
In general for m elements spaces by n elements starting from k you can use
k=5;
m=3;
n=6;
I=1:numel(v);
v_combined = v((I>=k) & mod(I-k,n)<m)

What is the meaning of the addition at the end of this array declaration?

I'm tasked with implementing an algorithm which was supplied as Matlab (which none of us have any experience with) into our c++ application.
There is an array declared as such:
encrypted = [18 10 20 13 6 25 21 13 17;
2 26 4 29 22 9 5 29 1;
19 11 21 12 7 24 20 12 16;
% ... many rows like this ...
13 21 11 18 25 6 10 18 14]+1;
What is the semantic meaning of the +1 at the end of the array declaration?
Simply adding 1 to each entry:
>> [1 2 3; 4 5 6]
ans =
1 2 3
4 5 6
>> [1 2 3; 4 5 6] + 1
ans =
2 3 4
5 6 7
If you have MATLAB around, you could have figured that out by just trying. If you do not, I hope you have a very clear picture of what the code is doing and write a good test suite, since you won't be able to compare your new code's output to the MATLAB one.
The +1 means that all elements of the written matrix will be increased by one.
Example
out = [1 2;
3 4] + 1;
disp(out)
2 3
4 5

Resources