combining the arrays - arrays

I have written a code and i'm pretty much stuck.
In the following code, i have split the complete image into a 3*3 block.
Each of the child (1-8) you can see, say i alter them in that child(1-8) array only.
Is there a method to combine these array (mother & child 1-8) to get the complete image back with the alteration that i've already made
pd_x=imread(name_doc);
[pd_m,pd_n]=size(pd_x);
di_m=pd_m;
di_n=pd_n;
pd_rv=ceil(pd_m/3);
pd_cv=ceil(pd_n/3);
mother1=pd_x(1:pd_rv,1:pd_cv);
child1=pd_x(1:pd_rv,pd_cv:(pd_cv+pd_cv));
child2=pd_x(1:pd_rv,(pd_cv+pd_cv):pd_n);
child3=pd_x(pd_rv:(pd_rv+pd_rv),1:pd_cv);
child4=pd_x(pd_rv:(pd_rv+pd_rv),pd_cv:(pd_cv+pd_cv));
child5=pd_x(pd_rv:(pd_rv+pd_rv),(pd_cv+pd_cv):pd_n);
child6=pd_x((pd_rv+pd_rv):pd_m,1:pd_cv);
child7=pd_x((pd_rv+pd_rv):pd_m,pd_cv:(pd_cv+pd_cv));
child8=pd_x((pd_rv+pd_rv):pd_m,(pd_cv+pd_cv):pd_n);

The syntax for concatenation is the following:
A = [12 62 93 -8 22; 16 2 87 43 91; -4 17 -72 95 6]
A =
12 62 93 -8 22
16 2 87 43 91
-4 17 -72 95 6
Taken from http://www.mathworks.com/help/techdoc/math/f1-84864.html
I've also made a basic example, defining first v,v2 and v3:
>> v
v =
1 2
>> v2
v2 =
3 4
>> v3
v3 =
5 6
I do the following concatenation, the result will be...
>> m = [v v2 v3; v3 v2 v];
>> m
m =
1 2 3 4 5 6
5 6 3 4 1 2
Hope it helps you understand how it works!!

If you used the method I've posted on this answer and still has the 4d matrix created, just do this:
mother1 = permute( mat4d, [ 1 3 2 4 ] );
mother1 = reshape( mother1, [ pd_rv pd_cv ] );
But pd_rv and pd_cv should be calculated with floor, and not with ceil, shouldn't they?

Related

How can I need multiply group of elements instead of one element in matrices multiplication

