Matrix patterns - matlab

I have two 9x9 matrices, A and B.
I would like to create a large matrix C with the following pattern
A B B B B B
B A B B B B
B B A B B B
B B B A B B
B B B B A B
B B B B B A
As you can see, the A matrices are on the diagonal, the B are everywhere else. I'm trying to create a code so that this pattern continues no matter how great the dimensions are.
E.g. 10 matrices x 10 matrices still has matrix A along the diagonal and B's everywhere else.
Best to use horzcat and vertcat or something else like blkdiag? I'd rather not convert these matrices to cells as matrix A and B already contain information.
Thank you everyone for taking the time to read.

How about (refined)
maskcell = repmat( {ones(size(A))}, 1, 10 );
maskdiag = blkdiag( maskcell{:} );
AA = repmat( {A}, 1, 10 );
AD = blkdiag( AA{:} );
BB = repmat( B, 10, 10 );
C = BB .* (maskdiag == 0) + AD
Following on from the entirely valid comments below, I added the 'mask' to ensure that the correct pieces are selected from C.

C=B(~eye(size(B)))+A(eye(size(A))) should get you what you want. Could be a faster way to combine the use of eye though...

kron(eye(10), A) + kron(~eye(10), B)

Related

Is there a way to mask a matrix in matlab based on elements in an array?

Suppose I have a matrix a = [1,2,3;4,1,2;3,4,2].
I need to create a logical matrix which is 1 wherever there is an element of b in a. The equivalent of a==4 | a==1 if my array b is a small one like [1,4].
I know one way to do this is:
b = [1,4];
c = logical(zeros(size(a)));
for i=b
c = c | a==i;
end
This solution may not scale well if a and b are large. Is there a cleaner way to do it for larger arrays?
I was hoping a == b would give me what i wanted, but it doesn't.
You can use ismember to output a logical array which is true whenever an element of the first input is a member of the second input. The output is the same size as the first input.
c = ismember( a, b );
In your example:
a = [1,2,3;
4,1,2;
3,4,2];
b = [1,4];
c = ismember( a, b );
% >> c =
% [1,0,0;
% 1,1,0;
% 0,1,0]

MATLAB: Compare matrices built with repelem and repmat

I have an array a of size ZxW.
Z = 20;
W = 30;
A = 40; %will be used below
size(a)
20 30
Then I apply to a two different transformations, and then after those I delete a and I cannot go back to it.
First transformation:
b = repelem(a(:,1),A,A);
Second transformation:
c = repmat(a,[1,1,A,A]);
d = c(:,1,:,:);
After those transformations and deleting a (which cannot be used for the following), I want to compare d and b using
assert( isequal(b,f) )
Where f is a transformation of d that makes the assertion true.
My first idea was a simple reshape:
f = reshape(squeeze(d),[Z*A,A]);
Which does not work as repelem and repmat move entries differently. How can I do this?
Thanks for the attention.
Sincerely
Luca
EDIT: changed
c = repmat(a,[A,A]);
with
c = repmat(a,[1,1,A,A]);
The answer (by Jan Simon) is:
f = reshape(permute(d, [3,1,4,2]), [Z*A,A]);
isequal(b, f) % 1: equal
Thanks for the help.
Luca
NOTE: This solution is obsoleted with the edited question, please refer to the other solutions posted.
Look closely at what the pattern of b and d are:
b = [1 1 1 2 2 2 3 3 3].'
d = [1 2 3 1 2 3 1 2 3].'
Hence, the transformation f can be:
f = reshape(d, [A, A]).'
f = f(:)
This will convert d to be exactly b or vice versa.

Matlab - matrix addition in for loop

I have a 7x21 matrix called A. Within this matrix there are three equally sized 7x7 submatrices. I call them B,C and D, where B = A(:,1:7), C = A(:,8:14) and D = A(:,15:21).
How can I produce a matrix E which is also 7x7 matrix where simply B, C and D are added up, i.e. E = B+C+D.
Thanks a lot for your help!
Generic code to get such an output -
N = 3; %// Number of submatrices
[m,n] = size(A) %// Get size [no. of cols must be multiple of N
E = reshape(sum(reshape(A,m*n/N,[]),2),m,n/N)
I don't see what's going to be more straightforward and concise than
E = A(:,1:7) + A(:,8:14) + A(:,15:21)
Unless you need an expression that generalizes in some way you're not describing...

Efficient way of mapping similar inputs to similar outputs

Is there a efficient way of approaching this particular problem in matlab.
I am trying to map this matrix or possible array BeansRice (see below)
Beans={0:1,0:1,0:2,0:2,0:2,0:2,0:1,0:1,0:2,0:2}
[a b c d e f g h i j ] = ndgrid(Beans{:})
BeansRice = [a(:) b(:) c(:) d(:) e(:) f(:) g(:) h(:) i(:) j(:)]
into a matrix/array BR (see below)
BR=[abc, de, fg, hij];
where if columns a, b and c each have values 0 (ties preference), I have preference for c>b>a. If all columns a, b and c each have values 1 (ties no preference), BR(1)=1. If columns a and b have values 0 and column c has value 2, BR(1)=2. If columns a and b have values 1 and column c has value 2, BR(1)=1.
I have an if function with indexing but I was thinking if it is possible to improve it, using the rank/order of the values in the matrix to break ties. Looking for a more efficient process as this is only a sub of a large problem.
You can use logical indexing instead of if conditions. For example
BR1(a==1 & b==1 & c==1)=1
BR1(a==0 & b==0 & c==2)=2
BR1(a==1 & b==1 & c==2)=1
...
then process the other parts, BR2(d==... & e>...)=##, then concatenate to obtain what you need
BR=[BR1(:) BR2(:) ...]
etc...

Image shuffling puzzle creation[Modified Question]

I have 3 images E1,E2,E3 of equal size 256*256*3. Now by some any arbitrary rule, i want to create a jig saw puzzle which should be a reversible operation. The resultant image E would then be of unequal size,preferably. The question is explained with a small example to show the objective for simplicity:
How to tackle the unequal sized of the resultant matrix E(image format) and how to achieve this? Please help
Example :
size(E1)=size(E2)=3*3
E1=( 1 2 3
4 5 6
7 8 9 )
E2 = ( a b c
d e f
g h i)
E = ( 1 2 3 a b c
4 5 6 d e f
7 8 9 g h i)
[r c]=size(E);
But the scheme for arrangement should be such that r/c = number of matrices involved in the operation. This however would apply for even dimensioned matrix.
So, the same operation is desired for RGB image.
Modified Question : In the above case, if E=[E1;E2] then how is it possible to extract/get back E1 and E2 from E?
I do not understand what you are doing, but you can accomplish what you have in the example easily using reshape:
E1_reshaped = reshape(e1, 1, []);
E2_reshaped = reshape(e2, 1, []);
E = [E1_reshaped; E2_reshaped];