turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-03-2012 10:02 AM

m matrices are created from a two level do-loop. These matrices have the same dimension, say n by n. How can I create a big matrix by appending these m matrices together in IML?

Thanks for your help!

Accepted Solutions

Solution

12-03-2012
10:22 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-03-2012 10:22 AM

You don't say whether you want horizontal concatenation or vertical, but here is some code for horizontal concatenation. The vertical case is similar.

proc iml;

m = 4; /* create m matrices */

n = 2; /* each is nxn */

/* in this approach, the matrices are appended

so that the first n columns are matrix 1,

the second n columns are matrix 2,

and so forth */

Big = j(n, n*m);

do i = 1 to m;

/* generate i_th matrix somehow */

x = i * j(n,n,1);

/* compute columns in Big matrix */

cStart = (i-1)*n + 1; /* start at this column */

cEnd = cStart + n - 1;

Big[, cStart:cEnd] = x; /* store i_th matrix */

end;

print Big;

Incidentally, I find that many times I can define a matrix without using a "two level do-loop" as you mention in your question. See if you can express the defining formula directly as a matrix expression without using DO loops. For some examples, see Constructing common covariance structures - The DO Loop

All Replies

Solution

12-03-2012
10:22 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-03-2012 10:22 AM

You don't say whether you want horizontal concatenation or vertical, but here is some code for horizontal concatenation. The vertical case is similar.

proc iml;

m = 4; /* create m matrices */

n = 2; /* each is nxn */

/* in this approach, the matrices are appended

so that the first n columns are matrix 1,

the second n columns are matrix 2,

and so forth */

Big = j(n, n*m);

do i = 1 to m;

/* generate i_th matrix somehow */

x = i * j(n,n,1);

/* compute columns in Big matrix */

cStart = (i-1)*n + 1; /* start at this column */

cEnd = cStart + n - 1;

Big[, cStart:cEnd] = x; /* store i_th matrix */

end;

print Big;

Incidentally, I find that many times I can define a matrix without using a "two level do-loop" as you mention in your question. See if you can express the defining formula directly as a matrix expression without using DO loops. For some examples, see Constructing common covariance structures - The DO Loop

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-03-2012 12:10 PM

Thank you, Rick. It works.

Actually I used the two-level do-loop to get the derivatives of a symmetric matrix about its elements. I need to store them in a big matrix and later to subtract each of them to use in the other formula, which is in the other two-level do-loop. This is the only way I figured out. Any comment?

My codes are as follows.

start MM(nn,mat);

mat=j(nn,nn*nn*(nn+**1**)/**2**,**0**); k=**0**;

do j=**1** to nn;

deltaj=j(nn,**1**,**0**);

deltaj**1**;

do i=j to nn;

deltai=j(nn,**1**,**0**);

deltai*=***1**;

k=k+**1**;

if i=j then mat1=deltaj*deltaj`;

else mat1=deltai*deltaj`+deltaj*deltai`;

cStart = (k-**1**)*nn + **1**; *copy your codes here;

cEnd = cStart + nn - **1**;

mat[,cStart:cEnd] = mat1;

end;

end;

finish;

**run** MM(**3**,mat);

print mat;

Is it true that do-loops can make an algorithm's convergence slowly? For my case, it looks I can not avoid the two-level do-loops. Right?

Thanks again!

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-03-2012 01:04 PM

Yes, it is generally true that unnecessary DO loops should be eliminated. The more you do with matrices and vectors, the more efficient an algorithm can be. This is not only true for SAS/IML, but also for other matrix-vector languages such as MATLAB and R.

If you are computing derivatives of symmetric matrices, the textbooks often express the calculations in terms of VECH and VEC. See

McCulloch (1982), "Symmetric Matrix Derivatives with Applications", *JASA*, or

Harville (1997), *Matrix Algebra from a Statistician’s Perspective*

In the SAS/IML language, I would use the SQRVECH function to eliminate the loops and the matrix multiplication:

start MMM(nn,mat);

size = nn*(nn+1)/2;

mat=j(nn,nn*size,0);

do k = 1 to size;

e_k = j(size,1,0); /* e_k = {0,...,0,1,0,...,0} where the 1 is in the k_th position */

e_k

cStart = (k-1)*nn + 1; *copy your codes here;

cEnd = cStart + nn - 1;

mat[,cStart:cEnd] = sqrvech(e_k);

end;

finish;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-03-2012 02:29 PM

Yes, I have the book. But I have a special case. I need to calculate the first derivative of V about A, with V={A@I_{k_i} 0, 0 0} where @ represents Kroneck product, 0s are matrices (not vectors or a scalar), A is a symmetric matrix, and I_{k_i} is an identity matrix with dimension k_i. We know that dvec(A)/dv(A) (the first derivative of vec(A) about the distinct elements in A, v(A) is a vector of these elements) is a duplication matrix and it is easier to write a function of a duplication matrix in IML if we know the dimension of the symmetric matrix. It looks that dV/dv(A) is a function of the duplication matrix. However, I did not figure out what it is. Do you have any suggestion?

Thanks for your time!

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-03-2012 02:57 PM

Not other than the SQRVECH improvement. It sounds like an interesting project! Good luck.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

01-31-2013 07:42 PM

what is wrong with this, I just started using proc iml;

SurvivalM=J(nrow(survival1),**1**,**1**);

do i = **1** to n;

if censored*=***1** then SurvivalM*=survival1 ; *else if censored[

end;

print SurvivalM;

InverseC=J(nrow(survival1),**1**,**1**);

do i = **1** to n;

if censored*=***1** then InverseC*=***1**/survival1*; *else if censored[**1**]=**0** then InverseC*=***1**; /*****survivalC* is the imputed censored survival and set the real Survivalval to 1**/*;

end;

print InverseC;

Big=SurvivalM*t(InverseC)[loc(test^=**1**)] ;

print Big;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

01-31-2013 08:18 PM

Hi, and welcome to IML and the IML forum!

It looks like your question is unrelated to the question in this thread (which, anyway, has been marked as "answered").

Please start a new question with a descriptive title and post your question there. It would also be useful if you could state

1) What you are trying to do. "What's wrong with this" doesn't give us enough info to help.

2) What error you are getting. Maybe show the SAS log that contains the error?