Suppose I have a matrix of dimension [4x4], and a vector of [16x1], I need to multiply every 4 element in the vector in one element in the matrix, (instead of multiplying element in row by element in vector), how can I do that using loop ?
For example here below, the results of the first four elements in the resulted vector as shown in the below example, then the same thing for the second, third and fourth rows in the matrix. :
So the results in that example is supposed to be [16x1]
Thank you
Using kron you can use this one-liner:
%A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
%v = [2 2 2 2 0 0 0 0 1 1 1 1 3 3 3 3].';
sum(kron(A,ones(4,4)).'.*v).'/4
I use the kronecker tensor product to "replicate" 4x4 time the A matrice. After that it's pure algebra.
This is just matrix multiplication in disguise... If your tall vector was a matrix of the same size as the matrix shown, where each highlighted block is a row, it's matrix multiplication. We can set this up, then reshape back into a vector.
You can use indexing to turn this into simple matrix multiplication. A question I answered already today details how the below indexing works using bsxfun, then we just reshape at the end:
% Setup
A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
v = [2 2 2 2 0 0 0 0 1 1 1 1 3 3 3 3].';
% Matrix mutliplication
r = numel(v)/size(A,1);
b = A * v( bsxfun( #plus, (1:r:numel(v)).', 0:r-1 ) );
% Make result a column vector
b = reshape( b.', [], 1 );
See if this is what you want:
A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
v = [2 2 2 2 0 0 0 0 1 1 1 1 3 3 3 3].';
r = reshape(sum(bsxfun(#times, permute(A, [3 2 1]), permute(reshape(v, 1, [], size(A,2)), [2 3 1])), 2), [], 1);
which gives
r =
17
17
17
17
41
41
41
41
65
65
65
65
89
89
89
89
There are details that I assumed, but this shoudl do the trick:
A=reshape(1:16,4,4).';
b=repelem([2,0,1,3],1,4).';
c=[];
for row=1:size(A,1)
c=[ c; sum(reshape(repelem(A(row,:),4).*b.',4,[]),2)];
end
I am assuming here that your demo for the vector is just a bad example and that you wont have repeated values, otherwise an easier version can be achieved by just not doing 3/4ths of the multiplications.
If you do not have access to repelem, have a look at alterative codes that do the same thing:Element-wise array replication in Matlab

Matlab: extract values from vector A, based on values in vector B

A = [5 10 16 22 28 32 36 44 49 56]
B = [2 1 1 2 1 2 1 2 2 2]
How to get this?
C1 = [10 16 28 36]
C2 = [5 22 32 44 49 56]
C1 needs to get the values from A, only in the positions in which B is 1
C2 needs to get the values from A, only in the positions in which B is 2
You can do this this way :
C1 = A(B==1);
C2 = A(B==2);
B==1 gives a logical array : [ 0 1 1 0 1 0 1 0 0 0 ].
A(logicalArray) returns elements for which the value of logicalArray is true (it is termed logical indexing).
A and logicalArray must of course have the same size.
It is probably the fastest way of doing this operation in matlab.
For more information on indexing, see matlab documentation.
To achieve this with an arbitrary number of groups (not just two as in your example), use accumarray with an a anoynmous function to collect the values in each group into a cell. To preserve order, B needs to be sorted first (and the same order needs to be applied to A):
[B_sort, ind_sort] = sort(B);
C = accumarray(B_sort.', A(ind_sort).', [], #(x){x.'});
This gives the result in a cell array:
>> C{1}
ans =
10 16 28 36
>> C{2}
ans =
5 22 32 44 49 56

Matlab: reshape 3-dimensional array into 2-dimensional array

I have a 3x3x2000 array of rotation matrices that I need to transform into a 2000x9 array.
I think I have to use a combination of permute() and reshape(), but I don't get the correct output order.
This is what I need:
First row of 3x3 array needs to be columns 1:3 in the output
Second row of 3x3 array needs to be columns 4:6 in the output
Third row of 3x3 array needs to be columns 7:9 in the output
I have tried all possible combinations of numbers 1 2 3 in the following code:
out1 = permute(input, [2 3 1]);
out2 = reshape(out1, [2000 9]);
But I always end up with the wrong order. Any tips for a Matlab newbie?
How about a simple for-loop?
for i=1:size(myinput,3)
myoutput(i,:)=[myinput(1,:,i) myinput(2,:,i) myinput(3,:,i)];
% or
% myoutput(i,:)=reshape(myinput(:,:,i),[],9);
end
It's not simple as using permute and reshape, but it is transparent and easier for debugging. Once everything in your program runs perfectly, you can consider to rewrite such for-loops in your code...
You had a mix-up in your permute
a = reshape(1:9*6, 3, 3, []);
a is a 3x3x6 matrix, each
a(:,:,i) = 9*(i-1) + [1 4 7
2 5 8
3 6 9];
So
out1 = permute(a, [3,1,2]);
out2 = reshape(out1, [], 9);
Or in one line
out3 = reshape(permute(a, [3,1,2]), [], 9);
So
out2 = out3 =
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 26 27
28 29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44 45
46 47 48 49 50 51 52 53 54

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

Generating matlab array from two arrays

I have two large arrays which I will illustrate using the following examples.
The first array A is:
[ 1 21;
3 4;
4 12;
5 65 ];
The second array B is:
[ 1 26;
31 56;
4 121;
5 54 ];
I want to obtain the final array C as following:
[ 1 21 26;
4 12 121;
5 65 54];
i.e. use the common elements of first column from A and B to sieve out the rows I want to extract from arrays A and B and generate C.
Use the two-output vesion of ismember:
[ii jj] = ismember(A(:,1), B(:,1));
C = [ A(ii,:) B(jj(ii),2) ];
Note that in the second line ii is a logical index, whereas jj(ii) is a standard (integer) index.
bsxfun approach -
%// Slightly bigger and not-so-straightforward example to avoid any confusion
A =[ 1 21;
3 4;
4 12;
8 10
5 65]
B = [ 1 26;
31 56;
4 121;
5 54
9 99
8 88]
binmat = bsxfun(#eq,A(:,1),B(:,1).');%//'
[v1,v2] = max(binmat,[],2);
C = [A(any(binmat,2),:) B(nonzeros(v1.*v2),2:end)]
Output -
A =
1 21
3 4
4 12
8 10
5 65
B =
1 26
31 56
4 121
5 54
9 99
8 88
C =
1 21 26
4 12 121
8 10 88
5 65 54

Resources