Problema con uno struct

di il
23 risposte

Problema con uno struct

Salve a tutti sto realizzando uno script che mi serva per fare l'identificazione in frequenza di un sistema termico. Ho però un problema devo calcolare il modulo dei 4 sensori che ho utilizzato per misurare le temperature.
Vi allego lo script
misure='mhz';
files='frequenza';
freq={'05' '07' '09' '1' '2' '3' '5' '6' '7' '8' '9' '9' '10' '20' '30' '40' '50' };
Hvf=[];

for i=1:(size(freq,2)); %ciclo atto a scorrere tutte le acquisizioni fatte nella condizione scelta
load(cat(2,files,freq{i},misure));
data=eval(cat(2,files,freq{i},misure));
p=data;
Hv=[];
Imax=5;
N=127;

for v=1:length(p(:,1))
I(v)=p(v,8);
Th(v)=p(v,3); %Valore della temperatura del lato caldo (sensor8)
Tc(v)=p(v,2); %Valore della temperatura del lato freddo (sensor2)
%calculation parameters
[SM,RM,KM]=Parametri(Imax,N,Tc(v),Th(v));
SMrec(v)=SM;
RMrec(v)=RM;
KMrec(v)=KM;
%calculation heat flux
Hv(v,1)=SM*I(v)*Th(v)+0.5*RM*I(v)^2-KM*(Th(v)-Tc(v)); %calcolo di Qh pag 15
end
Hvf{i}=Hv;
end
max_Hvf=cellfun(@max,Hvf);
min_Hvf=cellfun(@min,Hvf);
for a=1:17
modulosensore1=20*log10(max(p(:,4))-max_Hvf(:,a))/(min(p(:,4))-min_Hvf(:,a));
end
Il mio problema è quando vado a calcolare il modulosensore 1, io vorrei che il valore di quel max_Hvf e anche del minimo cambiasse di volta in volta poichè io ho una cella di valori.
Spero di essermi spiegato in maniera adeguata.

