[英]How to compute the GCD of a vector in GNU Octave / Matlab
gcd (A1, A2, ...)
計算元素A1(1), A2(1), ...
的GCD。 作為存儲在向量A
的元素,如何計算gcd (A)
?
(我的意思是, gcd (4, 2, 8) = 2
, gcd ([4, 2, 8]
會在GNU Octave 4.0.0中引發錯誤)。
以下是粗略的,但似乎適用於簡單的例子
function g = gcd_array(vals)
if length(vals) == 1
g = vals;
else
g = gcd(vals(1), gcd_array(vals(2:end)));
endif
這是一個單行,僅在八度音程中有效(感謝nirvana-msu指出matlab的限制):
A = [10 25 15];
gcd(num2cell(A){:})
# ans = 5
這使用單元陣列擴展,有點隱藏在那里 :
使用'{'和'}'運算符訪問單元數組的多個元素將導致所有請求元素的逗號分隔列表
所以這里A{:}
被解釋為A(1), A(2), A(3)
,因而gcd(A{:})
為gcd(A(1), A(2), A(3))
仍在八度音階
A = 3:259;
tic; gcd(num2cell(A){:}); toc
Elapsed time is 0.000228882 seconds.
與gcd_vect
中的gcd_vect回答,
tic; gcd_vect(A); toc
Elapsed time is 0.0184669 seconds.
這是因為使用遞歸意味着高性能損失(至少在八度音階下)。 實際上,對於A中超過256個元素,遞歸限制已用盡。
tic; gcd_vect(1:257); toc
<... snipped bunch of errors as ...>
error: evaluating argument list element number 2
error: called from
gcd_vect at line 8 column 13
使用Divide and conquer算法可以大大改善這一點
雖然單元陣列擴展(僅限八度)可以很好地擴展:
A = 127:100000;
tic; gcd(num2cell(A){:}); toc
Elapsed time is 0.0537438 seconds.
這個應該在matlab下工作(雖然沒有經過測試。歡迎反饋)。
它也使用遞歸,就像在其他答案中一樣,但是使用Divide和conquer
function g = gcd_array(A)
N = numel(A);
if (mod(N, 2) == 0)
% even number of elements
% separate in two parts of equal length
idx_cut = N / 2;
part1 = A(1:idx_cut);
part2 = A(idx_cut+1:end);
% use standard gcd to compute gcd of pairs
g = gcd(part1(:), part2(:));
if ~ isscalar(g)
% the result was an array, compute its gcd
g = gcd_array(g);
endif
else
% odd number of elements
% separate in one scalar and an array with even number of elements
g = gcd(A(1), gcd_array(A(2:end)));
endif
endfunction
定時:
A = 127:100000;
tic; gcd_array(A); toc
Elapsed time is 0.0184278 seconds.
所以這似乎比單元陣列擴展更好。
請注意,與Octave不同,Matlab gcd
函數只需要兩個輸入參數。 由於gcd(a,b,c) = gcd(a,gcd(b,c))
你可以使用遞歸來處理它。 以下函數接受兩種輸入格式 - 單個向量或多個標量輸入,並且應該在Matlab和Octave中都有效:
function divisor = gcd_vect(a, varargin)
if ~isempty(varargin)
a = [a, varargin{:}];
elseif length(a) == 1
divisor = a;
return;
end
divisor = gcd(a(1), gcd_vect(a(2:end)));
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.