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!
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
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
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
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!
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;
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!
Not other than the SQRVECH improvement. It sounds like an interesting project! Good luck.
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[1]=0 then SurvivalM=survival1; /*****Create a 1 by N -matrix of Survival ****/;
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;
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?
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.