2016-06-01 10 views
0

Können Sie mir helfen, einen sehr schnellen Algorithmus in Matlab aufzuschreiben, was macht folgendes: Ich habe 2 Vektoren, A der Dimension nx1 und B der Dimension nx1. Ich möchte C von Dimension konstruieren 2nx1 so dassUnter alternativ Elemente zweier Vektoren und komponieren sie in Matlab

C(1)=A(1), C(2)=B(1), C(3)=A(2), C(4)=B(2), C(5)=A(3), C(6)=B(3), ... 

ich aber über

C=[]; 
for j=1:n 
    C=[C; [A(j) B(j)]']; 
end 

Haben Sie etwas schneller und effizienter wissen?

Beispiel:

n=9 
A=[1 3 5 7 9 11 13 15 17]'; 
B=[2 4 6 8 10 12 14 16 18]'; 
C=[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]'; 
+0

Haben Sie kein * schnell * Antwort wollen? Ich habe einen Benchmark hinzugefügt, der die relative Leistung zeigt. – Suever

Antwort

3

in Matlab, sind Indexoperationen im Allgemeinen schneller als for-Schleifen.
Was eine 2nx1 Matrix erste Konstrukt ist und verwenden Sie dann die Indizierung ich tun würde, um die Werte zuweisen:

C = zeros(2*n,1); 
C(1:2:end) = A; 
C(2:2:end) = B; 
+1

Initialisierende 'c' mit' c (2 * n, 1) = 0' ist noch schneller (obwohl zugegebenermaßen hackish) –

+0

Interessant ... wusste das nicht. – ThP

+0

Siehe [diese Antwort] (http://Stackoverflow.com/a/14195309/2586922) und den verknüpften Beitrag @ThP –

5

Normalerweise werden Sie in einer Schleife zu einem Array anhängt Daten zu vermeiden, wie Sie es geschrieben haben, wie dieser Speicher wie Sie jede Zeit durch die Schleife neu zu vergeben hat erweitern Die Variable.

Am einfachsten wäre es, sie beide in Zeilenvektoren mit (:).' zu konvertieren, sie entlang der ersten Dimension zu verketten und dann zu einem Spaltenvektor unter Verwendung reshape abzuflachen. Aufgrund der MATLAB-Spalten-Major-Reihenfolge werden die Werte A und B automatisch voneinander getrennt, um C zu erstellen.

C = reshape(cat(1, A(:).', B(:).'), [], 1) 

Benchmark

Soweit, ob dies schneller als Indizierung (@ ThP Antwort), hier ein kurzer Test-Benchmark der beide.

sizes = round(linspace(100, 10000, 100)); 

times1 = zeros(size(sizes)); 
times2 = zeros(size(sizes)); 

for k = 1:numel(sizes) 
    A = rand(sizes(k), 1); 
    B = rand(sizes(k), 1); 

    times1(k) = timeit(@()combine1(A,B)); 
    times2(k) = timeit(@()combine2(A,B)); 
end 

figure 
plot(sizes, times1) 
hold on 
plot(sizes, times2) 
legend('cat + reshape', 'Indexing') 

function C = combine1(A, B) 
    C = reshape(cat(1, A(:).', B(:).'), [], 1); 
end 

function C = combine2(A,B) 
    C = zeros(2*numel(A),1); 
    C(1:2:end) = A; 
    C(2:2:end) = B; 
end 

enter image description here

+0

Schön. Es wäre interessant zu vergleichen, mit 'C (2 * n, 1) = 0 'wie von Luis Mendo empfohlen – ThP

+0

@ ThP Ich habe es verglichen. Kaum ein Unterschied. Http://i.imgur.com/1DqE2gc.png – Suever

+1

Es ist nur Mikro-Optimierung, aber das Folgende ist etwas schneller 'C = [A (:). '; B (:). ']; C = C (:); 'Die Annahme ist, dass es sich nur um einen Funktionsaufruf handelt (da der Unterschied zu" cat + reshape "ungefähr konstant ist), aber wenn das Problem aus vielen Funktionsaufrufen besteht, kann dies von Bedeutung sein. – patrik

Verwandte Themen