## Return multiple values using SAS/IML function when using nested functions

Hi

I am simulating data and calling  module function from within another module. My problem is that I need to return the vector of data that I created inside my module along with the index (q).

********************************************************

proc iml;

n=20; m=15; K=J(m,1,0); K[m]=n-m;
L=K;  m1=m; m2=m;
Theta1 =2; Theta2=5;
seed=22;

start Uniform_p(m,R)  global(seed);

** The Required Progressively Type-II from U(0,1);

W=ranuni( repeat(seed,m,1) );
V=J(m,1,0); U=J(m,1,0);

Do i=1 to m;
Sum=0;
Do j=m-i+1 to m;
Sum=Sum+R[j];
End;
Sum=Sum+i;
V[i]=W[i]**(1/Sum);
End;

Do i=1 to m;
U[i]=1-prod ( V[m: (m-i+1)]   );
End;

Call sort (U);
return U;
Finish;

T=X[CEIL(m/4)];
Do idx=1 to m-1;
If (( X[idx] < T) & (T <= X[idx+1] )) then q=idx;
End;

If X[m]>T then

Do;
W=Uniform_p(m-q,R);
X_m_q = T - theta*log(1-W);
End;

else

Do;
q= m;
End;

return X_Adptive; * I need to return X_Adptive ,  q  and T;
Finish;

X = - theta1 * log (1- uniform_p(m1,K));
Y = - theta2 * log (1- uniform_p(m2,L));

quit;

1 ACCEPTED SOLUTION

Accepted Solutions

## Re: Return multiple values using SAS/IML function when using nested functions

You're on the right track, but you're still returning just the vector X_Adptive from your Adaptive module. When you create the list P1 in that module, you need to include X_Adptive as an element of the list (in addition to T and q) and then return P1:

``````P1 = [ X_Adptive, T, q];
return P1;``````

And later on, note that when you call the Adaptive module, you access elements of the returned list like this:

``````adaptiveRes = Adaptive(X,m1,K,theta1);

I would also recommend reviewing the use of named lists in the above linked blog post. In the examples above, you can see I'm extracting list items using their positions (i.e., `adaptiveRes\$1`is the first item of the list). However, giving list items names can improve code readability. For example, in your case, you could name your list items 'X_Adaptive', 't', and 'q', and then extract those by name rather than position.

8 REPLIES 8

## Re: Return multiple values using SAS/IML function when using nested functions

One option is to return a list. @Rick_SAS  wrote about lists here: https://blogs.sas.com/content/iml/2017/03/29/lists-sasiml.html . In your case, you would want to return a list of two items, where the first item is the simulated vector, and the second item is the index value.

## Re: Return multiple values using SAS/IML function when using nested functions

Thank you for your suggestions. I read the article and I even went to SAS help to read more about it. However, I am not sure where to put it in my code!!

Inside the subroutine? and How?

Can you please demonstrate into my code.

Thank you

## Re: Return multiple values using SAS/IML function when using nested functions

At the end of your Adaptive module, it looks like you want to return X_Adptive, q and t, but you are only returning X_Adptive. To return all three, you can create a list that contains those three items (see here https://blogs.sas.com/content/iml/2018/01/22/iml-lists-syntax.html ) and return the list from the module.

## Re: Return multiple values using SAS/IML function when using nested functions

Thank you Nike_N for your help.

I added the list as you suggested, unfortunately the code didn't work and SAS didn't recognize the list. I am not sure if this is due to defining it inside my subroutine or something else. Please advise. The code attached below.

## Re: Return multiple values using SAS/IML function when using nested functions

You're on the right track, but you're still returning just the vector X_Adptive from your Adaptive module. When you create the list P1 in that module, you need to include X_Adptive as an element of the list (in addition to T and q) and then return P1:

``````P1 = [ X_Adptive, T, q];
return P1;``````

And later on, note that when you call the Adaptive module, you access elements of the returned list like this:

``````adaptiveRes = Adaptive(X,m1,K,theta1);

I would also recommend reviewing the use of named lists in the above linked blog post. In the examples above, you can see I'm extracting list items using their positions (i.e., `adaptiveRes\$1`is the first item of the list). However, giving list items names can improve code readability. For example, in your case, you could name your list items 'X_Adaptive', 't', and 'q', and then extract those by name rather than position.

## Re: Return multiple values using SAS/IML function when using nested functions

Thank you so much for your help.

## Re: Return multiple values using SAS/IML function when using nested functions

In addition to what @Mike_N says, I would gently suggest that you consider two changes to your program:

1. Use the RANDGEN function instead of RANUNI. See Six reasons you should stop using the RANUNI function to generate random numbers - The DO Loop (sas....

2. Vectorize the program to achieve better performance. See How to vectorize computations in a matrix language - The DO Loop (sas.com)

I suspect @Mike_N can help with my second suggestion if it is not clear.

## Re: Return multiple values using SAS/IML function when using nested functions

Hello Rick

Thank you for the suggestions. Is it ok to use

Do i=1 to m;
W[i]=Uniform(seed);
End;
instead of the ranuni which I used earlier in my code?
As for the second suggestion, I am not sure I understood it.

Thank you
From The DO Loop