A simple module for finding row-wise cumulative sum in IML:
Proc IML;
Start rowcumsum(x);
Step1 = cusum(x);
Step2 = 0 // Step1[1:nrow(Step1)-1,ncol(Step1)];
Output = Step1 - repeat(Step2,1,ncol(Step1));
return(Output);
Finish rowcumsum;
a = {1 2 3,4 5 6, 7 8 9};
SASCUSUM = cusum(a);
ROWCUSUM = rowcumsum(a);
print a; print SASCUSUM; Print ROWCUSUM;
Quit;
a
01 02 03
04 05 06
07 08 09
SASCUSUM
01 03 06
10 15 21
28 36 45
ROWCUSUM
01 03 06
04 09 15
07 15 24
You didn't ask a question, so I can't tell whether you are saying "here is how to do this" or whether you are asking "is this the best way to do this."
If the former, yes, this is a good way to compute cumulative sums across rows of a matrix.It is a clever algorithm.
If you are asking whether this is the fastest way, I'll offer two observations: you can use the LAG function (introduced in SAS/IML 9.22) to speed up Step2, and you don't need the REPEAT function when forming the OUTPUT matrix. Thus the following code is slightly more efficient:
start rs(x);
Step1 = cusum(x);
Step2 = lag(Step1[,ncol(Step1)], 1); /* returns missing in Step2[1] */
Step2[1] = 0; /* replace missing value with 0 */
Output = Step1 - Step2;
return( Output);
finish;
Unless your matrices are huge, it doesn't really matter which module you run. In fact, unless the number of rows is huge, you can just use a simple DO loop and the computation is just as fast:
Output = j(nrow(x), ncol(x));
do i = 1 to nrow(x);
Output[i,] = cusum(x[i,]);
end;
You didn't ask a question, so I can't tell whether you are saying "here is how to do this" or whether you are asking "is this the best way to do this."
If the former, yes, this is a good way to compute cumulative sums across rows of a matrix.It is a clever algorithm.
If you are asking whether this is the fastest way, I'll offer two observations: you can use the LAG function (introduced in SAS/IML 9.22) to speed up Step2, and you don't need the REPEAT function when forming the OUTPUT matrix. Thus the following code is slightly more efficient:
start rs(x);
Step1 = cusum(x);
Step2 = lag(Step1[,ncol(Step1)], 1); /* returns missing in Step2[1] */
Step2[1] = 0; /* replace missing value with 0 */
Output = Step1 - Step2;
return( Output);
finish;
Unless your matrices are huge, it doesn't really matter which module you run. In fact, unless the number of rows is huge, you can just use a simple DO loop and the computation is just as fast:
Output = j(nrow(x), ncol(x));
do i = 1 to nrow(x);
Output[i,] = cusum(x[i,]);
end;
Thanks for the variations, Rick. I just wanted to share the piece of code that I repeatedly found useful.
My co's yet to make the step up from 9.20, which is slightly irritating because 9.22 has a decent set of functions introduced ... so instead of say, cuprod(x) which is available in 9.22, I use exp(cusum(log(x)))
The loop increases the computation time drastically if this function is used within an optimization code. I noticed IML has this amazing speed-up (nearly 15x) for vectorized vs loop section (similar results to your blog post on running mean and variance).The results were a bit surprising because MATLAB hardly produced a 1.5x speedup for the same optimization code, and a fully vectorized optimization code in IML runs 3x faster than the same code in MATLAB!
Impressive results! Congratulations, and thanks for sharing!
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!