23 Risposte

  • Re: Problema con uno struct

    Il mio problema è quando vado a calcolare il modulosensore 1, io vorrei che il valore di quel max_Hvf e anche del minimo cambiasse di volta in volta poichè io ho una cella di valori
    Nel corso del ciclo for che hai scritto per il calcolo del valore di modulosensore1, vengono già utilizzati tutti i valori contenuti negli array max_Hvf e min_Hvf nel corso delle varie iterazioni, infatti hai scritto:
    max_Hvf(:,a)
    
    e
    min_Hvf(:,a)
    così che, ad ogni iterazione, al variare dell'indice "a" utilizzi lo "a-esimo" elemento dei due array.

    Puoi verificarlo facilmente eseguendo passo passo ogni iterazione con il debug.

    Tieni presente che, avendo il cellarray Hvf una sola dimensione, in particolare (1 x length(freq)), anche gli array max_Hvf e min_Hvf avranno dimensione (1 x length(freq)).

    Di conseguenza, quando li utilizzi all'interno di un ciclo for, puoi fare riferimento ai loro contenuti così:
    max_Hvf(a)
    min_Hvf(a)
    
    Infatti, dal momento che hanno una sola riga, l'uso di ":" è inutile.

    Inoltre, nel corso delle varie iterazioni, i valore di max(p(:,4)) e min(p(:,4)) non cambiano, per cui possono essere calcolati una volta sola, prima del ciclo for[/] ed assegnati a due variabili da utilizzare all'interno del ciclo.

    Il problema, nell'implementazione del ciclo for consiste nel fatto che, ad ogni iterazione il valore calcolato di modulosensore1 viene sovrascritto.

    Non so come debba essere calcolato il valore finale di modulosensore1 (es. somma di tutti i valori calcolati in ogni iterazione, media dei valori, ecc.), ma l'istruzione deve necessariamente essere modificata in modo che utilizzi "tutti" i valori calcolati per modulosensore1.

    Possibili modifiche potrebbero essere:

    modulosensore1=[];
    for a=1:17
       modulosensore1[a]=20*log10(max(p(:,4))-max_Hvf(:,a))/(min(p(:,4))-min_Hvf(:,a));
    end
    
    in questo caso, al termine del ciclo for otterrai un array contenente tutti i valori di modulosensore1 calcolati ad ogni iterazione.

    Oppure
    modulosensore1=0;
    for a=1:17
       modulosensore1=modulosensore1+20*log10(max(p(:,4))-max_Hvf(:,a))/(min(p(:,4))-min_Hvf(:,a));
    end
    
    In questo caso il valore finale di modulosensore1 sarà la somma dei valori calcolati nel corso delle varie iterazioni.

    Queste sono due delle tante possibili soluzioni, sta a te definire quella giusta la quale, però, dovrebbe considerare tutti i valori di modulosensore1 calcolati in ogni iterazione.

    Hope this helps.
  • Re: Problema con uno struct

    Grazie mille per la tua risposta. comunque ho usato la soluzione numero uno inserendo il tutto all'interno del primo ciclo for.
    Una cosa con l'istruzione cellfun è possibile farsi ritornare sia il valore che max che l'indice riferito al valore max?
  • Re: Problema con uno struct

    Per ottenere in output anche il valore dell'indice basta modificare l'istruzione come segue:
    [max_Hvf,idx]=cellfun(@max,Hvf)
    
    In questo caso il vettore idx conterrà gli indici delle posizioni dei valori massimi.

    Hope this helps.
  • Re: Problema con uno struct

    Grazie mille. e invece per avere la stessa cosa nella funzione max è sempre uguale?
  • Re: Problema con uno struct

    Assumo che tu ti riferisca alla ricerca degli indici dei minimi ad ogni modo,
    [*] hai provato ad usare la funzione? Cosa è successo?
    [*] hai ottenuto il risultato atteso?
    [*] hai ottenuto un messaggio di errore?

    La funzione cellfun si limita ad invocare la funzione specificata come primo parametro per ognuno degli elementi del cellarray specificato come secondo parametro.

    I valori in output dalla funzione cellfun sogno gli stessi delle funzioni indicate come primo parametro.

    Dal momento che le funzioni max e min possono ritornare (anche) gli "indici posizione":
    [max_Hvf,idx_max]=cellfun(@max,Hvf)
    [max_Hvf,idx_min]=cellfun(@min,Hvf)
    
    idx_max: conterrà gli indici posizione dei valori massimi
    idx_min: conterrà gli indici posizione dei valori minimi

    Hope this helps.
  • Re: Problema con uno struct

    No no io mi riferivo al fatto che se si ha un vettore e io voglio calcolare il max utilizzo la funzione max , ma se volessi anche l'indice qual'è la sintassi corretta? è simile a quella utilizzata nelle celle?
    Altra domanda vorrei creare un vettore che contenga il valore corrispondente all'indice trovato precedentemente della 1 colonna del vettore p.
  • Re: Problema con uno struct

    Per quanto riguarda la prima parte della domanda:
    ma se volessi anche l'indice qual'è la sintassi corretta? è simile a quella utilizzata nelle celle
    la risposta è sì:
    >> help max
    max Largest component.
    For vectors, max(X) is the largest element in X. For matrices,
    max(X) is a row vector containing the maximum element from each
    column. For N-D arrays, max(X) operates along the first
    non-singleton dimension.

    [Y,I] = max(X) returns the indices of the maximum values in vector I.
    If the values along the first non-singleton dimension contain more
    than one maximal element, the index of the first one is returned.
    [ ... ]
    Per quanto riguarda la seconda parte della domanda
    Altra domanda vorrei creare un vettore che contenga il valore corrispondente all'indice trovato precedentemente della 1 colonna del vettore p
    non sono sicuro di avere capito cosa intendi; un vettore contenente una serie di indici può essere usato per modificare l'ordine dei valori di un altro vettore o per crearne uno.
    
    % Creazione di un vettore con 10 numeri interi
    a=randi(10,1,10)
    % Creazine di un vettore di indici
    idx=randperm(10)
    % Applicazione del vettore di indici: nella Command Window vengono
    % stampati gli elemenrti del vettore "a" nell'ordine definito dal vettore
    % di indici "idx"
    a(idx)
    % CReazione di un vettore contenente gli elementi del vettore "a" disposti
    % secondo l'ordine definito del vettore di indici "idx"
    b=a(idx)
    
    Output nella Command Window:
    a =
        10     2    10     7     1     3     6    10    10     2
    idx =
         5     6     3    10     8     4     7     2     9     1
    ans =
         1     3    10     2    10     7     6     2    10    10
    b =
         1     3    10     2    10     7     6     2    10    10
    Hope this helps.
  • Re: Problema con uno struct

    Ti spiego meglio io ho un vettore p che ha 7 colonne, io voglio lavorare solo sulla prima colonna. Vorrei prendere l'elemento della 1 colonna che ha indice trovato precedente ed andarlo ad inserire in un nuovo vettore.
  • Re: Problema con uno struct

    La risposta alla tua domanda è già contenuta nella domanda stessa:
    ho un vettore p che ha 7 colonne, io voglio lavorare solo sulla prima colonna. Vorrei prendere l'elemento della 1 colonna che ha indice trovato precedente ed andarlo ad inserire in un nuovo vettore
    Prova a tradurre in codice:

    "ho un vettore p che ha 7 colonne"
    % Esempio di una matrice, 10 righe, 7 colonne
    p=randi(100,10,7);
    io voglio lavorare solo sulla prima colonna.
    
    % Estrazione della prima colonna dalla matrice "p" (questo passaggio non è strettamente necessario, ma serve per seguire la traduzione della domanda, passo passo
    tmp_v=p(:,1)
    Vorrei prendere l'elemento della 1 colonna che ha indice trovato precedente ed andarlo ad inserire in un nuovo vettore
    L'ordine dei passaggi in questa parte della domanda deve essere invertito

    ==> indice trovato precedente
    
    % Creazione di un vettore di esempio
    v=randi(100,1,10)
    % Identificazione del valore massimo e relativo indice
    [v_max,idx]=max(v)
    

    ==> Vorrei prendere l'elemento della 1 colonna che ha indice trovato precedente ed andarlo ad inserire in un nuovo vettore
    
    % Assegnazione del valore in posizione "idx" della prima colonna della matrice "p" nel vettore di output (assumendo di essere all'interno di un loop con indice "i" (es. i=2)
    i=2
    out_v(i)=tmp_v(idx)
    
    Volendo creare uno script completo:
    % Generazion della matrice "p"
    p=randi(100,10,7);
    % Inizializzazione del vettore di output
    nv=nan(1,10);
    for i=1:10
       % Generazione di un vetore di numeri random (interi)
       v=randi(100,1,10)
       % Identificazione del valore massimo e relativo indice
       [v_max,idx]=max(v)
       % Assegnazione allo i-esimo elemento del vettore di output del calore
       % della prima colonna della matrice "p" corrispondente all'indice idx
       nv(i)=p(idx,1)
    end
    
    Hope this helps.
  • Re: Problema con uno struct

    Rieccomi qui. Ecco come ho modificato lo script per quello che mi serviva
    misure='mhz';
    files='frequenza';
    freq={'05' '07' '09' '1' '2' '3' '5' '6' '7' '8' '9' '10' '20' '30' '40' '50' };
    Hvf=[];
    frequenza=[0.5, 0.7, 0.9, 1, 2, 3, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50]*10^-3;
    modulosensore1=zeros(1,16);
    modulosensore2=zeros(1,16);
    modulosensore3=zeros(1,16);
    modulosensore4=zeros(1,16);
    fasesens1=zeros(1,16);
    fasesens2=zeros(1,16);
    fasesens3=zeros(1,16);
    fasesens4=zeros(1,16);

    for i=1:(size(freq,2)); %ciclo atto a scorrere tutte le acquisizioni fatte nella condizione scelta
    load(cat(2,files,freq{i},misure));
    data=eval(cat(2,files,freq{i},misure));
    p=data;
    Hv=[];
    Imax=5;
    N=127;

    for v=1:length(p(:,1))
    I(v)=p(v,8);
    Th(v)=p(v,3); %Valore della temperatura del lato caldo (sensor8)
    Tc(v)=p(v,2); %Valore della temperatura del lato freddo (sensor2)
    %calculation parameters
    [SM,RM,KM]=Parametri(Imax,N,Tc(v),Th(v));
    SMrec(v)=SM;
    RMrec(v)=RM;
    KMrec(v)=KM;
    %calculation heat flux
    Hv(v,1)=SM*I(v)*Th(v)+0.5*RM*I(v)^2-KM*(Th(v)-Tc(v)); %calcolo di Qh pag 15
    end
    Hvf{i}=Hv;
    [max_Hvf,idx_max]=cellfun(@max,Hvf);
    Ti_max=p(idx_max,1);
    min_Hvf=cellfun(@min,Hvf);

    [max_p1,idxT1]= max(p(:,4));
    To_maxs1=p(idxT1,1);

    [max_p2,idxT2]= max(p(:,5));
    To_maxs2=p(idxT2,1);

    [max_p3,idxT3]= max(p(:,6));
    To_maxs3=p(idxT3,1);

    [max_p4,idxT4]= max(p(:,7));
    To_maxs4=p(idxT4,1);

    modulosensore1(i)=20*log10(max(p(:,4))-max_Hvf)/(min(p(:,4))-min_Hvf);
    modulosensore2(i)=20*log10(max(p(:,5))-max_Hvf)/(min(p(:,5))-min_Hvf);
    modulosensore3(i)=20*log10(max(p(:,6))-max_Hvf)/(min(p(:,6))-min_Hvf);
    modulosensore4(i)=20*log10(max(p(:,7))-max_Hvf)/(min(p(:,7))-min_Hvf);
    fasesens1=((Ti_max-To_maxs1)/(1/frequenza(i)));
    fasesens2=((Ti_max-To_maxs2)/(1/frequenza(i)));
    fasesens3=((Ti_max-To_maxs3)/(1/frequenza(i)));
    fasesens4=((Ti_max-To_maxs4)/(1/frequenza(i)));
    end

    Vi è però un problema quando esegue il calcolo di Ti_max in quando mi dice "Index exceeds matrix dimensions"; come potrei risolvere?
    Inoltre secondo voi quando va a calcolare le fasisens se metto frequenza nel calcolo utilizza la frequenza che ha indice i considerato del vettore frequenza?
    Grazie per le risposte
  • Re: Problema con uno struct

    Se non pubblichi i dati di input è impossibile far girare il tuo script e trovare l'errore (es. DropBox o simile, oppure direttamente nella domanda - se sono troppo grossi, nella domanda inseriscine una parte significativa che consenta di far girare lo script).

    Dovresti anche riportare il messaggio di errore completo.

    Una possibile spiegazione dell'errore (ma senza poter fare girare lo script è solo un supposizione) potrebbe essere che la matrice "p" abbia meno di 16 righe.

    Quante righe ha la matrice "p"?

    Dovresti provare ad eseguire lo script utilizzando il debugger fino ad individuare l'iterazione nel corso della quale si verifica il problema (o, in prima approssimazione, verificare il valore degli indici dei loop successivamente al verificarsi dell'errore).

    Hai provato a "debuggare" lo script?

    La seconda domanda ("Inoltre secondo voi quando va a calcolare le fasisens se metto frequenza nel calcolo utilizza la frequenza che ha indice i considerato del vettore frequenza?") purtroppo non riesco a capirla.

    Anche in questo caso, però:

    [*] hai provato a "mettere la frequenza ..."?
    [*] cosa è successo? Hai ottenuto dei messaggi di errore? Hai ottenuto dei risultati che non ti aspettavi?

    Se non hai provato ... prova.

    Nell'inserire del codice nelle domande dovresti formattarlo utilizzando le opzioni presenti nella toolbar posta sopra la finestra di edit (taso "Code": selezioni il codice che hai inserito e premi il bottone).

    Hope this helps.
  • Re: Problema con uno struct

    Allora ho provato a fare il debugger e mi dava errore appena andavo a calcolare Ti_max e l'errore era che mi dava era questo:
    Index exceeds matrix dimensions.
    Error in funzione (line 43)
    Ti_max=p(idx_max,1);

    per la seconda parte della domanda si ho provato e mi ha dato dei risultati che non mi aspettavo.
  • Re: Problema con uno struct

    Usare il debugger per "trovare" il punto nel quale si verifica l'errore (punto che, per altro viene evidenziato nel messaggio di errore) è solo il primo passo.

    Devi analizzare il messaggio di errore e cercare di capire quale ne sia il motivo e "dove" questo si generi (non sempre il problema che genera l'errore è nell'istruzione nel quale l'esecuzione si interrompe; quello, spesso, è il punto nel quale un errore generato in precedenza ha effetto).

    Ad ogni modo, assodato che il punto "critico" è l'istruzione:

    Ti_max=p(idx_max,1);

    Il messaggio di errore dice: "Index exceeds matrix dimensions."

    Cosa significa?
    Significa che, molto probabilmente, il valore di "idx_max" è maggiore del numero di righe della matrice "p".

    Hai provato a verificare quante righe ha la matrice "p"? (vedi risposta precedente "Una possibile spiegazione dell'errore (ma senza poter fare girare lo script è solo un supposizione) potrebbe essere che la matrice "p" abbia meno di 16 righe.

    Quante righe ha la matrice "p"?)


    Quindi:
    [*] quante righe ha la matrice "p"?
    [*] il valore di "idx_max" è maggiore del numero di righe della matrice "p"? Se sì, dove / perchè "idx_max" ha raggiunt un valore maggiore del numero di righe di "p"?

    Queste (ed altre simili) sono le domande ce devi porti analizzando il codice durante il debug.

    Di nuovo, se non pubblichi i dati di input (od una parte significativa di essi) non è possibile aiutarti.

    Per quanto riguarda la seconda parte della domanda:
    visto che la variabile "frequenza" è un array e che le istruzioni
    fasesens1=((Ti_max-To_maxs1)/(1/frequenza(i)));
    fasesens2=((Ti_max-To_maxs2)/(1/frequenza(i)));
    fasesens3=((Ti_max-To_maxs3)/(1/frequenza(i)));
    fasesens4=((Ti_max-To_maxs4)/(1/frequenza(i)));
    
    si trovano all'interno di un loop, mi sembra ragionevole scrivere "frequenza(i)" per cui non capisco cosa vorresti scrivere invece di "frequenza(i)".

    Ad ogni modo, scrivere "si ho provato e mi ha dato dei risultati che non mi aspettavo" non consente di aiutarti, devi fornire più informazioni:

    [*] cosa hai scritto al posto di "frequenza(i)?
    [*] che risultato hai ottenuto?
    [*] quale era il atteso?

    Hope this helps.
  • Re: Problema con uno struct

    Ho trovato la causa dell'errore.

    Contrariamente a quanto ho scritto nelle risposte precedenti (e mi scuso per il mio errore) il problema risiede solo indirettamente nel numero di righe della matrice "p" e, principalmente nell'algoritmo:

    [*] al termine di ogni iterazione del loop interno, il vettore "Hv viene assegnato al cellarray "Hvf"
    Hvf{i}=Hv;
    [*] successivamente, tramite la funzione "cellfun" viene calcolato il valore massimo del cellarray
    [max_Hvf,idx_max]=cellfun(@max,Hvf);
    [*] Il valore dell'indice-posizione del valore massimo viene usato per accedere al corrispondente elemento della prima colonna della matrice "p"
    Ti_max=p(idx_max,1);
    [*] Al termine della prima iterazione del loop esterno, non ci sono problemi

    Il problema sorge a partire dalla seconda iterazione.

    [*] al termine della seconda iterazione, il cellarray Hvf contiene due vettori (i due vettori Hv calcolati nel loop interno
    [*] l'istruzione
    [max_Hvf,idx_max]=cellfun(@max,Hvf);
    ritorna in idx_max due valori: gli indici-posizione dei valori massimi dei due vettori contenuti nel cellarray "Hvf"
    [*] quando nell'istruzione suvvessiva, "idx_max" viene usato per accedere elementi della prima colonna della matrice "p" si genera l'errore.
    Supponendo che "idx_max" contenga i valori (15444, 4748), l'istruzione
    Ti_max=p(idx_max,1);
    si traduce in
    Ti_max=p([15444, 4748],1);
    il che significa "prendere i valori presenti nelle righe "15444" e "4748" della prima colonna della matrice "p" ed assegnarli a Ti_max.

    Il primo valore (15444) identifica la posizione del massimo del primo elemento del cellarray.
    Siccome ad ogni iterazione del loop principale la matrice "p" viene aggiornata, se nel corso della seconda iterazione la matrice "p" non ha un numero di righe uguale (o maggiore) a quello della prima iterazione, l'istruzione "cerca" di accedere alla riga "15444" della matrice "p" che "non esiste", perchè la matrice "p", nella seconda iterazione, ha meno di "15444" righe.

    Questo è il motivo per il quale viene viene generato il messaggi di errore.

    La soluzione dipende dall'algoritmo che vuoi implementare.

    Quando, al termine del loop interno cerchi il valore massimo all'interno del cellarray "Hvf" devi cercarlo tra tutti gli elementi del cellarray calcolati fino a quel moneto o solo nell'ultimo?

    [*] nel primo caso avrai tanti "valori massimi" quanti sono i cicli effettuati fino al quel momento dal loop esterno.
    Se ti serve un solo valore (per accedere agli elementi della prima colonna della matrice "p")
    devi gestire questi "n" valori opportunamente considerando il numero delle righe della matrice "p" nel corso della iterazione attuale.

    [*] nel secondo caso, a meno che il cellarray con tutti i vettori "Hv" non ti serva in un altra parte del codice che non hai pubblicato puoi semplicemente "non usare il cellarray, ma identificare il massimo direttamente nel vettore "Hv" per cui le due istruzioni:
       Hvf{i}=Hv;
       [max_Hvf,idx_max]=cellfun(@max,Hvf);
    
    possono diventare:
    %   Hvf{i}=Hv;
       [max_Hv,idx_max]=max(Hvf);
    
    Spero di essere riuscito a spiegarmi, la spiegazione è un po' complicata da scrivere.

    In sostanza devi rivedere la seconda parte dell'algoritmo e, in particolare, come usare i valori memorizzarti nel cellarray "Hvf".

    In questo, purtroppo, non posso aiutarti.

    Posso, invece, indicarti alcuni miglioramenti che potresti apportare al codice per renderlo un po' più veloce:


    Funzione "Parametri"

    Nella funzione "Parametri.m" calcoli i valori dei parametri "s1", "s2", "s3" ecc.
    Dal momento che sono delle costanti, non è necessario calcolarli "tutte" le volte che invochi la funzione "Parametri" (nel caso dell file di input "frequenza05mhz.mat" li calcoli 4 milioni e mezzo di volte).

    Puoi spostare quella sezione fuori dalla funzione, all'inizio dello script principale e passarli come parametri alla funzione.
    Per "limitare" il numero di parametri da passare, potresti anche definirli cole campi di una struttura e passare alla funzione la struttura.

    Nella funzione c'è l'"if"
    if Tc==Th %DeltaT=0
    Tc e Th sono numeri reali, considerando le approssimazioni floating point, la possibilità che due numeri reali siano "esattamente uguali" (condizione che testi nell'"if" è estremamente bassa (per non dire "quasi impossibile") per cui le possibilità che il codice esegua le istruzioni contenute nell'"if"
        SM= s1 + s2*Tc + s3*Tc^2 + s4*Tc^3;
        RM= r1 + r2*Tc + r3*Tc^2 + r4*Tc^3;
        KM= k1 + k2*Tc + k3*Tc^2 + k4*Tc^3;
    
    sono di conseguenza estremamente basse.

    Per curiosità, prova a a fare questo test con Matlab e vedi ... cosa succede:
    a=0.1 + 0.1 + 0.1
    b=0.3
    
    if(a == b)
       disp('"a" è uguale a "b"')
    else
       disp('"a" è diverso da "b"')
    end   
    a-b
    
    Il consiglio, nel caso tu debba confrontare numeri reali, è utilizzare un valore di soglia (opportunamente scelto) come elemento discriminante.
    L'"if" in questione potrebbe essere riscritto così:
    soglia=1.0e-05
    if(abs(Tc-Th) <= soglia)
        SM= s1 + s2*Tc + s3*Tc^2 + s4*Tc^3;
        RM= r1 + r2*Tc + r3*Tc^2 + r4*Tc^3;
        KM= k1 + k2*Tc + k3*Tc^2 + k4*Tc^3;
    else
        SMth= s1*Th + (s2*Th^2)/2 + (s3*Th^3)/3 + (s4*Th^4)/4;
        SMtc= s1*Tc + (s2*Tc^2)/2 + (s3*Tc^3)/3 + (s4*Tc^4)/4;
        [ ... ]
    end
    


    Per identificare il valore della soglia (vedi sopra) puoi inserire, prima dell'inizio del loop interno:
       tmp_Tc=p(:,2);
       tmp_Th=p(:,3);
       min_diff=min(abs(tmp_Tc-tmp_Th))
       soglia=0.0001; % questa istruzione dovrebbe essere spostata fuori dal loop
       if(min_diff <= soglia)
          disp(['Input file: ' files,freq{i},misure,'.mat'])
          disp(['min_diff = ' num2str(min_diff)])
          disp(['      Possibile Tc == Th non catturato in "Parametri.m"'])
       end
       continue
    
    e far girare lo script principale; l'istruzione continue, evita di eseguire il loop interno.
    Una volta identificata la soglia, puoi rimuovere questa porzione di codice (e, soprattutto l'istruzione "continue")

    script principale

    Puoi inserire, prima dei due loop, il calcolo dei parametri "s1", "s2", "s3" ecc.

    %
    % Definizione parametri delle equazioni (from "Parametri.m")
    %
    param.s1=1.33450*10^(-2);  %questi parametri sono per una cella con 71 coppie e 6-ampere module
    param.s2=-5.37574*10^(-5);
    param.s3=7.42731*10^(-7);
    param.s4=-1.27141*10^(-9); 
    param.r1=2.08317;
    param.r2=-1.98763*10^(-2);
    param.r3=8.53832*10^(-5);
    param.r4=-9.03143*10^(-8);
    param.k1=4.76218*10^(-1);
    param.k2=-3.89821*10^(-6);
    param.k3=-8.64864*10^(-6);
    param.k4=2.20869*10^(-8);
    e passare la struttura "param" alla funzione "Parametri"
    [SM,RM,KM]=Parametri(param,Imax,N,Tc,Th);
    nella funzione puoi assegnare alle variabili "s1", "s2", "s3" ecc. i valori dei corrispondenti campi della struttura o usare direttamente la struttura.

    La sezione di lettura dei files di input è ridondante e "spreca" memoria":
    load(cat(2,files,freq{i},misure));
    data=eval(cat(2,files,freq{i},misure));
    p=data;
    
    "load" legge già il file, per cui, la seconda istruzione è inutile (e, inoltre, utilizza la funzione "eval", cosa assolutamente sconsigliata).
    L'istruzione "p=data" è superflua, perchè non scrivere direttamente
    "p=eval(cat(2,files,freq{i},misure))"

    Volendo gestire in modo dinamico i nomi dei files di input e risparmiare memoria, puoi leggere i files in questo modo:
    %
    % Il file di input viene caricato nella struttura "tmp"
    %
       tmp=load([files,freq{i},misure,'.mat']);
    %
    % Istruzione non necessari, il file di input viene già letto dalla
    % istruzione precedente
    %
    % % %    data=eval(cat(2,files,freq{i},misure));
    %
    % Identificazione del none del campo della struttura
    %
       f_name=fieldnames(tmp);
    %
    % Assegnazione del contenuto del campo alla matrice "p"
    %
       p=getfield(tmp,f_name{1});
    %
    % Cancellazione della variabile temporanea "tmp"
    %
       clear tmp
    Prima del loop interno, conviene inizializzare il vettore "Hv"; non è strettamente necessario, MatLab gestisce l'incremento della dimensione delle struttura dati automaticamente, ma questo rallenta in modo significativo l'esecuzione dello script.
    %
    % Inizializzazione del vettore "Hv"
    %
       Hv=zeros(length(p),1);
    
    Nel loop interno, i vettori "I", "Th" e "Tc" non sono utilizzati come tali, quindi, a meno che non servano in altre parti del codice che non hai pubblicato, puoi sostituire "I(v)", "Th(v)" e "Tc(v)", semplicemente con "I", "Th" e "Tc".

    Nel caso invece ti servissero come vettori, dovresti inizializzarli prima del loop (per le ragioni sopra espresse).

    Analogo discorso per i vettori SMrec, RMrec e KMrec che sembrano inutilizzati (e non inizializzati).

    Per quanto riguarda le ultime quattro istruzioni:
       fasesens1=((Ti_max-To_maxs1)/(1/frequenza(i)));
       fasesens2=((Ti_max-To_maxs2)/(1/frequenza(i)));
       fasesens3=((Ti_max-To_maxs3)/(1/frequenza(i)));
       fasesens4=((Ti_max-To_maxs4)/(1/frequenza(i)));
    
    all'inizio dello script le variabili "fasesens1", "fasesens2", "fasesens3" e "fasesens4" sono definite come vettori, ma poi sono usate come variabili "semplici"
    fasesens1=zeros(1,16);
    fasesens2=zeros(1,16);
    fasesens3=zeros(1,16);
    fasesens4=zeros(1,16);

    Dovresti verificare.

    Ribadito che ho trovato l'errore, ma non la soluzione che dipende dall'algoritmo che devi implementare, inserisco di seguito i codici della funzione "Parametri" e dello script principale con le modifiche che ti ho suggerito (QUINDI L'ERRORE "C'E ancora)

    OVVIAMENTE DECLINANDO QUALUNQUE RESPONSABILITA sull'uso e sui risultati


    Funzione "Parametri"
    % function [ SM,RM,KM ] = Parametri( Imax,N,Tc,Th)
    function [ SM,RM,KM ] = Parametri(param,Imax,N,Tc,Th)
    %
    % Aggiunto parametro di input "param" => struttura contenente i valori
    % delle costanti "s1", "s2", "s3", ...
    %
    %PARAMETRI: calcolo del coefficiente di Seedback SM, della resistenza
    %elettrica RM e della conduttanza termica KM. I valori di N e Imax servono
    %per adattare i parametri ottenuti nel sistema considerato. Tesi pag 12...
    
    %parametri delle equazioni:
    %
    % Calcolo delle costanti spostato nel "main" in modo da essere fatto una
    % volta sola
    %
    s1=param.s1; %=1.33450*10^(-2);                 %questi parametri sono per una cella con 71 coppie e 6-ampere module
    s2=param.s2; %=-5.37574*10^(-5);
    s3=param.s3; %=7.42731*10^(-7);
    s4=param.s4; %=-1.27141*10^(-9); 
    r1=param.r1; %=2.08317;
    r2=param.r2; %=-1.98763*10^(-2);
    r3=param.r3; %=8.53832*10^(-5);
    r4=param.r4; %=-9.03143*10^(-8);
    k1=param.k1; %=4.76218*10^(-1);
    k2=param.k2; %=-3.89821*10^(-6);
    k3=param.k3; %=-8.64864*10^(-6);
    k4=param.k4; %=2.20869*10^(-8);
    
    if Tc==Th %DeltaT=0
        SM= s1 + s2*Tc + s3*Tc^2 + s4*Tc^3;
        RM= r1 + r2*Tc + r3*Tc^2 + r4*Tc^3;
        KM= k1 + k2*Tc + k3*Tc^2 + k4*Tc^3;
    else
        SMth= s1*Th + (s2*Th^2)/2 + (s3*Th^3)/3 + (s4*Th^4)/4;
        SMtc= s1*Tc + (s2*Tc^2)/2 + (s3*Tc^3)/3 + (s4*Tc^4)/4;
        SM = (SMth-SMtc)/(Th-Tc);
        
        RMth= r1*Th + (r2*Th^2)/2 + (r3*Th^3)/3 + (r4*Th^4)/4;
        RMtc= r1*Tc + (r2*Tc^2)/2 + (r3*Tc^3)/3 + (r4*Tc^4)/4;
        RM = (RMth-RMtc)/(Th-Tc);
        
        KMth= k1*Th + (k2*Th^2)/2 + (k3*Th^3)/3 + (k4*Th^4)/4;
        KMtc= k1*Tc + (k2*Tc^2)/2 + (k3*Tc^3)/3 + (k4*Tc^4)/4;
        KM = (KMth-KMtc)/(Th-Tc);
    end
    %for the configuration considered with N and Imax, the following
    %normalization must be done (pag 16 pdf tesi):
    SM=SM*N/71;
    RM=RM*6*N/(Imax*71);
    KM=KM*Imax*N/(6*71);
    

    Script principale
    misure='mhz';
    files='frequenza';
    freq={'05' '07' '09' '1' '2' '3' '5' '6' '7' '8' '9' '10' '20' '30' '40' '50' };
    Hvf=[];
    frequenza=[0.5, 0.7, 0.9, 1, 2, 3, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50]*10^-3;
    modulosensore1=zeros(1,16);
    modulosensore2=zeros(1,16);
    modulosensore3=zeros(1,16);
    modulosensore4=zeros(1,16);
    fasesens1=zeros(1,16);
    fasesens2=zeros(1,16);
    fasesens3=zeros(1,16);
    fasesens4=zeros(1,16);
    
    %
    % Definizione parametri delle equazioni (from "Parametri.m")
    %
    param.s1=1.33450*10^(-2);  %questi parametri sono per una cella con 71 coppie e 6-ampere module
    param.s2=-5.37574*10^(-5);
    param.s3=7.42731*10^(-7);
    param.s4=-1.27141*10^(-9); 
    param.r1=2.08317;
    param.r2=-1.98763*10^(-2);
    param.r3=8.53832*10^(-5);
    param.r4=-9.03143*10^(-8);
    param.k1=4.76218*10^(-1);
    param.k2=-3.89821*10^(-6);
    param.k3=-8.64864*10^(-6);
    param.k4=2.20869*10^(-8);
    %
    for i=1:(size(freq,2)); %ciclo atto a scorrere tutte le acquisizioni fatte nella condizione scelta
    % % %    load(cat(2,files,freq{i},misure));
    %
    % Il file di input viene caricato nella struttura "tmp"
    %
       tmp=load([files,freq{i},misure,'.mat']);
    %
    % Istruzione non necessari, il file di input viene già letto dalla
    % istruzione precedente
    %
    % % %    data=eval(cat(2,files,freq{i},misure));
    %
    % Identificazione del none del campo della struttura
    %
       f_name=fieldnames(tmp);
    %
    % Assegnazione del contenuto del campo alla matrice "p"
    %
       p=getfield(tmp,f_name{1});
    %
    % Cancellazione della variabile temporanea "tmp"
    %
       clear tmp
    %
    % % %    Hv=[];
    %
    % Inizializzazione del vettore "Hv"
    %
       Hv=zeros(length(p),1);
    %
       Imax=5;
       N=127;
    %
    % Inizializzazine calcolo durata del loop   
    %
       tic
    %
    % Verifica della possibilità che "Tc" sia (quasi) uguale a "Th"
    % 
       tmp_Tc=p(:,2);
       tmp_Th=p(:,3);
       min_diff=min(abs(tmp_Tc-tmp_Th))
       soglia=0.0001; % questa istruzione dovrebbe essere spostata fuori dal loop
       if(min_diff <= soglia)
          disp(['Input file: ' files,freq{i},misure,'.mat'])
          disp(['min_diff = ' num2str(min_diff)])
          disp(['      Possibile Tc == Th non catturato in "Parametri.m"'])
       end
    %  
       for v=1:length(p(:,1))
    % % %       I(v)=p(v,8);
          I=p(v,8);
    % % %       Th(v)=p(v,3); %Valore della temperatura del lato caldo (sensor8)
          Th=p(v,3); %Valore della temperatura del lato caldo (sensor8)
    % % %       Tc(v)=p(v,2); %Valore della temperatura del lato freddo (sensor2)
          Tc=p(v,2); %Valore della temperatura del lato freddo (sensor2)
          %calculation parameters
    % % %       [SM,RM,KM]=Parametri(Imax,N,Tc(v),Th(v));
          [SM,RM,KM]=Parametri(param,Imax,N,Tc,Th);
    % % %       SMrec(v)=SM;
    % % %       RMrec(v)=RM;
    % % %       KMrec(v)=KM;
          %calculation heat flux
    % % %       Hv(v,1)=SM*I(v)*Th(v)+0.5*RM*I(v)^2-KM*(Th(v)-Tc(v)); %calcolo di Qh pag 15
          Hv(v)=SM*I*Th+0.5*RM*I^2-KM*(Th-Tc); %calcolo di Qh pag 15
       end
    % 
    % Stampa della durata del loop nella Command Window
    %
       toc
    %   
       Hvf{i}=Hv;
       
       [max_Hvf,idx_max]=cellfun(@max,Hvf);
       Ti_max=p(idx_max,1);
       min_Hvf=cellfun(@min,Hvf);
       
       [max_p1,idxT1]= max(p(:,4));
       To_maxs1=p(idxT1,1);
       
       [max_p2,idxT2]= max(p(:,5));
       To_maxs2=p(idxT2,1);
       
       [max_p3,idxT3]= max(p(:,6));
       To_maxs3=p(idxT3,1);
       
       [max_p4,idxT4]= max(p(:,7));
       To_maxs4=p(idxT4,1);
       
       modulosensore1(i)=20*log10(max(p(:,4))-max_Hvf)/(min(p(:,4))-min_Hvf);
       modulosensore2(i)=20*log10(max(p(:,5))-max_Hvf)/(min(p(:,5))-min_Hvf);
       modulosensore3(i)=20*log10(max(p(:,6))-max_Hvf)/(min(p(:,6))-min_Hvf);
       modulosensore4(i)=20*log10(max(p(:,7))-max_Hvf)/(min(p(:,7))-min_Hvf);
       fasesens1=((Ti_max-To_maxs1)/(1/frequenza(i)));
       fasesens2=((Ti_max-To_maxs2)/(1/frequenza(i)));
       fasesens3=((Ti_max-To_maxs3)/(1/frequenza(i)));
       fasesens4=((Ti_max-To_maxs4)/(1/frequenza(i)));
    end
    
    Hope this helps.
Devi accedere o registrarti per scrivere nel forum
23 risposte