BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
IanWakeling
Barite | Level 11

I have been experimenting with the GRAYCODE function within an IML program and thought I would post my experiences for the benefit of others.

I was expecting to be able to define a vector x = j(1, 4, 0), set k = -1 and then call

rc = graycode(k, x);

in a loop, where x would cycle through all the combinations (effectively a representation of the binary numbers 0 to 15 in a minimum change order).  If I do that, I get an unhelpful error insisting that the first argument k should be binary, I think I can see now why I get this, but not the first few times.  It seems the only way to use it, is to provide a list of scalars that have all been pre-initialised.  So the following does work:

   k = -1;
   a = 0; b = 0; c = 0; d = 0;
   do i=1 to 2##4;
     rc = graycode(k, a, b, c, d);
     print i k a b c d rc;
   end;

the only problem is that I am thinking of putting this in an algorithm with 2^19 iterations, and managing 19 scalars is cumbersome to say the least.  Wouldn't it make much more sense to get the scalars returned as a row vector?  My solution is to create the row vector myself using the return codes, and just feed in zeros rather than scalars. This is far from intuitive, but does do what I want.

   k = 0;
   x = j(1, 4, 0);
   rc = 0;
   print x rc;
   do i=2 to 2##4;
     rc = graycode(k, 0, 0, 0, 0);

     x[rc] = 1 - x[rc];
     print x rc;
   end;

I also tried  rc = graycode(k, , , , ) but regretted it!

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

I understand your frustration. I have blogged about the problem of calling Base SAS functions that require a list of parameters, and have provided a method that I often use to handle INPUT parameters: Calling Base SAS functions from SAS/IML: How to handle argument lists? - The DO Loop

In this case, the Base SAS function is providing multiple OUTPUT parameters, so you can't use my trick. However, you can solve your problem by using the CALL GRAYCODE subroutine rather than the GRAYCODE function.  It's not clear from your description whether you need a numerical vector or whether a character string will suffice. In the following statements, s is a character string; if you need a numerical vector, use the new functionality of the SUBSTR function to convert the string to a vector:

s='0000';

n=length(s);

k=countc(s, '0');

do i=2 to 2##n;

   call graycode(k, s, n, '01');

   x = num(substr(s, 1:n, 1));  /* necessary */

   print i  k s x;

end;

BTW, when the initial string has 19 characters (s='0000000000000000000';) the program completes in less than a second, so it appears to be sufficiently efficient.

View solution in original post

2 REPLIES 2
Rick_SAS
SAS Super FREQ

I understand your frustration. I have blogged about the problem of calling Base SAS functions that require a list of parameters, and have provided a method that I often use to handle INPUT parameters: Calling Base SAS functions from SAS/IML: How to handle argument lists? - The DO Loop

In this case, the Base SAS function is providing multiple OUTPUT parameters, so you can't use my trick. However, you can solve your problem by using the CALL GRAYCODE subroutine rather than the GRAYCODE function.  It's not clear from your description whether you need a numerical vector or whether a character string will suffice. In the following statements, s is a character string; if you need a numerical vector, use the new functionality of the SUBSTR function to convert the string to a vector:

s='0000';

n=length(s);

k=countc(s, '0');

do i=2 to 2##n;

   call graycode(k, s, n, '01');

   x = num(substr(s, 1:n, 1));  /* necessary */

   print i  k s x;

end;

BTW, when the initial string has 19 characters (s='0000000000000000000';) the program completes in less than a second, so it appears to be sufficiently efficient.

IanWakeling
Barite | Level 11

Many thanks for your tips Rick.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

Multiple Linear Regression in SAS

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.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 2 replies
  • 899 views
  • 0 likes
  • 2 in conversation