Esiste una funzione MATLAB incorporata per scoprire se una matrice contiene un determinato valore? (ala del PHP in_array()
)La funzione per "la matrice contiene il valore X?"
risposta
Molti modi per farlo. ismember è il primo che viene in mente, dal momento che si tratta di un'azione di appartenenza imposta che si desidera prendere. Così
X = primes(20);
ismember([15 17],X)
ans =
0 1
Dal momento che 15 non è primo, ma 17 è, ismember ha svolto bene il suo lavoro qui.
Naturalmente, trovare (o qualsiasi) funzionerà anche. Ma questi non sono vettorizzati nel senso che è stato. Possiamo testare per vedere se 15 è nel set rappresentato da X, ma per testare entrambi i numeri prenderà un ciclo, o test successivi.
~isempty(find(X == 15))
~isempty(find(X == 17))
o,
any(X == 15)
any(X == 17)
Infine, rilevo che i test per i valori esatti sono pericolose se i numeri possono essere veri galleggianti. I test contro i valori interi come ho mostrato sono facili. Ma i test contro i numeri in virgola mobile dovrebbero solitamente utilizzare una tolleranza.
tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
Il più veloce dei tre sembra essere "qualsiasi". Ma potresti volerlo misurare tu stesso (usando 'tic' e' toc'). – Lewistrick
Per i valori in virgola mobile, se si utilizza almeno R2015a, è sufficiente usare ['ismembertol'] (http://stackoverflow.com/a/28907857/2778484). – chappjc
si può fare:
A = randi(10, [3 4]); %# a random matrix
any(A(:)==5) %# does A contain 5?
per ottenere il risultato in un vettorializzare modo, l'uso:
any(bsxfun(@eq, A(:), [5 7 11])
o come @woodchips suggerisce:
ismember([5 7 11], A)
perché stai usando [5 7 11] come argomento in ismember – Jordan
@Jordan: la risposta restituita è una matrice logica (vero/falso) della stessa dimensione dell'argomento, che indica se la matrice 'A' contiene ognuna di quelle valori (es. '[true, true, false]' che significa 'A' contiene i valori' 5' e '7' ma non' 11'). – Amro
ora ho capito, grazie – Jordan
Se avete bisogno di controllare se gli elementi di un vettore sono in un altro, la soluzione migliore è ismember
come detto in altre risposte.
ismember([15 17],primes(20))
Tuttavia, quando si tratta di numeri in virgola mobile, o semplicemente desidera avere vicino le partite (+ - 1000 è anche possibile), la soluzione migliore che ho trovato è il abbastanza efficiente File Exchange Submission: ismemberf
Dà un esempio molto pratico:
[tf, loc]=ismember(0.3, 0:0.1:1) % returns false
[tf, loc]=ismemberf(0.3, 0:0.1:1) % returns true
Anche se la tolleranza di default dovrebbe di norma essere sufficiente, ti dà maggiore flessibilità
ismemberf(9.99, 0:10:100) % returns false
ismemberf(9.99, 0:10:100,'tol',0.05) % returns true
Per i dati in virgola mobile, è possibile utilizzare il nuovo ismembertol
function, che calcola l'appartenenza allo con una tolleranza specificata. È simile alla funzione ismemberf
trovata in File Exchange, tranne per il fatto che ora è incorporata in MATLAB. Esempio:
>> pi_estimate = 3.14159;
>> abs(pi_estimate - pi)
ans =
5.3590e-08
>> tol = 1e-7;
>> ismembertol(pi,pi_estimate,tol)
ans =
1
Per dati in virgola mobile in cui può essere desiderata una tolleranza, si noti che la versione R2015a ha aggiunto nuove funzionalità per gestire questo con una singola funzione incorporata.Le soluzioni accettate per i dati con valori interi sono grandi, ma per i float, passa a [questa risposta] (http://stackoverflow.com/a/28907857/2778484). Ci scusiamo per l'auto-promozione, ma è una grande aggiunta a MATLAB dopo anni di domande. – chappjc