How to compute the GCD of a vector in GNU Octave / Matlab -
gcd (a1, a2, ...)
computes gcd of elements a1(1), a2(1), ...
. being elements stored in vector a
, how compute gcd (a)
?
(i mean, gcd (4, 2, 8) = 2
, gcd ([4, 2, 8]
raise error in gnu octave 4.0.0).
with cell array expansion
here one-liner, valid in octave (thanks nirvana-msu pointing out matlab's limitation):
a = [10 25 15]; gcd(num2cell(a){:}) # ans = 5
this use cell array expansion, bit hidden there :
accessing multiple elements of cell array ‘{’ , ‘}’ operators result in comma separated list of requested elements
so here a{:}
interpreted a(1), a(2), a(3)
, , gcd(a{:})
gcd(a(1), a(2), a(3))
performance
still under octave
a = 3:259; tic; gcd(num2cell(a){:}); toc elapsed time 0.000228882 seconds.
while gcd_vect
in @nirvana_msu answer,
tic; gcd_vect(a); toc elapsed time 0.0184669 seconds.
this because using recursion implies high performance penalty (at least under octave). , more 256 elements in a, recursion limit exhausted.
tic; gcd_vect(1:257); toc <... snipped bunch of errors ...> error: evaluating argument list element number 2 error: called gcd_vect @ line 8 column 13
this improved lot using divide , conquer algorithm
while cell array expansion (octave only) scales well:
a = 127:100000; tic; gcd(num2cell(a){:}); toc elapsed time 0.0537438 seconds.
divide , conquer algorithm (best)
this 1 should work under matlab (not tested though. feedback welcome).
it uses recursion too, in other answers, divide , conquer
function g = gcd_array(a) n = numel(a); if (mod(n, 2) == 0) % number of elements % separate in 2 parts of equal length idx_cut = n / 2; part1 = a(1:idx_cut); part2 = a(idx_cut+1:end); % use standard gcd compute gcd of pairs g = gcd(part1(:), part2(:)); if ~ isscalar(g) % result array, compute gcd g = gcd_array(g); endif else % odd number of elements % separate in 1 scalar , array number of elements g = gcd(a(1), gcd_array(a(2:end))); endif endfunction
timings:
a = 127:100000; tic; gcd_array(a); toc elapsed time 0.0184278 seconds.
so seems better cell array expansion.
Comments
Post a Comment