[Matlab]-Ciclo FOR (elementare)

di il
8 risposte

[Matlab]-Ciclo FOR (elementare)

Salve, premetto che non serve alcuna conoscenza di elettrotecnica per capire il mio problema.
Ho un problema con la risoluzione di un circuito in matlab:
mi viene chiesto di calcolare per quale valore del generatore di tensione la potenza su un resistore è 4Kw
che tradotto significa risolvere un sistema del tipo :
{ 30*I1 + 30*I2 = E(k)
{ I1 - I2 = 15
Dove appunto E(k) è la tensione che varia. In matlab traduco il sistema in matrici e faccio variare E(k) con un ciclo for:
>>E=[1:1:500]                           %Definisco il vettore E 
>>A=[30 30; 1 -1];                      %Definisco la matrice dei coefficienti
>>N=length (E)                           %N=Lunghezza vettore E
>>for k=1:N 
           b(k)=[E;15]; x(k)=inv(A)*b; I1(k)=x(1); P(k)=30*I1^2;
   end;
mi da quest'errore :
Error using vertcat
Dimensions of matrices being concatenated are not consistent.

Error in (line 5)
b(k)=[E;15]; x(k)=inv(A)*b; I1(k)=x(1);P(k)=30*I1^2;
Cosa sbaglio? Come imposto correttamente il ciclo for ?

8 Risposte

  • Re: [Matlab]-Ciclo FOR (elementare)

    Ho cambiato qualcosa :
    >>clear all ;clc ;
    >>E=[0:1:1000];
    >>A=[30 30;1 -1];
    >>for k=1:length(E)
    b(k)=[E(k);15];
    x(k)=inv(A)*b;
    I(k)=x(2);
    P(k)=30*I(k)^2;
    end;
    E mi da questi errori:
    In an assignment A(I) = B, the number of elements in B and I must be the same.
    
    Error in Untitled (line 5)
    b(k)=[E(k);15];
    HeLP!
  • Re: [Matlab]-Ciclo FOR (elementare)

    Per rendere piu chiaro il problema spiego cosa ho fatto fare al programma e perchè:
    -La potenza si calcola
    R*I^2
    , R è costante e quindi devo calcolare tutte le 'I' (correnti) al variare della tensione di alimentazione E.
    Significa risolvere quel tipo di sistema dove però c'è un parametro che è appunto la E che varia; equivale a risolvere n (nel mio caso 1000 visto che il vettore E è del tipo [1:1:1000]) sistemi lineari da cui quindi ricavo i miei 1000 valori di corrente che mi interessano (incognite del sistema ). Ricavati i 1000 valori di 'I' ricavo i 1000 valori di 'P' semplicemente dall'equazione
    30*I^2
    .
  • Re: [Matlab]-Ciclo FOR (elementare)

    Le mie conoscenze di elettrotecnica non vanno oltre il saper cambiare una lampadina per cui non discuto l'approccio al problema.
    Forse, però, c'è un metodo migliore rispetto a quello scelto nella domanda.

    A prescindere dalle considerazioni sul metodo, se però, come descritto nella domanda, si tratta di risolvere un sistema di due equazioni con uno dei due termini noti "varaibile" si può utilizzare il metodo di Cramer come nello script in calce.

    Nello script ho definito (per comodità) i coefficienti delle incognite I1 e I2, rispettivamente, (x1, x2) e (y1, y2).
    Le incognite I1 e I2 sono definite "x" e "y"
    Il vettore E rappresenta i valori di tensione da "esplorare", t2 il termine noto della seconda equazione del sistema.

    Per risolvere il sistema per diversi valori di E (es: E=1:500) e per il calcolo dei successivi valori di potenza non è necessario usare cicli "for":
    % Risoluzione sistema con metodo di Cramer
    D=(x1*y2)-(x2*y1);
    x=((E*y2)-(t2*y1))/D;   % Corrisponde a I1
    y=((x1*t2)-(x2*E))/D;   % Corrisponde a I2
    % Calcolo della potenza per le due soluzioni
    Px=30*x.^2;
    Py=30*y.^2;
    
    Dal momento che si usano valori discreti per "E" i valori di delle Potenze relative alle correnti I1 e I2 soluzione del sistema saranno, a loro volta, discreti, questo comporta che, probabilmente, non si riuscirà ad determinare il valore di E che, nel caso della domanda, corrisponderà ad una potenza di 4kW, "esatto", ma solo valori approssimati (per eccesso o per difetto).

    Nella seconda parete dello script vengono individuati i valori di "E" ed i relativi valori di Potenza considerando un valore di tolleranza "toll", definito in input all'inizio dello script.
    Si può provare a modificane il valore per vedere come cambiano i risultati (i valori di E e Potenza).
    
    % Valore potenza sul resistore
    P_res=4000;
    % Valore soglia per ricerca soluzione
    toll=5;
    % Definizione dei coefficienti del sistema
    x1=30;   % I1 prima equazione
    x2=1;    % I1 seconda equazione
    y1=30;   % I2 prima equazione
    y2=-1;   % I2 seconda equazione
    % Definizione valori E di tensione
    E=1:500;
    % Definizione termine noto seconda equazione
    t2=15;
    % Risoluzione sistema con metodo di Cramer
    D=(x1*y2)-(x2*y1);
    x=((E*y2)-(t2*y1))/D;   % Corrisponde a I1
    y=((x1*t2)-(x2*E))/D;   % Corrisponde a I2
    % Calcolo della potenza per le due soluzioni
    Px=30*x.^2;
    Py=30*y.^2;
    % Ricerca del valore della tensione e valori corrispondenti di Potenza
    Tens=0;
    Tens=find(Px <= (P_res + toll) & Px >= (P_res - toll));
    if(~isempty(Tens))
       disp(['Valori tensione= ' num2str(Tens)])
       P=Px(Tens);
       disp(['Valori Potenza= ' num2str(P)])
    else
       Tens=find(Py <= (P_res + toll) & Py >= (P_res - toll));
       if(~isempty(Tens))
          disp(['Valori tensione= ' num2str(Tens)])
          P=Px(Tens);
          disp(['Valori Potenza= ' num2str(P)])
       end
    end
    if(isempty(Tens))
       disp('Nessuna soluzione per il range di Tensione considerato e/o il valore di tolleranza')
    end
    
    Hope this helps.
  • Re: [Matlab]-Ciclo FOR (elementare)

    Grazie mille per l'attenzione! Ho dato un occhiata inizialmente accurata leggendo è diventata veloce perchè ho trovato qualche difficoltà. Se non ti richiede molto ( visto la risoluzione che mi hai dato!) potresti risolvermelo con il ciclo for ? perchè purtroppo devo farlo così all'esame..Diversamente cerco di applicarmi per imparare il tuo metodo, almeno lo risolvo . Grazie mille aspetto una tua risposta
  • Re: [Matlab]-Ciclo FOR (elementare)

    Ho riletto e mi rimangono alcuni dubbi:
    -Hai risolto materialmente con la regola di Cramer, se la applico come x1=det(A1)/det(A) avrò
    sempre errore per l'incombatibilità dimensionale delle matrici per via del vettore E ?
    -Premesso che a me serve solo 1 valore di potenza, quello per I1, mi puoi spiegare cosa fai fare al programma con la funzione find? qual'è la sua struttura , cosa significa if isempty ?

    grazie mille
  • Re: [Matlab]-Ciclo FOR (elementare)

    Ho capito tutto e ho imparato a farlo...se mi spieghi come impostare il ciclo for per ottenere lo stesso risultato te ne sarei grato
  • Re: [Matlab]-Ciclo FOR (elementare)

    Dal momento che, come hai scritto negli ultimi messaggi sei riuscito a capire il precedente codice ed il funzionamento delle funzioni di MatLab in esso invocate e che ora l'unico problema è l'implementazione della soluzione con l'utilizzo di cicli for, inserisco direttamente il codice.

    All'interno del codice ho inserito dei commenti che spero siano abbastanza dettagliati ed esplicativi.

    Per renderlo più chiaro, ho rimosso dal codice la vecchia implementazione.

    Rispetto alla versione precedente, ho inserito un nuovo parametro:

    step_E=1;

    che consente di definire il passo di incremento di E.

    Puoi confrontare i risultati forniti dai due codici, eseguendoli in sequenza.

    Nel caso avessi ancora dei dubbi ... scrivi.
    
    % Valore potenza sul resistore
    P_res=4000;
    % Valore soglia per ricerca soluzione
    toll=5;
    % Definizione dei coefficienti del sistema
    x1=30;   % I1 prima equazione
    x2=1;    % I1 seconda equazione
    y1=30;   % I2 prima equazione
    y2=-1;   % I2 seconda equazione
    % Definizione del valore massimo di E da considerare
    max_E=500;
    % Definizione del passo di incremento del valore di E
    step_E=1;
    % Definizione termine noto seconda equazione
    t2=15;
    % Risoluzione sistema con metodo di Cramer in un ciclo for
    % Il determinante "D" non diopende dalla variabile "E" quindi si calcola
    % una volta sola, fuorida ciclo for
    D=(x1*y2)-(x2*y1);
    % Inizializzazione dei vettori "x" e "y"
    % Non è strettamente necessario dal momento che MatLab gestisce
    % l'allocazione dinamica della memoria in modo automatico, ma velocizza
    % l'esecuzione successiva del ciclo for in quanto MatLab non deve invocare,
    % ad ogni iterazione, le funzioni per l'alocazine della memoria
    x=zeros(0,max_E*step_E);
    y=zeros(0,max_E*step_E);
    % Ciclo for: il parametro "tens_E" varia da 1 a 500 con passo "sterp_E"
    % Inizializzazione contatore "cnt"
    cnt=1;
    for tens_E=1:step_E:max_E
       x(cnt)=((tens_E*y2)-(t2*y1))/D;   % Corrisponde a I1
       y(cnt)=((x1*t2)-(x2*tens_E))/D;   % Corrisponde a I2
       cnt=cnt+1;
    end
    % Inizializzazione dei vettori "Px" e "Py" (vedi commento precedente sulla
    % inizializzazione
    Px=zeros(1,max_E*step_E);
    Py=zeros(1,max_E*step_E);
    % Calcolo della potenza per le due soluzioni con ciclo for
    % Inizializzazione contatore "cnt"
    cnt=1;
    for i=1:step_E:max_E
       Px(cnt)=30*x(cnt)^2;
       Py(cnt)=30*y(cnt)^2;
       cnt=cnt+1;
    end
    % Ricerca del valore della tensione e valori corrispondenti di Potenza in
    % un ciclo for con indice "tens_idx"
    % Inizializazione di Tens
    Tens=0;
    % Loop su Px Se, l'i-esimo valore di Px è compreso tra la potenza di
    % riferimento (P_res) e la soglia di tolleranza l'indice del loop viene
    % memorizzato in "Tens"
    % Identificazione lunghezza (numero di elementi) dei vettori Px e Py
    n_Px=length(Px);
    n_Py=n_Px;
    for tens_idx=1:n_Px
       if(Px(tens_idx) <= P_res + toll && Px(tens_idx) >= (P_res - toll))
          Tens=tens_idx;
          disp(['Valori tensione= ' num2str(Tens)])
          P=Px(Tens);
          disp(['Valori Potenza= ' num2str(P)])
          break;
       end
    end
    % Se nessun valore di Px cade nell'intervallo (P_res +- toll), il valore di
    % Tens non sarà stato nel ciclo for
    % Si procede con il loop su Py
    if(Tens == 0)
       for tens_idx=1:n_Py
          if(Py(tens_idx) <= P_res + toll && Py(tens_idx) >= (P_res - toll))
             Tens=tens_idx;
             break;
          end
       end
       if(Tens ~= 0)
          disp(['Valori tensione= ' num2str(Tens)])
          P=Py(Tens);
          disp(['Valori Potenza= ' num2str(P)])
       end
    end
    % Se Tens è "ancora" uguale a 0 non ci sono soluzioni
    if(Tens == 0)
       disp('Nessuna soluzione per il range di Tensione considerato e/o il valore di tolleranza')
    end
       
    figure
    plot(x,'r')
    hold on
    plot(y,'b')
    grid on
    
    figure
    plot(Px,'k')
    hold on
    plot(Py,'g')
    grid on
    
    Hope this helps.
  • Re: [Matlab]-Ciclo FOR (elementare)

    Ti ringrazio ancora ma sono riuscito a risolverlo da solo nel caso in cui servisse il codice è questo
    clear all;clc;
    %Definisco valori della tensione di alimentazione
    E=[0:1/100:500];
    %Inserisco dati
    R=[30 20 10]; J=15;
    A=[30 30;1 -1];
    L=length(E);
    for k=1:L
        b=[E(k);J];
        x=inv(A)*b;
        I1(1,k)=x(1);
        PR1(1,k)=R(1)*I1(1,k).^2;
    end
    toll=0.1;Potenza=4000;
    Tens=find(PR1<= (Potenza+toll) & PR1>= (Potenza-toll));
    disp(['Valore di tensione = ' num2str(E(Tens))]);
    disp(['Valore di potenza = ' num2str(PR1(Tens))])
    Grazie mille ancora
Devi accedere o registrarti per scrivere nel forum
8 risposte