L'ipotesi fatta sulla ragione per la quale lo script non dà il risultato atteso è corretta.
Modificando il numero di righe della matrice all'interno del loop rende non più coerente l'indicizzazione.
Una possibile soluzione consiste nel dividere il problema in due parti:
[1] individuazione dell'indice delle righe da eliminare
[2] eliminazione delle righe
Per individuare l'indice delle righe da eliminare si può procedere nel modo seguente:
[1] estrarre in un vettore la prima colonna (questo passo non è strettamente necessario, ma semplifica la notazione del codice)
[2] utilizzare la funzione built-in "find" per trovare gli indici degli elementi del vettore che verificano la condizione
[3] utilizzare gli indici ricavati al passo precedente per cancellare le righe
La complessità della porzione di codice che, tramite la funzione "find" individua gli indici varia in funzione del tipo di condizione:
[1] il caso più semplice è costituito dal caso in cui la condizione sia: eliminare le righe il valore della prima colonna delle quali sia maggiore (minore) di una soglia
[2] il caso intermedio è rappresentato dal caso nel quale la condizione sia: eliminare le righe il valore della prima colonna delle quali sia compreso all'interno di un intervallo
[2] il caso più complicato (relativamente complicato) è rappresentato dal caso nel quale la condizione sia: eliminare le righe il valore della prima colonna delle quali sia esterno ad un intervallo
Caso 1: cancellazione righe con valore prima colonna INFERIORE SOGLIA
idx=find(prima_colonna < soglia);
m(idx)=[];
gli indici individuati dalla funzione "find" (prima_colonna è il vettore che contiene la prima colonna della matrice) corrispondono agli indici delle righe da eliminare.
Caso 2: Cancellazione righe con valore prima colonna COMPRESO NELL'INTERVALLO
idx_inf=find(prima_colonna > soglia_sup);
idx_sup=find(prima_colonna < soglia_inf);
idx=sort([idx_inf;idx_sup]);
m1=m(idx,:);
si può invocare due volte la funzione "find" per trovare gli indici corrispondenti ai valori, rispettivamente, inferiori e superiori agli estremi dell'intervallo (soglia_inf;soglia_sup).
Gli indici vengono quindi uniti a creare la lista complessiva degli indici delle righe ella matrice risultante dopo la cancellazione
Caso 3: Cancellazione righe con valore prima colonna ESTERNO ALL'INTERVALLO
idx_inf=find(prima_colonna > soglia_inf);
idx_sup=find(prima_colonna < soglia_sup);
a1=zeros(1,length(prima_colonna));
a2=a1;
a1(idx_inf)=idx_inf;
a2(idx_sup)=idx_sup;
idx=find((a1.*a2) > 0);
m1=m(idx,:);
La prima chiamata alla funzione "find" individua gli indici delle righe con valore della prima colonna superiore alla soglia inferiore.
La seconda chiamata alla funzione "find" individua gli indici delle righe con valore della prima colonna inferiore alla soglia superiore.
Gli indici delle righe da eliminare saranno quelli non comuni alle due chiamate.
Per individuarli si possono costruire due vettori di "0" ("a1" e "a2") ai quali vengono, successivamente assegnati i valori degli indici trovati dalla funzione "find" nelle corrispondenti locazioni.
Il prodotto elemento per elemento dei due vettori darà un risultato diverso da 0 nel caso l'indice compaia in entrambi i vettori; questo, individuato tramite un'altra chiamata alla funzione "find" sarà l'indice della riga da conservare.
Il tutto, ovviamente, si può realizzare anche tramite "cicli for", ma per matrici di grandi dimensioni, i tempi di esecuzione risultano molto più lunghi.
La soluzione proposta è stata implementata nello script che segue.
%
% Definizione matrice di esempio
%
m=magic(9);
m=m(randperm(9),:);
%
% Definizione matrice di valori "NaN" (solo per debug). Alle matrice "m1"
% verranno sovrascritte le righe che NON dovranno essere eliminate di
% conseguenza le righe con valori NaN corrisponderanno alle righe da
% eliminare
%
m1=NaN(size(m));
%
% Estrazione dei valori della prima colonna della matrice di input
%
prima_colonna=m(:,1)
%
% Cancellazione righe con valore prima colonna ESTERNO ALL'INTERVALLO
% (soglia_inf;soglia_sup)
%
%
% Definizione dei valori di soglia
%
soglia_inf=28;
soglia_sup=64;
idx_inf=find(prima_colonna > soglia_inf);
idx_sup=find(prima_colonna < soglia_sup);
a1=zeros(1,9);
a2=a1;
a1(idx_inf)=idx_inf;
a2(idx_sup)=idx_sup;
idx=find((a1.*a2) > 0);
m
m2=m(idx,:)
m1(idx,:)=m(idx,:)
[soglia_inf soglia_sup]
%
% Cancellazione righe con valore prima colonna COMPRESO NELL'INTERVALLO
% (soglia_inf;soglia_sup)
%
%
% Definizione dei valori di soglia
%
soglia_inf=28;
soglia_sup=64;
m1=NaN(size(m));
idx_inf=find(prima_colonna > soglia_sup);
idx_sup=find(prima_colonna < soglia_inf);
idx=sort([idx_inf;idx_sup]);
m
m2=m(idx,:)
m1(idx,:)=m(idx,:)
[soglia_inf soglia_sup]
%
% Cancellazione righe con valore prima colonna SUPERIORE SOGLIA
%
%
% Definizione dei valori di soglia
%
soglia=33;
m1=NaN(size(m));
idx=find(prima_colonna < soglia);
m
m2=m(idx,:)
m1(idx,:)=m(idx,:)
[soglia]
%
% Cancellazione righe con valore prima colonna INFERIORE SOGLIA
%
%
% Definizione dei valori di soglia
%
soglia=42;
m1=NaN(size(m));
idx=find(prima_colonna > soglia);
m
m2=m(idx,:)
m1(idx,:)=m(idx,:)
[soglia]
Hope this helps.