2013-04-19 16 views
5

Ich habe verschiedene Fälle in Matlab und Oktave bemerkt, wo Funktionen sowohl Matrizen und Vektoren akzeptieren, aber nicht dasselbe mit Vektoren tun, wie es mit Matrizen tut.Octave und Matlab "Wat" Matrix/Vektor Inkonsistenzen

Dies kann frustrierend sein, denn wenn Sie eine Matrix mit einer variablen Anzahl von Zeilen/Spalten eingeben, könnte es als Vektor interpretiert werden und etwas tun, was Sie nicht erwarten, wenn die Höhe/Breite 1 für schwieriges Debuggen und macht seltsame bedingte Randfälle.

Ich werde ein paar Liste die ich gefunden habe, aber ich bin neugierig, was andere Leute in

(Hinweis ausgeführt haben. Ich bin nur für die Fälle, wo Code-Matrizen als gültige Eingabe akzeptiert alles, was wenn eine Ausnahme auslöst ein nicht-Vektormatrix gegeben wird als Argument nicht zählt)

1) „diag“ kann bedeuten, die verwendet werden diagonal aus einer Matrix oder schalten einen Vektor in eine diagonale Matrix

Seit Ersteres wird im Allgemeinen nur für quadratische Matrizen verwendet, in Matlab ist es nicht so ungeheuerlich, aber in Octave kann es besonders schmerzhaft sein, wenn Octave interpetiert Ctor beginnend mit einem Nicht-Null-Element und alles andere Nullen als „Diagonalmatrix“, dh

t=eye(3); 
size(diag(t(:,3))) == [3,3] 
size(diag(t(:,2))) == [3,3] 
size(diag(t(:,1))) == [1,1] 

2) Indexieren in einen Zeilenvektor mit Logicals Gibt einen Zeilenvektor

Indexieren in irgendetwas anderes mit Logicals kehrt

ein Spaltenvektor
a = 1:3; 
b = true(1,3); 
size(a(b)) == [1, 3] 
a = [a; a]; 
b = [b; b]; 
size(a(b)) == [6, 1] 

3) Indexieren in einen Vektor v mit einem Indexvektor i einen Vektor der gleichen (Zeile/Spalte zurückgibt) als V-Typ. Aber wenn entweder V oder i eine Matrix ist, den Rückgabewert hat die gleiche Größe wie ich.

a = 1:3; 
b = a'; 
size(a(b)) == [1, 3] 
b = [b,b]; 
size(a(b)) == [3, 2] 

4) max, min, sum usw. arbeiten auf der Spalten einer Matrix individiually M, es sei denn M in welchem ​​Fall sie arbeiten auf M als einreihige Vektor

a = 1:3 
size(max(a)) == [1, 1] 
a = [a;a] 
size(max(a)) == [1, 3] 

max ist 1xN ist besonders schlecht, da es nicht einmal eine Dimension als Argument nehmen kann (im Gegensatz zur Summe)

Welche anderen Fälle sollte ich beachten, wenn ich Octave/Matlab-Code schreibe?

+0

nur um zu verdeutlichen: Sie können Dimension für max/min angeben: 'min (rand (3), [], 1)' oder 'max (Rand (3), [], 2)' – Amro

Antwort

1

Jede Sprache hat ihre eigenen Konzepte. Ein wichtiger Punkt dieser Sprache ist es, Matrizen oft als eine Anordnung von Vektoren zu betrachten, jede Spalte als einen Eintrag. Die Dinge werden dann anfangen, Sinn zu ergeben. Wenn Sie dieses Verhalten nicht möchten, verwenden Sie matrix(:) als Argument für die Funktionen, die einen einzelnen Vektor statt einer Matrix übergeben. Zum Beispiel:

octave> a = magic (5); 
octave> max (a) 
ans = 

    23 24 25 21 22 

octave> max (a(:)) 
ans = 25 

1) Dies gilt nicht für mindestens Octave 3.6.4. Ich bin nicht 100% sicher, aber möglicherweise bezogen auf this bug, die bereits behoben wurde.

2) Wenn Sie mit booleschen Werten indizieren, wird dies als Maske betrachtet und als solche behandelt. Wenn Sie mit nicht booleschen Werten indizieren, werden sie als Indizes für die Werte behandelt. Das macht Sinn für mich.

3) Dies ist nicht wahr. Der zurückgegebene Wert hat immer die gleiche Größe wie der Index, unabhängig davon, ob es sich um eine Matrix oder einen Vektor handelt. Die einzige Ausnahme ist, dass wenn der Index ein Vektor ist, die Ausgabe eine einzelne Zeile ist.Die Idee ist, dass die Indizierung mit einem einzelnen Vektor/Matrix etwas von der gleichen Größe zurückgibt:

