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

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 885 views
  • 0 likes
  • 2 in conversation