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

I want to simulate 1000 sets comprising 6 weights (w1, w2, w3, w4, w5, w6). Their values are uniformly distributed ranging from -1 to 1 (but their absolute values are greater than 0.01. The sum of their absolute values is added to 1. 

 

Can anyone please help?

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

Hello @rosiecao2509,

 

As mkeintz has already pointed out, there is no probability distribution satisfying all your requirements. Indeed, note that for |wi| (i=1, ..., 6) with a uniform distribution on [0.01, 1] you would have the expectation E(|w1|+...+|w6|) = 6*(0.01+1)/2 = 3.03, not 1 as per your requirement.

 

I would probably start with a Dirichlet distribution, Dir(a). For example, consider the special case a=(1,1,1,1,1,1), which yields the uniform distribution over the set of points with positive coordinates in six-dimensional space whose coordinates sum to 1. Once you have generated a random vector (x1, ..., x6) from this distribution, you easily get corresponding weights wi: Just apply the linear transformation xi → 0.01+0.94*xi and generate a random sign.

 

Here is SAS code implementing this approach:

data want(drop=i j);
call streaminit(27182818);
array w[6];
array x[6] _temporary_;
do i=1 to 1000;
  do j=1 to dim(w);
    x[j]=rand('expo');
  end;
  do j=1 to dim(w);
    w[j]=(2*rand('bern',0.5)-1)*(0.01+0.94*x[j]/sum(of x[*]));
  end;
  output;
end;
run;

(Note that the exponential distribution with default parameter 1 is the same as the Gamma(1,1) distribution mentioned in the Wikipedia article.)

 

In particular, this approach ensures that the six weights have the same probability distribution.

View solution in original post

3 REPLIES 3
mkeintz
PROC Star

The moment you require the sum of absolute values of w1..w6 to be 1, you can no longer expect each weight w to be uniformly distributed w~uniform(-1,1). 

 

True, you could distribute w1~uniform(-1,+1), excluding (-0.01,+0.01).  Actually you'd distribute absolute |w1|~uniform(0.01,+1), and then randomly generate a positive or negative sign.  Or to prevent any of w2 through w6 being less than 0.01, you would uniformly distribute |w1|~uniform(0.01,0.95).

 

Let's say the absolute value of |w1| is 0.4.  Then you could uniformly distribute absolute |w2| over (0.01,0.55), i.e. (0.01, 0.95-0.4), and again randomly generate a sign.

 

You could similarly generate w3 through w5, and finally directly calculate absolute |w6| from the others, and randomly give it a sign.  

 

But clearly the only weight distributed uniform(-1,1) is w1.  

 

So could you clarify?

 

 

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
FreelanceReinh
Jade | Level 19

Hello @rosiecao2509,

 

As mkeintz has already pointed out, there is no probability distribution satisfying all your requirements. Indeed, note that for |wi| (i=1, ..., 6) with a uniform distribution on [0.01, 1] you would have the expectation E(|w1|+...+|w6|) = 6*(0.01+1)/2 = 3.03, not 1 as per your requirement.

 

I would probably start with a Dirichlet distribution, Dir(a). For example, consider the special case a=(1,1,1,1,1,1), which yields the uniform distribution over the set of points with positive coordinates in six-dimensional space whose coordinates sum to 1. Once you have generated a random vector (x1, ..., x6) from this distribution, you easily get corresponding weights wi: Just apply the linear transformation xi → 0.01+0.94*xi and generate a random sign.

 

Here is SAS code implementing this approach:

data want(drop=i j);
call streaminit(27182818);
array w[6];
array x[6] _temporary_;
do i=1 to 1000;
  do j=1 to dim(w);
    x[j]=rand('expo');
  end;
  do j=1 to dim(w);
    w[j]=(2*rand('bern',0.5)-1)*(0.01+0.94*x[j]/sum(of x[*]));
  end;
  output;
end;
run;

(Note that the exponential distribution with default parameter 1 is the same as the Gamma(1,1) distribution mentioned in the Wikipedia article.)

 

In particular, this approach ensures that the six weights have the same probability distribution.

rosiecao2509
Fluorite | Level 6
Thanks a lot Reinhard,
It works perfectly well. Thank you so much for your help.

Wish you all the best.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 553 views
  • 2 likes
  • 3 in conversation