octave> a = 4:7 
a = 

    4 5 6 7 

octave> a([1 1]) 
ans = 

    4 4 

octave> a([1 3]) 
ans = 

    4 6 

octave> a([1 3; 3 1]) 
ans = 

    4 6 
    6 4 

4) max dauert Dimension als Argument zumindest in Octave. Aus dem 3.6.4 Hilfetext von max:

Geben Sie für ein Vektorargument den Maximalwert zurück. Geben Sie für ein Matrixargument den Maximalwert aus jeder Spalte als Zeilenvektor oder über der Dimension DIM zurück, wenn definiert, wobei Y auf der leeren Matrix gesetzt werden sollte (andernfalls wird sie ignoriert).

Der Rest gilt wie gesagt auf dem Intro. Wenn Sie eine Matrix angeben, wird jede Spalte als Datensatz betrachtet.

+2

ich nicht Ich glaube, du hast verstanden, wonach ich gefragt habe. Ich beschwerte mich im Allgemeinen, dass Vektoren nicht als Matrizen behandelt werden (obwohl Sie mein Problem zu sein schienen, dass Matrizen nicht als Vektoren behandelt werden) In Fall 2 bin ich nur mit Booleans, nie mit Numerik (nicht in jedem Fall), doch gibt man einen Zeilenvektor und den anderen einen Spaltenvektor zurück. In Fall 3 ist die Ausnahme, die Sie erwähnen, genau das, worüber ich mich beschwere. Wenn ich eine Matrix habe, mit der ich indizieren muss, aber die Matrix eine variable Anzahl von Spalten hat, dann muss ich eine if-Anweisung für diese eine Ausnahme mit nur 1 schreiben – dspyz

0

1) Wie vom anderen Benutzer angegeben, gilt dies nicht für Octave> = 3.6.4.

Im Fall 2) die Regel für Vektoren ist, kehren immer die gleiche Form des Vektors, für irgendetwas anderes ein Spaltenvektor zurückzukehren, betrachten:

>> a = reshape (1:3, 1,1,3) 

a(:,:,1) = 

    1.0000e+000 


a(:,:,2) = 

    2.0000e+000 


a(:,:,3) = 

    3.0000e+000 

>> b = true(1,3) 

b = 

    1×3 logical array 

    1 1 1 

>> a(b) 

ans(:,:,1) = 

    1.0000e+000 


ans(:,:,2) = 

    2.0000e+000 


ans(:,:,3) = 

    3.0000e+000 

>> a = [a;a] 

a(:,:,1) = 

    1.0000e+000 
    1.0000e+000 


a(:,:,2) = 

    2.0000e+000 
    2.0000e+000 


a(:,:,3) = 

    3.0000e+000 
    3.0000e+000 

>> b = [b;b] 

b = 

    2×3 logical array 

    1 1 1 
    1 1 1 

>> a(b) 

ans = 

    1.0000e+000 
    1.0000e+000 
    2.0000e+000 
    2.0000e+000 
    3.0000e+000 
    3.0000e+000 

Sie können sehen, dass dies Sinn macht, da Vektoren a haben Deaktivieren Sie "Richtung", aber andere geformte Matrizen nicht, wenn Sie Elemente entfernen. EDIT: eigentlich habe ich gerade überprüft und Octave scheint auf diese Weise nicht genau funktionieren, aber wahrscheinlich sollte.

3) Dies steht im Einklang mit 2). Wenn Sie eine Liste von Indizes angeben, bleibt die Richtung des indizierten Vektors erhalten. Wenn Sie Indizes mit einer Form wie eine Matrix angeben, wird die neue Information die Indexmatrixform verwendet. Dies ist flexibler, da Sie a(b(:)) immer tun können, um die Form von a zu erhalten, wenn Sie dies wünschen. Sie können sagen, dass es nicht konsistent ist, aber denken Sie daran, dass die Indizierung mit logischen Elementen die Anzahl der zurückzugebenden Elemente reduzieren kann, so dass sie auf diese Weise nicht umgestaltet werden können.

4) Wie in einem Kommentar darauf hingewiesen, können Sie Dimension für max/min angeben arbeiten auf: min(rand(3),[],1) oder max(rand(3),[],2), aber in diesem Fall gibt es Probleme ‚Legacy‘ mit diesen Funktionen, auf die Daten zurück, wenn sie waren zuerst erstellt und jetzt sind sehr schwer zu ändern, ohne Menschen zu verärgern.