Tony Chivers
Tony Chivers

Reputation: 191

How can I create a modified identity matrix?

I have an identity matrix in MATLAB which is used in some regression analysis for joint hypothesis tests. However, when I change the linear restrictions for my tests, I can no longer rely on the identity matrix.

To give a simple example, here is some code which produces an identity matrix depending on the value of y:

for i = [1, 2, 4]
  y = i
  x = 5;
  H = eye(y*x)
end

However, what I need is not the identity matrix, but the first two rows and all others to be zero.

For the first example, the code produces an eye(5):

H =

     1     0     0     0     0
     0     1     0     0     0
     0     0     1     0     0
     0     0     0     1     0
     0     0     0     0     1 

I need something that given y does not produce the identity but in fact produces:

H =

     1     0     0     0     0
     0     1     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0 

Can I adjust the identity matrix to include zeroes only after the first two rows?

Upvotes: 0

Views: 524

Answers (3)

Adriaan
Adriaan

Reputation: 18187

As suggested in this comment you can use diag:

diag([ones(2,1); zeros(x*y-2,1)])

This works because diag makes a vector become the main diagonal of a square matrix, so you can simply feed it the diagonal vector, which is your case would be 2 1s and the rest 0s.

Of course if you need a variable amount of 1s, which I was in doubt about hence the comment,

n=2;
diag([ones(n,1); zeros(x*y-n,1)])

Upvotes: 3

Luis Mendo
Luis Mendo

Reputation: 112749

Here are some alternatives:

  • Use blkdiag to diagonally concatenate an identity matrix and a zero matrix:

    y = 5; x = 2;
    H = blkdiag(eye(x), zeros(y-x));
    
  • A more exotic approach is to use element-wise comparisons with singleton expansion and exploit the fact that two NaN's are not equal to each other:

    y = 5; x = 2;
    H = [1:x NaN(1,y-x)];
    H = double(bsxfun(@eq, H, H.'))
    

Upvotes: 2

gnovice
gnovice

Reputation: 125874

I think the simplest solution is to make a matrix of all zeroes and then just place the two ones by linear indexing:

H = zeros(x*y);
H([1 x*y+2]) = 1;

Generalizing the above to putting the first N ones along the diagonal:

H = zeros(x*y);
H(x*y.*(0:(N-1))+(1:N)) = 1;

Upvotes: 4

Related Questions