2013-04-19 5 views
5

Ho notato vari casi in Matlab e ottava in cui le funzioni accettano sia matrici che vettori, ma non fa la stessa cosa con i vettori come con le matrici.Incoerenze di matrice/vettore "wat" di ottava e Matlab

Questo può essere frustrante perché quando si immette una matrice con un numero variabile di righe/colonne, può essere interpretata come un vettore e fare qualcosa che non ci si aspetta quando l'altezza/larghezza è 1 per il debug difficile e casi limite condizionali strani.

ti elenco alcune che ho trovato, ma sono curioso di ciò che gli altri le persone hanno incontrato

(Nota:. Sto solo cercando per i casi in cui il codice accetta matrici come input valido Tutto ciò che solleva un'eccezione quando una matrice non vettoriale è dato come argomento non conta)

1) "diag" può essere usato per indicare diagonale di una matrice o di trasformare un vettore in una matrice diagonale

da il primo è generalmente usato solo per matrici quadrate, non è così eclatante in MATLAB, ma in Octave può essere particolarmente doloroso quando Octave interpone a All'inizio ctor con un elemento diverso da zero e tutto zeri altro come una "matrice diagonale" cioè

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

2) indicizzazione in una riga vettore con Logicals restituisce una riga vettore

indicizzazione in qualsiasi altra cosa con Logicals rendimenti un vettore colonna

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

3) indicizzazione in un vettore v con un vettore indice i restituisce un vettore della stessa (riga/col) tipo as v. Ma se uno vo i è una matrice, il valore restituito ha le stesse dimensioni di me

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

4) max, min, ecc somma operare sulle colonne di una matrice M individiually meno M è 1xn nel qual caso essi operano su M come una singola riga vettore

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

max è particolarmente negativo poiché non può nemmeno prendere una dimensione come argomento (a differenza della somma)

Quali altri casi di questo tipo dovrei fare attenzione quando si scrive codice ottava/matlab?

+0

Giusto per chiarire: è possibile specificare la dimensione per max/min: 'min (rand (3), [], 1)' 'o max (rand (3), [], 2)' – Amro

risposta

1

Ogni lingua ha i suoi concetti. Un punto importante di questo linguaggio è molto spesso pensare alle matrici come a una matrice di vettori, a ciascuna colonna una voce. Le cose cominceranno ad avere un senso allora. Se non vuoi questo comportamento, usa matrix(:) come argomento per quelle funzioni che passeranno un singolo vettore, piuttosto che una matrice. Per esempio:

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

    23 24 25 21 22 

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

1) Questo non è vero con almeno Octave 3.6.4. Non sono sicuro al 100% ma potrebbe essere correlato a this bug che è già stato risolto.

2) Se si indice con valori booleani, verrà considerata una maschera e trattata come tale. Se si indice con valori non booleani, viene considerato come indici per i valori. Questo ha perfettamente senso per me.

3) Questo non è vero. Il reso ha sempre la stessa dimensione dell'indice, indipendentemente se si tratta di una matrice o di un vettore. L'unica eccezione è che se l'indice è un vettore, l'output sarà una singola riga.L'idea è che l'indicizzazione con un singolo vettore/matrice restituisce qualcosa della stessa dimensione:

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 fa prendere come argomento dimensione almeno in ottava. Dal testo della guida 3.6.4 di max:

Per un argomento vettore, restituire il valore massimo. Per un argomento matrice , restituire il valore massimo di ogni colonna, come vettore riga, o dimensione DIM se definito, nel qual caso Y deve essere impostato su matrice vuota (altrimenti viene ignorato).

Il resto si applica come ho detto nell'introduzione. Se fornisci una matrice, penserà a ciascuna colonna come un set di dati.

+2

io no pensa di aver capito cosa stavo chiedendo. Mi stavo generalmente lamentando che i vettori non sono trattati come matrici (mentre sembrava che il mio problema fosse che le matrici non sono trattate come vettori) Nel caso 2, sto solo indicizzando con i booleani, mai con i numeri (non in entrambi i casi), tuttavia si ritorna un vettore riga e l'altro un vettore colonna. Nel caso 3, l'eccezione che citi è esattamente ciò di cui mi lamento. Se ho una matrice con cui ho bisogno di indicizzare, ma la matrice ha un numero variabile di colonne, allora devo scrivere un'istruzione if per quell'unica eccezione con solo 1 – dspyz

0

1) Come sottolineato dall'altro utente, questo non è vero con Octave> = 3.6.4.

Nel caso 2) la regola è per i vettori, tornare sempre la stessa forma del vettore, per altro restituire un vettore colonna, prendere in considerazione:

>> 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 

Si può vedere che questo ha un senso dal momento che i vettori hanno un cancella la 'direzione', ma altre matrici a forma non lo fanno quando rimuovi elementi. EDIT: in realtà ho appena controllato e Octave non sembra funzionare in questo modo esattamente, ma probabilmente dovrebbe.

3) Ciò è coerente con 2). Essenzialmente, se si fornisce una lista di indici, la direzione del vettore indicizzato viene preservata. Se fornisci indici con una forma come una matrice, la nuova informazione è la forma della matrice dell'indice utilizzata. Questo è più flessibile, dal momento che puoi sempre fare a(b(:)) per mantenere la forma di a se lo desideri. Si può dire che non è coerente, ma ricorda che l'indicizzazione con le logiche può ridurre il numero di elementi da restituire, quindi non possono essere rimodellati in questo modo.

4) Come sottolineato in un commento, è possibile specificare la dimensione per max/min per operare su: min(rand(3),[],1) o max(rand(3),[],2), ma in questo caso ci sono problemi 'legacy' con queste funzioni, che i dati di nuovo a quando erano prima creato e ora sono molto difficili da cambiare senza sconvolgere le persone.