我想创建一些随机矩阵,但它们在内存中非常大,所以我想找到一种方法在计算机上重现它们,这样当我需要将它们发送到另一台机器时,我只需要发送代码。 我想这样做:
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
我担心的是parfor循环,无论parfor中的索引顺序如何,我都需要能够重现随机矩阵。所以我决定使用MATLAB流:
这是我的代码(变量n,p,R_type控制随机矩阵是如何形成的,但它们并不重要,K与上面的变量相同,我需要它在行{{1} }}):
>> 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
尝试了一些代码,这里是:
awk
我想知道代码是否正确,是否在函数调用后保留了全局流的状态?请帮助我,非常感谢
答案 0 :(得分:4)
MATLAB从“已知”但“复杂”函数生成随机数,因此您可以生成相同的随机序列!号码。
这样做你应该使用“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'),并且用于 worker默认为Combined Multiple Recursive生成器 ('CombRecursive'或'mrg32k3a')。如果有必要生成 客户端和工作人员中的数字流相同,您可以设置一个 匹配另一个。“
显然matlab工作者使用matlab本身使用不同的函数(用于生成随机数),所以你也可以在“rng”函数中设置默认函数,
rng(5,'twister') % for using twister method to generate random number
for more info try this doc from 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函数的worker中设置默认函数(答案中的最后一个例子)
关于使用全局流,使用全局流没有区别,您应该使用rng函数设置种子值以获得相同的可重现结果,全局流只是指示您使用哪个函数生成随机数, matlab有大约6个函数来完成这项工作,但如果你有自己的函数你可以在全局流上设置它,然后再次使用rng函数来获取每次生成随机数时的相同序列