크기 - MATLAB에서 병렬 호출간에 무작위 행렬을 생성 할 때 재현 가능한 결과



매트랩 행렬 저장 (1)

MATLAB은 "KNOWN"이지만 "복잡한"함수에서 임의의 숫자를 생성하므로 동일한 임의 순서를 생성 할 수 있습니다! 번호.

그렇게하려면 "rng"함수를 사용해야합니다.
rng를 기본값으로 설정하여 난수 생성을 재설정합니다.

rng('default');
rand(1,5)
ans=
0.8147  0.9058  0.1270  0.9134  0.6324

다음이 난수 시퀀스를 재현하려면 다음과 같이 작성할 수 있습니다.

rng('default');
rand(1,5)
ans=
    0.8147  0.9058  0.1270  0.9134  0.6324

또 다른 방법은 난수 생성을위한 시드를 얻거나 설정하는 것입니다.

s=rng;
rand(1,5)
ans= 0.0975  0.2785  0.5469  0.9575  0.9649

동일한 seq를 재생할 수 있습니다.

rng(s);
rand(1,5)
ans=
     0.0975  0.2785  0.5469  0.9575  0.9649

noe "rng"그 자체가 풍부한 함수이고 matlab 문서에서 더 공부할 수 있습니다.

(나는 그 질문을 올바르게 이해하기를 바랍니다)

@ m7913d의 답변에

"기본적으로 MATLAB® 클라이언트와 MATLAB 작업자는 작업자가 클라이언트가있는 동일한 시스템의 로컬 클러스터에 속하더라도 다른 난수 생성기를 사용합니다. 클라이언트의 경우 기본값은 Mersenne Twister 생성기 ( 'twister' )이고, 작업자의 경우 기본값은 Combined Multiple Recursive 생성자 ( 'CombRecursive'또는 'mrg32k3a')입니다. 클라이언트와 작업자에서 동일한 숫자의 스트림을 생성해야하는 경우 다른 하나와 일치하도록 하나를 설정할 수 있습니다. "

분명히 matlab 노동자 matlab 자체에서 다른 함수 (임의의 숫자를 생성하기 위해)를 사용하므로 "rng"함수의 기본 함수를 설정할 수도 있습니다,

rng(5,'twister') % for using twister method to generate random number

자세한 정보는 matlab에서이 문서를 사용해보십시오.

parfor에서 임의의 숫자 시퀀스를 재현 할 수 있음을 보여주는 새로운 예제입니다.

>> parfor i=1:3
rng(3,'twister');
rand(1,5)
i
end

ans =

    0.5508    0.7081    0.2909    0.5108    0.8929


ans =

     3


ans =

    0.5508    0.7081    0.2909    0.5108    0.8929


ans =

     1


ans =

    0.5508    0.7081    0.2909    0.5108    0.8929


ans =

     2

코멘트에서 필수적인 부분 :

"클라이언트 근로자"에 대해 내가 말했듯이 matlab은 모든 클라이언트 워커에 대해 기본 함수를 사용하기 때문에 결과는 완전히 재현 가능합니다. 다만, 임의의 수를 생성하는 기본 함수는 matlab 자체 기본 함수와 다릅니다. MATLAB과 rng 함수를 사용하는 작업자의 기본 함수를 설정할 수있는 문제는 아닙니다 (마지막 예제는 답)

글로벌 스트림을 사용하는 방법에 대한 차이점은 없습니다. 글로벌 스트림을 사용하는 것과 차이가 없습니다. 동일한 재현 결과를 얻기 위해 rng 함수를 사용하여 시드 값을 설정해야합니다. 글로벌 스트림은 임의의 숫자를 생성하는 함수를 나타냅니다. 6 함수는이 작업을 수행하지만 전역 스트림에서 설정할 수있는 함수가있는 경우 rng 함수를 사용하여 난수를 생성 할 때마다 동일한 시퀀스를 가져야합니다

여러 개의 무작위 매트릭스를 만들고 싶지만 실제로 메모리에 맞도록 크기가 큽니다. 따라서 다른 컴퓨터로 보낼 필요가있을 때 컴퓨터간에 재현 할 수있는 방법을 찾고 싶습니다. 코드를 보내면됩니다. 여기 내가 어떻게하고 싶은가요 :

