I need to Use SAS random number generation functions RAND() and a DO....END loop to create 100 obs in variable named X then I want to use another DO loop of 500 rounds to generate a total of 500 samples, each with 100 obs. a sample is basically sampling from a standard normal distribution.
I tried the following code but it does not give me what I need:
data A;
call streaminit(123); /* set random number seed */
do i = 1 to 100;
X = rand("Normal"); /* random number generator */
output;
end;
do r = 1 to 500 ;
if i then X = rand("Normal");
output;
end;
run;
Any input will be greatly appreciated.
Perfect time to use PROC IML:
proc iml;
call streaminit(123); /* set seed */
x = j(500, 100); /* allocate 500 by 100 matrix */
call randgen(x, "Normal"); /* fill matrix with N(0,1) random draws */
create mydata from x; /* move matrix to a dataset in the work directory */
append from x;
close mydata;
quit;
Here is a data step solution
data want;
do I=1 to 500;
do _iorc_=1 to 100;
X=rand ("normal");
output;
end;
end;
run;
Related
I am trying to write a decoder for GPU. My encoding scheme has data dependencies between lines. So when decoding columns of data each column depends on the previous. I want to parallellize the internal computation of each column, but execute each column one-by-one and sequentially, but I am having trouble getting this correctly.
Below I have modeled a toy example to show the problem:
Func f;
Var x,y;
RDom r(1,3,1,3); // goes from (1,1) to (4,4)
f(x,y) = 0;
f(0,y) = y;
Expr p_1 = f(r.x-1,r.y);
Expr p_2 = f(r.x-1,r.y-1);
f(r.x,r.y) = p_1 + p_2;
Buffer<int32_t> output_2D = f.realize({4,4});
A visualization of this program can be seen here: Serial Computation Visualisation
This reduction should give the following array():
int expected_output[4][4] = {{0,0,0,0},
{1,1,1,1},
{2,3,4,5},
{3,5,8,12}};
And checking using Catch2 I can see that it actually calculates it correctly
for(int j = 0; j < output_2D.height(); j++){
for(int i = 0; i < output_2D.width(); i++){
CAPTURE(i,j);
REQUIRE(expected_output[j][i]==output_2D(i,j));
}
}
My task is to speed this computation up. Since column one depends on column zero I have to calculate each column in series. I can however, calculate all the values in the column in parallel. Please see Computation Steps Parallel and Desired Pipeline to see how I want Halide to compute the pipeline.
I tried doing this in halide using the f.update(1).allow_race_conditions().parallel(r.y); and this does almost what I want.
f(r.x,r.y) = p_1 + p_2;
f.update(1).allow_race_conditions().parallel(r.y);
f.trace_stores();
Buffer<int32_t> output_2D = f.realize({4,4});
For some reason however, it seems that parallel(y) executes the columns in seemingly random order.
It yields the following store_trace:
Init Image:
Store f29.0(0, 0) = 0
Store f29.0(1, 0) = 0
....
Store f29.0(3, 3) = 0
Init first row:
Store f29.0(0, 0) = 0
Store f29.0(1, 0) = 1
Store f29.0(2, 0) = 2
Store f29.0(3, 0) = 3
Start Parallel Computation:
Store f29.0(1, 1) = 1 // First parallel column
Store f29.0(2, 1) = 1
Store f29.0(3, 1) = 1
Store f29.0(1, 3) = 5 // Second parallel column: THIS IS MY PROBLEM
Store f29.0(2, 3) = 5 // This should be column 2 not column 3.
Store f29.0(3, 3) = 5
Store f29.0(1, 2) = 3
Store f29.0(2, 2) = 4
Store f29.0(3, 2) = 5
A visualization of this pattern can be seen here in this figure: Current Pipeline.
I know that I explicitly enabling the race_conditions so I must be doing something wrong, but I dont know what is the right way to do this and this is the closest I got. I could vectorize() with respect to y and that gives the correct evaluation, but I want to use the parallel() block to gain greater speedup for larger matrixes/images. RFactor might be a solution as my problem should be associative in the y direction, but it might not work as it is non-associative in the x-direction(each column depends on the previous) Does anyone know how to be serial in x and parallel in y when using RDoms?
I am having trouble with the math.random() function in Lua.
The code I'm trying to run is:
for x = 1,5 do
math.randomseed(os.time())
math.random(); math.random(); math.random()
value = math.random(0,9)
print(value)
end
The random number that is being printed is always the same.
What can be the possible solution to this? I want 5 unique random numbers.
Initialize random once (outside the loop), use many:
math.randomseed(os.time()) -- random initialize
math.random(); math.random(); math.random() -- warming up
for x = 1,5 do
-- random generating
value = math.random(0,9)
print(value)
end
I would like to ask if anybody can give a hand in solving the following issue: How should I use the random function in Pascal in order to generate a random combination of digits that are already initialized (I mean that I have given values to four variables and I want via the random function to create a random combination of these four digits).
Thanks in advance!
Rossi
var digits : array[0..3] of integer = (10,20,30,40);
i : integer;
begin
Randomize; // initialize the random generator. Only once per program
for i:=0 to 50 do
Writeln(digits[random(4)]);
end.
The Writeln line draws a number 0<=x<4 so 0..3, and looks it up in the digits array, then writes it to console output. It is draws 50 random numbers and then quits.
var
randomnumber,i:integer;
number:array[0..3] of integer;
begin
randomize;
for i:= 0 to 3 do
begin
readln(number[i]);
end;
randomnumber:= (number[random(4)] * 1000) + (number[random(4)] * 100) + (number[random(4)] * 10) + (number[random(4)] * 1);
writeln(randomnumber);
end.
I hope this could help.
But the given initial value should be between 0 to 9.
If you want that the output contains each digit only once, then you would need to stored the digits which have already been chosen in a set to prevent them from being chosen again.
const
digits: array [0..3] of integer = (1, 3, 5, 7);
var
i, n, total: integer;
stored: set of integer;
begin
Randomize;
stored:= [];
total:= 0;
for i:= 1 to 4 do
begin
repeat
n:= random (4);
until not (n in stored);
stored:= stored + [n];
total:= total * 10 + digits[n];
end;
writeln (total)
end.
I have an excel file that I imported into SAS that contains 3 variables and 3 observations.
All values are numbers.
24 12 47
99 30 14
50 5 41
Is there a way I can code so that each row is sorted in ascending order?
Result would be:
12 24 47
14 30 99
5 41 50
I need to do this for several excel files that contain huge number of variables and observations.
Thank You.
The simple way is to use CALL SORTN which sorts across rows.
data have;
input a b c;
datalines;
24 12 47
99 30 14
50 5 41
;
run;
data have;
modify have;
call sortn(of _numeric_);
run;
I would use a FCMP sort routine. FCMP functions and subroutines only allow temporary arrays to be passed to them for modification. So you have to assign the values into a temporary array, sort, and then reassign to the permanent variables.
Modify the code below for your number of columns and column names.
options cmplib=work.cmp;
proc fcmp outlib=work.cmp.fns;
subroutine qsort(arr[*],lo,hi);
outargs arr;
i = lo;
j = hi;
do while (i < hi);
pivot = arr[floor((lo+hi)/2)];
do while (i<=j);
do while (arr[i] < pivot);
i = i + 1;
end;
do while (arr[j] > pivot);
j = j - 1;
end;
if (i<=j) then do;
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
i = i + 1;
j = j - 1;
end;
end;
if (lo < j) then
call qsort(arr,lo,j);
lo = i;
j = hi;
end;
endsub;
run;
quit;
data test;
input a b c;
datalines;
24 12 47
99 30 14
50 5 41
;
run;
%let ncol=3;
%let cols = a b c;
data sorted;
set test;
array vars[&ncol] &cols;
/*Only temporary arrays can be passed to FCMP functions*/
array tmp[&ncol] _temporary_;
/*Assign to tmp*/
do i=1 to &ncol;
tmp[i] = vars[i];
end;
/*Sort*/
call qsort(tmp,1,&ncol);
/*Put back sorted values*/
do i=1 to &ncol;
vars[i] = tmp[i];
end;
drop i;
run;
Though there's a package SAS/IML designed specifically for manipulations with matrices (where, I believe, this task would be trivial), it still can be done with SAS Base using a couple of PROCs wrapped into macro loop.
data raw;
input a b c;
datalines;
24 12 47
99 30 14
50 5 41
;
run;
proc transpose data=raw out=raw_t(drop=_:); run;
proc sql noprint;
select name into :vars separated by ' '
from sashelp.vcolumn
where libname='WORK' and memname='RAW_T';
quit;
%macro sort_rows;
%do i=1 %to %sysfunc(countw(&vars));
proc sort data=raw_t(keep=%scan(&vars,&i)) out=column;
by %scan(&vars,&i);
run;
data sortedrows;
%if &i>1 %then set sortedrows;;
set column;
run;
%end;
%mend sort_rows;
%sort_rows
proc transpose data=sortedrows out=sortedrows(drop=_:); run;
First, you transpose your original dataset.
Then you iterate through all columns (which were rows originally) one by one, sorting them and right-joining to each other.
And finally, transpose everything back.
I am new to parallel programming using MPI... I need to parallelize a 300x200 Lattice Boltzman cube.. I managed chunking row wise by dividing 200 into chunks depending on size... However my code works only when there are 4 and 8 cores... I need to run the program on 16 cores..Can anyone please direct me as to how to divide 200 for 16 cores..
I am splitting currently in the following manner:
.
.
.
MPI_Init( &argc, &argv );
/* size and rank will become ubiquitous */
/* get no of process (size) & rank of each proces*/
MPI_Comm_size( MPI_COMM_WORLD, &size );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
start= (200 / size) * rank;
end = start + (200 / size);
.
.
.
for(ii=start;ii<end;ii++) {
for(jj=0;jj<300;jj++)
.
.
.
}
.
.
CLearly the above technique would work only if 200%size = 0, for 16 cores size=16, and hence the approach would fail.. Could anyone please suggest a more generalized chunking approach approach..which would make the program independent (if possible) of number of cores I would be running it on..
The easiest way to fix that would be to calculate 'start' and 'end' as
slice_size = (200 + size - 1)/size; // max. amount of rows per core
start = rank * slice_size;
end = min(start + slice_size, 200);
In this case, some cores can be underloaded.
A better scalability could be achieved if the lattice is divided not by rows only, but both by rows and columns, or even in non-rectangular areas, for example, using a linear representation of the lattice, like this:
total_cells = rows * columns;
common_piece_size = (total_cells + size - 1) / size;
start = rank * common_piece_size;
end = min(start + common_piece_size, total_size);
for (i = start; i < end; i++) {
row = i / columns;
col = i % columns;
// process cell [col, row]
}
. This would require more complex inter-process communication though.