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

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -