0001 function rnd = gamrnd(a,b,method)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 if (nargin < 2)
0034 error('gamrnd:: Two input arguments are needed!');
0035 end
0036
0037 if nargin==2
0038 method= 'BauwensLubranoRichard';
0039 if any(a<1)
0040 method = 'Devroye';
0041 Devroye.small = 'Best';
0042
0043 end
0044 if ~strcmpi(method,'BauwensLubranoRichard')
0045 Devroye.big = 'Best';
0046
0047
0048
0049
0050 end
0051 else
0052 error('gamrnd:: Selection of method not yet implemented')
0053 end
0054
0055 [ma,na] = size(a);
0056 [mb,nb] = size(b);
0057
0058 if ma~=mb || na~=nb
0059 error('gamrnd:: Input arguments must have the same size!');
0060 end
0061
0062 if na~=1
0063 error('gamrnd:: Input arguments must be column vectors');
0064 end
0065
0066 if (any(a<0)) || (any(b<0)) || (any(a==Inf)) || (any(b==Inf))
0067 error('gamrnd:: Input arguments must be finite and positive!');
0068 end
0069
0070 [tests,integer_idx,double_idx] = isint(a);
0071
0072 number_of_integer_a = length(integer_idx);
0073 number_of_double_a = length(double_idx);
0074
0075 rnd = NaN(ma,1);
0076
0077 if number_of_integer_a
0078 small_idx = find(a(integer_idx)<30);
0079 big_idx = find(a(integer_idx)>=30);
0080 number_of_small_a = length(small_idx);
0081 number_of_big_a = length(big_idx);
0082 if number_of_small_a
0083
0084 for i=1:number_of_small_a
0085 rnd(integer_idx(small_idx(i))) = sum(exprnd(ones(a(integer_idx(small_idx(i))),1)))*b(integer_idx(small_idx(i)));
0086 end
0087 end
0088 if number_of_big_a
0089
0090 rnd(integer_idx(big_idx)) = sqrt(a(integer_idx(big_idx))).* b(integer_idx(big_idx)) .* randn(number_of_big_a, 1) + a(integer_idx(big_idx)) .* b(integer_idx(big_idx));
0091 end
0092 end
0093
0094
0095 if number_of_double_a
0096 if strcmpi(method,'BauwensLubranoRichard')
0097
0098 rnd(double_idx) = knuth_algorithm(a(double_idx),b(double_idx));
0099 else
0100 small_idx = find(a(double_idx)<1);
0101 big_idx = find(a(double_idx)>1);
0102 number_of_small_a = length(small_idx);
0103 number_of_big_a = length(big_idx);
0104 if number_of_small_a
0105 if strcmpi(Devroye.small,'Weibull')
0106
0107 rnd(double_idx(small_idx)) = weibull_rejection_algorithm(a(double_idx(small_idx)),b(double_idx(small_idx)));
0108 elseif strcmpi(Devroye.small,'Johnk')
0109
0110 rnd(double_idx(small_idx)) = johnk_algorithm(a(double_idx(small_idx)),b(double_idx(small_idx)));
0111 elseif strcmpi(Devroye.small,'Berman')
0112
0113 rnd(double_idx(small_idx)) = berman_algorithm(a(double_idx(small_idx)),b(double_idx(small_idx)));
0114 elseif strcmpi(Devroye.small,'GS')
0115
0116 rnd(double_idx(small_idx)) = ahrens_dieter_algorithm(a(double_idx(small_idx)),b(double_idx(small_idx)));
0117 elseif strcmpi(Devroye.small,'Best')
0118
0119 rnd(double_idx(small_idx)) = best_1983_algorithm(a(double_idx(small_idx)),b(double_idx(small_idx)));
0120 end
0121 end
0122 if number_of_big_a
0123 if strcmpi(Devroye.big,'Cheng')
0124
0125 rnd(double_idx(big_idx)) = cheng_algorithm(a(double_idx(big_idx)),b(double_idx(big_idx)));
0126 elseif strcmpi(Devroye.big,'Best')
0127
0128 rnd(double_idx(big_idx)) = best_1978_algorithm(a(double_idx(big_idx)),b(double_idx(big_idx)));
0129 end
0130 end
0131 end
0132 end
0133
0134
0135 function gamma_variates = weibull_rejection_algorithm(a,b)
0136 nn = length(a);
0137 mm = nn;
0138 cc = 1./a ;
0139 dd = a.^(a./(1-a)).*(1-a);
0140 ZE = NaN(nn,2);
0141 X = NaN(nn,1);
0142 INDEX = 1:mm;
0143 index = INDEX;
0144 while mm
0145 ZE(index,:) = exprnd(ones(mm,2));
0146 X(index) = ZE(index,1).^cc(index);
0147 id = find( (ZE(:,1)+ZE(:,2) > dd + X) );
0148 if isempty(id)
0149 mm = 0;
0150 else
0151 index = INDEX(id);
0152 mm = length(index);
0153 end
0154 end
0155 gamma_variates = X.*b;
0156
0157
0158 function gamma_variates = johnk_algorithm(a,b)
0159 nn = length(a);
0160 mm = nn;
0161 aa = 1./a ;
0162 bb = 1./b ;
0163 INDEX = 1:mm;
0164 index = INDEX;
0165 UV = NaN(nn,2);
0166 X = NaN(nn,1);
0167 Y = NaN(nn,1);
0168 while mm
0169 UV(index,:) = rand(mm,2);
0170 X(index) = UV(index,1).^aa(index);
0171 Y(index) = UV(index,2).^bb(index);
0172 id = find(X+Y>1);
0173 if isempty(id)
0174 mm = 0;
0175 else
0176 index = INDEX(id);
0177 mm = length(index);
0178 end
0179 end
0180 gamma_variates = exprnd(ones(nn,1)).*X./(X+Y);
0181
0182
0183 function gamma_variates = berman_algorithm(a,b)
0184 nn = length(a);
0185 mm = nn;
0186 aa = 1./a ;
0187 cc = 1./(1-a) ;
0188 INDEX = 1:mm;
0189 index = INDEX;
0190 UV = NaN(nn,2);
0191 X = NaN(nn,1);
0192 Y = NaN(nn,1);
0193 while mm
0194 UV(index,:) = rand(mm,2);
0195 X(index) = UV(index,1).^aa(index);
0196 Y(index) = UV(index,2).^cc(index);
0197 id = find(X+Y>1);
0198 if isempty(id)
0199 mm = 0;
0200 else
0201 index = INDEX(id);
0202 mm = length(index);
0203 end
0204 end
0205 Z = gamrnd(2*ones(nn,1),ones(nn,1));
0206 gamma_variates = Z.*X.*b ;
0207
0208
0209 function gamma_variates = ahrens_dieter_algorithm(a,b)
0210 nn = length(a);
0211 mm = nn;
0212 bb = (exp(1)+a)/exp(1);
0213 cc = 1./a;
0214 INDEX = 1:mm;
0215 index = INDEX;
0216 UW = NaN(nn,2);
0217 V = NaN(nn,1);
0218 X = NaN(nn,1);
0219 while mm
0220 UW(index,:) = rand(mm,2);
0221 V(index) = UW(index,1).*bb(index);
0222 state1 = find(V(index)<=1);
0223 state2 = find(V(index)>1);
0224 ID = [];
0225 if ~isempty(state1)
0226 X(index(state1)) = V(index(state1)).^cc(index(state1));
0227 test1 = UW(index(state1),2) <= exp(-X(index(state1))) ;
0228 id1 = find(~test1);
0229 ID = INDEX(index(state1(id1)));
0230 end
0231 if ~isempty(state2)
0232 X(index(state2)) = -log(cc(index(state2)).*(bb(index(state2))-V(index(state2))));
0233 test2 = UW(index(state2),2) <= X(index(state2)).^(a(index(state2))-1);
0234 id2 = find(~test2);
0235 if isempty(ID)
0236 ID = INDEX(index(state2(id2)));
0237 else
0238 ID = [ID,INDEX(index(state2(id2)))];
0239 end
0240 end
0241 mm = length(ID);
0242 if mm
0243 index = ID;
0244 end
0245 end
0246 gamma_variates = X.*b ;
0247
0248
0249 function gamma_variates = best_1983_algorithm(a,b)
0250 nn = length(a);
0251 mm = nn;
0252 tt = .07 + .75*sqrt(1-a);
0253 bb = 1 + exp(-tt).*a./tt;
0254 cc = 1./a;
0255 INDEX = 1:mm;
0256 index = INDEX;
0257 UW = NaN(nn,2);
0258 V = NaN(nn,1);
0259 X = NaN(nn,1);
0260 Y = NaN(nn,1);
0261 while mm
0262 UW(index,:) = rand(mm,2);
0263 V(index) = UW(index,1).*bb(index);
0264 state1 = find(V(index)<=1);
0265 state2 = find(V(index)>1);
0266 ID = [];
0267 if ~isempty(state1)
0268 X(index(state1)) = tt(index(state1)).*V(index(state1)).^cc(index(state1));
0269 test11 = UW(index(state1),2) <= (2-X(index(state1)))./(2+X(index(state1))) ;
0270 id11 = find(~test11);
0271 if ~isempty(id11)
0272 test12 = UW(index(state1(id11)),2) <= exp(-X(index(state1(id11)))) ;
0273 id12 = find(~test12);
0274 else
0275 id12 = [];
0276 end
0277 ID = INDEX(index(state1(id11(id12))));
0278 end
0279 if ~isempty(state2)
0280 X(index(state2)) = -log(cc(index(state2)).*tt(index(state2)).*(bb(index(state2))-V(index(state2)))) ;
0281 Y(index(state2)) = X(index(state2))./tt(index(state2)) ;
0282 test21 = UW(index(state2),2).*(a(index(state2)) + Y(index(state2)) - a(index(state2)).*Y(index(state2)) ) <= 1 ;
0283 id21 = find(~test21);
0284 if ~isempty(id21)
0285 test22 = UW(index(state2(id21)),2) <= Y(index(state2(id21))).^(a(index(state2(id21)))-1) ;
0286 id22 = find(~test22);
0287 else
0288 id22 = [];
0289 end
0290 if isempty(ID)
0291 ID = INDEX(index(state2(id21(id22))));
0292 else
0293 ID = [ID,INDEX(index(state2(id21(id22))))];
0294 end
0295 end
0296 mm = length(ID);
0297 if mm
0298 index = ID;
0299 end
0300 end
0301 gamma_variates = X.*b ;
0302
0303
0304 function gamma_variates = knuth_algorithm(a,b)
0305 nn = length(a);
0306 mm = nn;
0307 bb = sqrt(2*a-1);
0308 dd = 1./(a-1);
0309 Y = NaN(nn,1);
0310 X = NaN(nn,1);
0311 INDEX = 1:mm;
0312 index = INDEX;
0313 while mm
0314 Y(index) = tan(pi*rand(mm,1));
0315 X(index) = Y(index).*bb(index) + a(index) - 1 ;
0316 idy1 = find(X(index)>=0);
0317 idn1 = setdiff(index,index(idy1));
0318 if ~isempty(idy1)
0319 test = log(rand(length(idy1),1)) <= ...
0320 log(1+Y(index(idy1)).*Y(index(idy1))) + ...
0321 (a(index(idy1))-1).*log(X(index(idy1)).*dd(index(idy1))) - ...
0322 Y(index(idy1)).*bb(index(idy1)) ;
0323 idy2 = find(test);
0324 idn2 = setdiff(idy1,idy1(idy2));
0325 else
0326 idy2 = [];
0327 idn2 = [];
0328 end
0329 index = [ INDEX(idn1) , INDEX(index(idn2)) ] ;
0330 mm = length(index);
0331 end
0332 gamma_variates = X.*b;
0333
0334
0335 function gamma_variates = cheng_algorithm(a,b)
0336 nn = length(a);
0337 mm = nn;
0338 bb = a-log(4);
0339 cc = a+sqrt(2*a-1);
0340 UV = NaN(nn,2);
0341 Y = NaN(nn,1);
0342 X = NaN(nn,1);
0343 Z = NaN(nn,1);
0344 R = NaN(nn,1);
0345 index = 1:nn;
0346 INDEX = index;
0347 while mm
0348 UV(index,:) = rand(mm,2);
0349 Y(index) = a(index).*log(UV(index,2)./(1-UV(index,2)));
0350 X(index) = a(index).*exp(UV(index,2));
0351 Z(index) = UV(index,1).*UV(index,2).*UV(index,2);
0352 R(index) = bb(index) + cc(index).*Y(index)-X(index);
0353 test1 = (R(index) >= 4.5*Z(index)-(1+log(4.5)));
0354 jndex = index(find(test1));
0355 Jndex = setdiff(index,jndex);
0356 if ~isempty(Jndex)
0357 test2 = (R(Jndex) >= log(Z(Jndex)));
0358 lndex = Jndex(find(test2));
0359 Lndex = setdiff(Jndex,lndex);
0360 else
0361 Lndex = [];
0362 end
0363 index = INDEX(Lndex);
0364 mm = length(index);
0365 end
0366 gamma_variates = X.*b;
0367
0368
0369 function gamma_variates = best_1978_algorithm(a,b)
0370 nn = length(a);
0371 mm = nn;
0372 bb = a-1;
0373 cc = 3*a-.75;
0374 UV = NaN(nn,2);
0375 Y = NaN(nn,1);
0376 X = NaN(nn,1);
0377 Z = NaN(nn,1);
0378 W = NaN(nn,1);
0379 index = 1:nn;
0380 INDEX = index;
0381 while mm
0382 UV(index,:) = rand(mm,2);
0383 W(index) = UV(index,1).*(1-UV(index,1));
0384 Y(index) = sqrt(cc(index)./W(index)).*(UV(index,1)-.5);
0385 X(index) = bb(index)+Y(index);
0386 jndex = index(find(X(index)>=0));
0387 Jndex = setdiff(index,jndex);
0388 if ~isempty(jndex)
0389 Z(jndex) = 64*W(jndex).*W(jndex).*W(jndex).*UV(jndex,2).*UV(jndex,2);
0390 kndex = jndex(find(Z(jndex)<=1-2*Y(jndex).*Y(jndex)./X(jndex)));
0391 Kndex = setdiff(jndex,kndex);
0392 if ~isempty(Kndex)
0393 lndex = Kndex(find(log(Z(Kndex))<=2*(bb(Kndex).*log(X(Kndex)./bb(Kndex))-Y(Kndex))));
0394 Lndex = setdiff(Kndex,lndex);
0395 else
0396 Lndex = [];
0397 end
0398 new_index = INDEX(Lndex);
0399
0400 end
0401 index = union(new_index,INDEX(Jndex));
0402 mm = length(index);
0403 end
0404 gamma_variates = X.*b;