n=6; submit n; /** generate all permutations of n elements, in order **/ data perm&n (drop=i); array a{&n}; do i = 1 to &n; a[i]=i; end; /** initialize **/ do i = 1 to fact(&n); call allperm(i, of a[*]); output; end; run; endsubmit; n = 6; Valid = {0 0 1 1 1 1, 0 0 1 1 1 1, 1 1 0 0 1 1, 1 1 0 0 1 1, 1 1 1 1 0 0, 1 1 1 1 0 0}; start GetPermutationMatrix(v); /* create permutation matrix */ n = ncol(v); P = j(n, n, 0); do i = 1 to n; P[i, v[i]] = 1; end; return (P); finish; /****** TEST *******/ /** Sibling_1 ... Spouse_3 **/ names = {Si1 Sp1 Si2 Sp2 Si3 Sp3}; GiveTo = { 4 6 5 1 4 2}; PermMat = GetPermutationMatrix(GiveTo); print PermMat[r=names c=names]; g={2 6 1 5 4 3}; P2 = GetPermutationMatrix(g); print P2[r=names c=names]; /****** TEST *******/ use perm6; read all var _NUM_ into X; close perm6; v = j(1, n, .); /** create data set to hold results **/ create matches from v; do k = 1 to nrow(X); v = X[k,]; P = GetPermutationMatrix( v ); s = sum(Valid#P); /** check if permutation is valid **/ if s = n then /** if so, append to results **/ append from v; end; close matches; use matches; read all var _NUM_ into Y; close matches; names = {M P D J N R}; years = 2011:(2010+nrow(Y)); years = char(years, 4); Exchange = shape( names[Y], nrow(Y) ); /** names are in systematic order; randomize **/ u = uniform( j(nrow(Y), 1, 98765432) ); r = rank(u); Exchange = Exchange[r, ]; print (Exchange[1:15,])[r=years c=names]; /*************************************/ /** SAS/IML Studio program to simulate probability that Pam gives to someone twice in a row Rick Wicklin 03JAN2011 blogs.sas.com/iml **/ proc iml; call randseed(4321); NumSim = 100000; /** simulate this many times **/ p = {0.25 0.25 0.25 0.25}; /** probability that Pam gives to any person **/ x = j(NumSim, 1); /** allocate vector for random results **/ call randgen(x, "Table", p); /** module to compute the lag of a column vector (not needed for SAS/IML 9.22) **/ /* start Lag(x, d); n = nrow(x); y = j(n, 1, .); if n >= d then y[d+1:n] = x[1:n-d]; return( y ); finish; */ /** estimate probability that Pam gives to same person twice in a row **/ any2 = sum(x=Lag(x,1)) / NumSim; print any2; NumYears = 15; x = j(NumYears, NumSim); call randgen(x, "Table", p); /** each column is one 15-year simulation **/ results = j(NumSim, 1); do j = 1 to NumSim; results[j] = sum( x[,j]=Lag(x[,j],1) ); end; match = 0:14; y = pdf("Binomial", match, 0.25, 14); /** P(success) = 1/4. Number of trials = 14. **/ declare BarChart b; b = BarChart.Create("test", results); b.SetOtherThreshold(0); b.ShowPercentage(); b.ShowAxisReferenceLines(YAXIS); b.SetGraphAreaBackgroundColor(WHITE); /** draw markers **/ b.DrawUseNormalizedCoordinates(-0.5, 11.5, 0, 0.25); b.DrawMarker(match, y, MARKER_CIRCLE, 6); b.SetTitleText("Repeated Giving in 15 Years", true); run DrawLegend(b, {"Simulated" "Binomial(X, 0.25, 14)"}, 10, RGBToInt({245 248 177}) || BLACK, 0||-1, -1||MARKER_CIRCLE, -1, "IRT" );