2016-05-11 13 views
1

Angenommen, ich habe eine Matrix Ein in Fortran der (n, m), und einen Vektor B die (1, m). Ich möchte den Vektor B von allen Zeilen von A subtrahieren, ohne eine Schleife zu verwenden.subtrahiert, um einen Vektor aus einer Matrix (zeilenweise)

Ab jetzt habe ich nur in der Lage gewesen, es mit einer Schleife zu tun:

PROGRAM Subtract 
IMPLICIT NONE 

REAL, DIMENSION(250,5) :: A 
INTEGER, DIMENSION(1,5) :: B 
INTEGER :: i 

B(1,1) = 1 
B(1,2) = 2 
B(1,3) = 3 
B(1,4) = 4 
B(1,5) = 5 

CALL RANDOM_NUMBER(A) 

do i=1,250 
    A(i,:) = A(i,:) - B(1,:) 
end do 


end program 

Aber das ist sehr ineffizient. Z.B. In Matlab kann man es mit der Funktion Reptmat in einer Zeile machen. Irgendwelche Vorschläge für einen besseren Weg, dies zu tun?

+0

Dies ist in der Tat ein Duplikat dieses Posts. Ich suchte das Forum, aber wir verwendeten sehr unterschiedliche englische Terminologie. – phdstudent

+1

Die Suche ist viel einfacher, wenn Sie die Antwort kennen. Aber das ist ein Punkt des Duplikatsystems: verschiedene Wege, dieselbe Frage zu formulieren, die auf einen einzigen Satz von Antworten hinweist. – francescalus

Antwort

1

Sie können spread für diesen Einsatz:

A = A - spread(B(1,:), 1, 250) 

Bitte beachten Sie, dass Fortran Spalte-Dur ist, so ist B(1,:) im Allgemeinen im Speicher nicht zusammenhängend, und ein temporäres Array erstellt wird. [Es ist in Ihrem Fall, da Sie nur eine Spalte haben - aber immer noch erwähnenswert. ]

In der gleichen Weise ist die Schleife über den ersten Index von A ineffizient. Es würde wahrscheinlich die Dinge beschleunigen, wenn Sie Ihre Matrizen transponieren würden. Dann könnte eine Loop-Lösung sogar schneller sein als die mit spread. (Aber das hängt vom Compiler ab.)

+0

Danke. Funktioniert wie Charme. Und danke für den Effizienzvorschlag. – phdstudent