Сбросить поток случайных чисел
Похоже, что SAS/IML имеет возможность сбросить поток случайных чисел ( ссылка на документ) .
Есть ли аналогичная функция для подпрограмм с произвольными числами на шаге данных SAS?
Исходя из этого поста, кажется, что последующие призывы к streaminit
игнорируются в пределах одного шага данных.
Например, приведенный ниже код создает разные случайные числа для каждой строки:
data want;
do i = 1 to 2;
call streaminit(123); * <-- WANT THIS TO RESET THE STREAM;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
put _all_;
output;
end;
run;
Выход:
i=1 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
i=2 ran1=0.3878454913 ran2=0.3291709244 ran3=0.3615948586
Я хотел бы вывод:
i=1 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
i=2 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
3 ответа
Вы не можете сбросить потоки для функции RAND в SAS 9.4M4. Однако вы можете перемотать поток в SAS 9.4M5 ( который был отправлен в сентябре 2017 года), используя новую процедуру STREAMREWIND. Следующая программа показывает синтаксис:
data want;
call streaminit(123);
do i = 1 to 2;
call streamrewind;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
put _all_;
output;
end;
run;
Вы можете обойти это, используя сгенерированный код, однако, с помощью CALL EXECUTE или, возможно, DOSUBL, например:
data _null_;
do i = 1 to 2;
rc=dosubl(cats("data want_",i,";
call streaminit(123); * <-- WANT THIS TO RESET THE STREAM;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
i=",i,";
put _all_;
output;
run;
"));
end;
rc = dosubl("data want; set want_1 want_2; run;");
run;
Очевидно, что проще / лучше написать макрос для этой части.
К сожалению, это ограничение "новой" программы RAND; со старым было намного легче работать в этом отношении (поскольку у него действительно было только одно семя). Свойства семени нового более сложны, и поэтому, хотя вы можете инициализировать его одним числом, это не так просто, отсюда и сложности.
Ты можешь использовать call ranuni
использовать одно и то же начальное число для двух разных потоков случайных чисел.
Обратите внимание, что здесь используется другой, более низкий PRNG, с гораздо более коротким циклом и худшими статистическими свойствами, чем rand()
функция.
Пример:
data x;
seed1 = 123;
seed2 = 123;
do i =1 to 3;
call ranuni(seed1, x);
call ranuni(seed2, y);
output;
end;
run;
Выход:
i=1 x=0.7503960881 y=0.7503960881
i=2 x=0.3209120251 y=0.3209120251
i=3 x=0.178389649 y=0.178389649