Subscribe Bookmark
XanGregg

Staff

Joined:

Jun 23, 2011

JSL Tip: Replace Loops with Functions on Matrices

In my previous JSL tip, we saw how it is faster to access matrix items than to list items. It's faster still if you don't have to access the items at all. That is, get JMP's internal code to do the looping and item access instead of doing it in your JSL code. You can do that when you just need to apply a simple function to each item.


Recall the loop to make a (one-dimensional) matrix of odd numbers:


// make a matrix of odd numbers

n = 1000;

y = J(1, n); // creates a 1 x n matrix with all values set to 1

for (i = 1, i <= n, i++,

y = 2 * i - 1;

);



Here's what it looks like without the loop:


// make a matrix of odd numbers

n = 1000;

y = 1::n; // creates a 1 x n matrix with all values set to 1..n

y = 2 * y - 1;



Besides getting rid of the loop, we used a different matrix creation function. m::n is shorthand for Index(m, n), which creates a one-dimensional matrix with elements m to n, inclusive. When we apply scalar operations to a matrix, JMP applies those operations to each cell individually. That way, we transfer the looping from JSL to JMP internals. Almost any numeric function can be applied this way.


Sqrt( y ); // [1 1.41421356 1.7320508 2 2.23606 ...

Power( y, y ); // [1 4 27 256 ...

Log( y ); // 0 0.6931471805 1.09861228 1.38629436 ...

Floor( y / 3 ); // [0 0 1 1 1 2 2 2 3 3 ...

Sine( y / n ); // [0.0009999998 0.0019999986 0.0029999955 ...



As commenter Michael noted previously, the odd numbers example can be simplified even more because the Index function can actually take a third argument, which is an increment. So we can get the first n odd numbers with:


y = Index( 1, n * 2, 2 ); // odd numbers from 1 to 2n