comparison scripts/statistics/distributions/betainv.m @ 20641:c3c052b9192a

Improve performance and error reporting of betainv, gaminv (bug #34363). * betainv.m: Replace for loop with do-until loop. Shorten max loop cycles to 40, rather than 10,000. Issue warning if algorithm fails. * gaminv.m: Replace for loop with do-until loop. Shorten max loop cycles to 40, rather than 100. Issue warning if algorithm fails.
author Rik <rik@octave.org>
date Sun, 11 Oct 2015 16:55:17 -0700
parents d9341b422488
children 4e307c55a2b5
comparison
equal deleted inserted replaced
20640:f9c991dc5c1a 20641:c3c052b9192a
79 l = find (y > 1 - myeps); 79 l = find (y > 1 - myeps);
80 if (any (l)) 80 if (any (l))
81 y(l) = 1 - sqrt (myeps) * ones (length (l), 1); 81 y(l) = 1 - sqrt (myeps) * ones (length (l), 1);
82 endif 82 endif
83 83
84 y_old = y; 84 y_new = y;
85 for i = 1 : 10000 85 loopcnt = 0;
86 do
87 y_old = y_new;
86 h = (betacdf (y_old, a, b) - x) ./ betapdf (y_old, a, b); 88 h = (betacdf (y_old, a, b) - x) ./ betapdf (y_old, a, b);
87 y_new = y_old - h; 89 y_new = y_old - h;
88 ind = find (y_new <= myeps); 90 ind = find (y_new <= myeps);
89 if (any (ind)) 91 if (any (ind))
90 y_new(ind) = y_old(ind) / 10; 92 y_new(ind) = y_old(ind) / 10;
92 ind = find (y_new >= 1 - myeps); 94 ind = find (y_new >= 1 - myeps);
93 if (any (ind)) 95 if (any (ind))
94 y_new(ind) = 1 - (1 - y_old(ind)) / 10; 96 y_new(ind) = 1 - (1 - y_old(ind)) / 10;
95 endif 97 endif
96 h = y_old - y_new; 98 h = y_old - y_new;
97 if (max (abs (h)) < sqrt (myeps)) 99 until (max (abs (h)) < sqrt (myeps) || ++loopcnt == 40)
98 break; 100
99 endif 101 if (loopcnt == 40)
100 y_old = y_new; 102 warning ("betainv: calculation failed to converge for some values");
101 endfor 103 endif
102 104
103 inv(k) = y_new; 105 inv(k) = y_new;
104 endif 106 endif
105 107
106 endfunction 108 endfunction