num_of_iters = 10;
K = 200;
for iter = 1:num_of_iters
    parfor j = 1:K
        R = make_random_R(iter,j,.....);
        % Do something
    end
end

제가 걱정하는 것은 parfor 루프입니다. parfor의 인덱스 순서가 무엇이든 무작위 매트릭스를 재현 할 수 있어야합니다. 그래서 이것을 위해 MATLAB 스트림을 사용하기로했습니다.

  • 전역 스트림 저장
  • 새 스트림을 만들고 시드와 해당 하위 스트림을 설정합니다 (iter 및 j에 따라 다름)
  • 수학을해라.
  • 글로벌 스트림 되돌리기

여기에 내 코드가있다 (변수 n, p, R_type은 랜덤 행렬이 어떻게 만들어 지는지 제어하지만 중요하지 않으며 K는 위에서 나온 변수와 같은 변수이다.) substream_id = (iter - 1) * K + j; ) :

function [R] = make_random_R(iter,j,n,K,p,R_type)
% Data as code
% R_type: 'posneg' or 'normdist'
% 1 <= iter <= 100
% 1 <= j <= K
% K: Number of classifiers
% n: Number of observations

assert(strcmp(R_type,'posneg') || strcmp(R_type,'normdist'),'R_type must be posneg or normdist');
assert(iter >= 1,'Error: iter >= 1 not satisfied');
assert((1 <= j) && (j <= K),'Error: 1 <= j <= K not satisfied');
assert(K > 0,'Error: K > 0 not satisfied');

globalStream = RandStream.getGlobalStream;
globalState =  globalStream.State;

stream=RandStream('mlfg6331_64','Seed',1);
substream_id = (iter - 1) * K + j;
stream.Substream = substream_id;
RandStream.setGlobalStream(stream);

switch R_type
    case 'posneg'        
        q0=ceil(2*log(n)/0.25^2)+1;
        if (q0 < p)
            q = q0;
        else
            q = ceil(p/2);
        end
        R = randi([0 1],p,q);
        R(R == 0) = -1;
    case 'normdist'        
        q = 2*ceil(log2(p));
        R = normrnd(0,1,[p,q]);    
end
RandStream.setGlobalStream(globalStream);
globalStream.State = globalState;
end

몇 가지 코드를 시도하고 여기있다 :

>> iter = 2;
>> j = 3;
>> n=100;
>> K=10;
>> p=6;
>> R_type = 'normdist';
>> for j=1:K
j
make_ran
>> parfor j=1:K
j
make_random_R(iter,j,n,K,p,R_type)
end
Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers.

ans =

     7


ans =

   -0.3660    0.8816    1.1754   -0.4987   -1.8612   -0.3683
    0.9504   -0.3067   -0.5156   -0.2383   -1.1661    0.3622
    2.0743   -0.4195    0.5021    0.3954    0.2415   -0.4552
   -0.0474   -0.1645   -0.1725   -0.4938   -0.2559    0.2188
    1.0735    0.3660    0.1043    0.4403   -0.3166    1.1241
   -1.0421   -1.4528   -0.4976   -0.7166   -1.1328   -2.0260


ans =

     2


ans =

   -1.6629    0.0213   -1.8138   -0.4375    0.3575   -0.0353
    0.6653   -1.2662   -0.3977   -0.6540   -1.2131    0.4858
    0.3421    1.1266   -0.6066   -1.2095    1.5496   -0.9341
    0.2145    0.7192   -2.2087    0.7597   -0.0110   -1.1282
   -0.3511   -0.7305   -0.1143    0.0242    0.2431   -0.8612
    0.5875    1.2665   -2.1943   -0.4879    0.0120   -1.1539


ans =

     1


ans =

   -0.5300    2.4077   -0.3478    1.8695   -1.1327   -1.0734
   -0.2540   -1.1265    0.3152    0.4265    1.2777    0.0959
    0.5005   -0.7557    0.6194    1.5873    0.0961   -1.9216
    0.7275    0.5420   -0.6237   -0.2228    0.8915    0.4644
    0.8131   -0.1492    0.9232    0.8410   -0.0637    2.1163
   -1.1995    0.2338   -1.3726    0.1604   -0.1855    1.3826


