1
votes

Unfortunately my programming skills are not that advanced and I really need to vectorize some loops to finish my thesis. I tried to make things really clear and simple and I have the following two questions in matlab:

1. If we have a 5x5 matrix A and we want to set the diagonal elements of this matrix to the diagonal of a matrix B, apart from diag(A)=diag(B) we could use :

    for i=1:5

    B(i,i)=A(i,i)

    end

Now if I want to vectorize this I can not use:

    i=1:5
    B(i,i)=A(i,i)

In that way we assign each combination from 1:5. So, in the end we asign each element of A equal to B and not the diagonal. Is there some way that we could assign each identical pair of (i,i)? I tried :

    i=1:5
    j=1:5
    B(i,find(j==i))=A(i,find(j==i))

But still does not work. I repeat I know the diag property but Im only interested on the particular problem.

2.

A similar problem is the fillowing. b=[ones(2,2) ones(2,2)*2 ones(2,2)*3 ones(2,2)*4] ;

    a         = zeros(8,12);

    for i=1:4             

    a((i-1)*2+1:(i)*2,(i-1)*3+1:(i)*3) =  [8*ones(2,1) b(:,[2*(i-1)+1 2*i])];

    end

Thank you for your time and for your help.

2
What is your second problem exactly? Can you explain it more clearly?user3667217

2 Answers

1
votes

Let's bring some mask magic, shall we!

Problem #1

mask = eye(size(A))==1
A(mask) = B(mask)

For creating the mask, you can also use bsxfun -

N = size(A,1)
bsxfun(@eq,[1:N]',1:N)

Or finally, you can use linear indexing -

N = size(A,1)
A(1:N+1:N^2) = B(1:N+1:N^2)

Sample run -

>> A
A =
     5     2     9     6     5
     9     1     6     2     2
     9     7     5     3     9
     4     5     8     8     7
     7     5     8     1     8
>> B
B =
     5     5     2     8     2
     1     1     6     5     2
     7     8     5     4     4
     1     8     9     8     8
     1     7     6     1     8
>> mask = eye(size(A))==1;
>> A(mask) = B(mask)
A =
     5     2     9     6     5
     9     1     6     2     2
     9     7     5     3     9
     4     5     8     8     7
     7     5     8     1     8

Problem #2

%// Append 8's at the start of every (2,2) block in b
b1 = reshape([8*ones(2,4) ; reshape(b,4,[])],2,[])

%// Mask where b1 values are to be put in an otherwise zeros filled array
mask = kron(eye(4,4),ones(2,3))==1

%// Initialize output arraya and set values from b1 into masked places 
out = zeros(size(mask))
out(mask) = b1
0
votes

For your first problem. Use logical indexing:

index = diag(ones(1,size(B,1))
B(index) = A(index)