ans =

     8


ans =

   -0.5146    2.2106    2.7200   -1.2136    1.0004    1.3089
    0.7225    0.2746   -0.8798    0.2978   -0.8490    1.6744
    1.1998   -0.0363    1.9105   -0.7747   -0.8707   -0.6823
    0.6801    1.3194   -0.0685    0.5944    1.5078   -1.6821
    0.0876    1.2150   -0.0747    0.0324   -1.1552    0.0966
   -0.0624   -0.3874   -0.5356    0.6353    1.4090   -1.1014


ans =

     6


ans =

    0.5866   -1.0222   -0.2168    0.8582    1.4360    0.0699
    2.0677   -0.4740   -0.8763    1.7827    0.1930   -1.2167
   -0.3941   -0.5441    0.3719   -0.0609    0.7138   -1.0920
    0.3622   -0.0459   -0.0221    0.2030   -0.7695   -0.8963
   -0.1986   -0.2560    0.6666    0.4831   -1.2028   -0.9423
    0.1656    1.2006   -1.1131    0.7704   -0.6906   -1.3143


ans =

     5


ans =

   -0.5782   -0.3634    1.5381   -1.3173   -0.9493    0.8480
    1.5921   -0.4069    0.7795   -0.3390   -0.1071    0.4201
   -0.0184    0.2865   -0.1139   -0.1171    0.2288    0.5511
    0.1787    0.7583    0.3994    1.0457    0.3291   -0.9150
    0.3641   -0.6420   -0.2096    0.7761    0.4022   -0.7478
    0.1165    0.7142    0.7029   -1.1195    0.0905    0.6810


ans =

     4


ans =

    0.1246   -0.3173    0.8068    0.6485   -0.8572    0.2275
    0.3674   -0.0507   -0.9196    0.6161   -0.5821   -0.4291
   -1.0142   -1.1614   -2.5438    1.5915    2.0356    0.4535
   -0.2111   -0.3974    0.0376    0.3825   -1.9702    1.5318
   -0.3890    0.9210   -0.0635    0.3248    1.8666   -0.0160
    1.3908   -0.7204   -0.6772   -0.0713    0.0569    0.5929


ans =

     3


ans =

   -0.1602    0.6891    0.4725    0.0277   -2.0510   -2.2440
   -0.7497    1.8225   -0.4433    0.4090    0.9021   -1.6683
    0.0659    0.3909    0.2043    0.9065    1.4630    0.3091
   -0.3886    0.6715   -0.9742   -0.5468    0.2890    0.5625
   -0.4558    0.4770   -0.1888   -0.6504    0.3281    1.3767
    0.3983    0.5834    0.9360    0.8604   -0.9776    0.6755


ans =

    10


ans =

   -0.4843   -0.4512    0.7544    0.7585   -0.4417   -0.0208
    1.8537   -1.6935   -2.7067   -0.5077    0.9616   -1.7904
   -1.6943   -1.0988    0.1208   -0.8100    1.8778    1.1654
    1.1759   -0.7087   -1.2673   -0.1381   -0.0710    0.5343
    0.2589   -0.5128   -0.3970    0.6737    0.8097    2.7024
   -0.8933    0.2810    0.8117   -0.5428   -0.8782    1.1746


ans =

     9


ans =

    0.0254   -0.7993    1.5164    1.2921   -1.1013    1.8556
   -0.6280    0.9374   -0.1962    0.1685   -0.5079    0.4333
   -0.3962   -0.9977    0.6971   -1.0310   -1.1997   -2.1391
    0.7179    1.0177   -0.8874   -0.6732    0.7295    1.4448
   -1.1793   -1.3210    1.5292    0.2280    1.9337    1.0901
   -0.0926    0.1798   -1.1740    0.3447    2.4578    0.4170

나는 코드가 맞는지 궁금하고, 함수 호출 후에 전역 스트림의 상태를 유지합니까? 제발 도와주세요. 고마워요.