WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Variablennamen in einer Schleife verschiedeneWerte zu weisen

 

Waldemar
Forum-Century

Forum-Century


Beiträge: 100
Anmeldedatum: 14.10.11
Wohnort: Neuss
Version: R2011b
     Beitrag Verfasst am: 17.01.2013, 15:38     Titel: Variablennamen in einer Schleife verschiedeneWerte zu weisen
  Antworten mit Zitat      
Hallo,

hab schon den ganzen Tag an verschiedenen Problemen rumgetüftelt, so dass ich gerade nicht mehr weiterkomme (bin leer)...vielleicht könnt ihr mir helfen:

Hier ein Auszug aus meinem Skript:
Code:

close all
clear all
clc

R1=1;
R2=1;
R3=1;

var_list = whos('R*');
var_name={var_list.name};
size_var_name=size(var_name);

for k=1:size_var_name(2)
       
       R1=1;
       R2=1;
       R3=1;
     
for j=1:2
   
  char(var_name(k))=j         % UM DIESE ZEILE GEHT ES!!!
                                          % Bisher falsch, aber so hätte ich es gern:
                                          % z.B. R1=1 usw.

  Aktuelle_Wichtungen={[R1,R2,R3]};
  Akt_Wicht_Matrix(j,k)=Aktuelle_Wichtungen;

end

end

 


Mein Ziel ist, dass der aktuellen Variable
Code:
char(var_name(k))
in der j-Schleife die Werte - in diesem Fall - 1 und (danach) 2 zu gewiesen werden (in j passiert normalerweise mehr)!
Und bevor der nächsten Variable andere Werte zu gewiesen werden, werden alle wieder auf eins gestellt!

Möchte also, dass in der j-Schleife folgendes gilt:
R1=1; R2=1; R3=1;
R1=2; R2=1; R3=1;
R1=1; R2=1; R3=1;
R1=1; R2=2; R3=1;
R1=1; R2=1; R3=1;
R1=1; R2=1; R3=2;

(Die Variablennamen werden in der j-SChleife an ein Simunlink-Modell übergeben!)


Wäre super, wenn jemand eine Idee hätte!

MfG, Waldemar
_________________

Im "ich brauch Hilfe"-Status
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 17.01.2013, 17:04     Titel: Re: Variablennamen in einer Schleife verschiedeneWerte zu we
  Antworten mit Zitat      
Hallo Waldemar,

Variablen R1, R2, R3, ... zu erzeugen ist prinzipiell eine sehr schlechte Idee. Es ist deutlich effizienter und besser zu debuggen, wenn Du einen Index als Index verwendest, anstatt ihn im Namen der Variablen zu verstecken, wo er zum Schreibn und Lesen erst umständlich herausgepfriemelt werden muss.

Besser: Entweder "R = zeros(1, 3)" oder ein anderes Array, falls alle R's den gleichen Typ und die gleiche Dimension haben, oder andernfalls: "R = cell(1, 3)".

Siehe dazu hunderte Themen in diesem Forum zum Stichwort "eval".

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Waldemar
Themenstarter

Forum-Century

Forum-Century


Beiträge: 100
Anmeldedatum: 14.10.11
Wohnort: Neuss
Version: R2011b
     Beitrag Verfasst am: 17.01.2013, 19:41     Titel:
  Antworten mit Zitat      
Hallo Jan S,

danke für deine Antwort und Mühe.

Ist es den trotzdem mgl.
Code:
char(var_name(k))
1:1 von rechts des Gleichheitszeichens auf die linke Seite des Gleichheitszeichens zu bekommen??

Hab alles soweit fertig, brauch nur noch R1, also char(var_name(1)), links des Gleichheitszeichens!!

Wenn es diese Mgl.keit nicht gibt, probiere mich gerne mal an der 'index-Variante'!
_________________

Im "ich brauch Hilfe"-Status
Private Nachricht senden Benutzer-Profile anzeigen
 
Waldemar
Themenstarter

Forum-Century

Forum-Century


Beiträge: 100
Anmeldedatum: 14.10.11
Wohnort: Neuss
Version: R2011b
     Beitrag Verfasst am: 17.01.2013, 20:11     Titel:
  Antworten mit Zitat      
Hallo,

bei deinem Vorschlag komme ich doch auch in das Problem, etwas, was bislang rechts des Gleichheitszeichens steht, nicht auf die linke Seite zu bekommen!!!

Code:
close all
clear all
clc

W=cell(2,6);

W(1,1)={'Q1'};
W(1,2)={'Q2'};
W(1,3)={'Q3'};
W(1,4)={'R1'};
W(1,5)={'R2'};
W(1,6)={'R3'};

W(2,1)={1};
W(2,2)={1};
W(2,3)={1};
W(2,4)={1};
W(2,5)={1};
W(2,6)={1};

length_W=length(W);

for k=1:length_W
 
    char(W(1,1))=cell2mat(W(2,1)); % geht so nicht!
    char(W(1,2))=cell2mat(W(2,2)); % geht so nicht!
    char(W(1,3))=cell2mat(W(2,3)); % geht so nicht!
    char(W(1,4))=cell2mat(W(2,4)); % geht so nicht!
    char(W(1,5))=cell2mat(W(2,5)); % geht so nicht!
    char(W(1,6))=cell2mat(W(2,6)); % geht so nicht!
   
for j=1:2

......



ich glaube ich stehe auf dem Schlauch!!!

Wäre jemand so lieb!


MfG, Waldemar
_________________

Im "ich brauch Hilfe"-Status
Private Nachricht senden Benutzer-Profile anzeigen
 
Seban
Forum-Meister

Forum-Meister


Beiträge: 600
Anmeldedatum: 19.01.12
Wohnort: ---
Version: ab R2014b
     Beitrag Verfasst am: 18.01.2013, 06:23     Titel:
  Antworten mit Zitat      
Hallo Waldemar,

Zunächst: Ich verstehe nicht so ganz, was du erreichen möchtest.

Sollen R1 bis R3 Variablen sein, denen du entweder 1 oder 2 zuordnest?

Du erstellst ein cell mit 6 Variablen und dazu 6 Werten. In der for-Schleife änderst du dann aber nicht die 6 Werte, sondern machst iwas mit den 6 Variablen, was ich nicht verstehe; Stichwort char. Du legst damit eine weitere Variable char an (was übrigens ein Matlab-Befehl ist und sich somit nicht gerade anbietet). Und plötzlich gibt es auch noch Qi. Ich bin verwirrt Question

---

Ich geh mal davon aus, du willst als Ziel so etwas haben:
Code:
    R1   R2   R3
    ---------------
     1     1     1   <- Zeitpunkt 1
     2     1     1   <- Zeitpunkt 2 usw.
     1     1     1
     1     2     1
     1     1     1
     1     1     2


Wie Jan bereits sagte, geht das einfacher, wenn du nicht 3 Variablen mit den Indizes im Namen erstellst, sondern ein Array, dessen Indizes du dann verwenden kannst, um die entsprechenden Werte anzusprechen.
R(1, 1) ist der Wert für dein R1, R(1, 2) ist dein R2, R(1, 3) ist dein R3
So erzeugst du dann dieses Array und veränderst in der Schleife bei jedem 2. Durchlauf ein Element von R:
Code:
j = 1;
for i = 1:1:6
    if mod(i, 2) == 1   % i ist ungerade
        R = ones(1, 3);
    else
        R(1, j) = 2;
        j = j + 1;
    end
end


Wenn du aber wirklich R1, R2, R3 explizit erzeugen willst, um diese bspw. später als Output zu verwenden, kannst du das per Cell (oder per Struct, s.u.) machen:
Code:
R_orig = {'R1', 'R2', 'R3'; 1, 1, 1};
j = 1;
for i = 1:1:6
    if mod(i, 2) == 1   % i ist ungerade
        R = R_orig;
    else
        R{2, j} = 2;
        j = j + 1;
    end
end

Im ersten Code-Bsp. haben wir den Vektor R vom Typ double 1x3. Dieser ist jetzt quasi in unserem Cell die Zeile 2. Beachte allerdings den Unterschied von R(2, 1) und R{2, 1}. In Zeile 1 haben wir die Bezeichnungen R1, R2, R3.

Jetzt mit einer Struktur:
Code:
R.namen = {'R1', 'R2', 'R3'};
j = 1;
for i = 1:1:6
    if mod(i, 2) == 1   % i ist ungerade
        R.werte = ones(1, 3);
    else
        R.werte(1, j) = 2;
        j = j + 1;
    end
end

Jetzt haben wir wieder den Zahlenvektor aus Code-Bsp. 1 (R.werte), zusätzlich auch Bezeichnungen (R.names), auf die wir leichter zugreifen können als in einem Cell.

Ich hoffe, ich konnte ein bisschen Licht spenden.

Grüße,
Seban
_________________

Richtig fragen
Debugging
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 18.01.2013, 09:58     Titel:
  Antworten mit Zitat      
Hallo Waldemar,

Zunächst mal empfehle ich, dass vollkommen sinnfreie aber ebenso weitverbreitete "clear all" wegzulassen. Es löscht auch alle geladenen Funktionen aus dem Speicher, was dann nützlich ist, wenn man während des Programm-Ablaufs alle M-Files geändert hat. Da das aber wohl kaum jemand jemals machen wird, bleibt mir die inflationäre Anwendung von "clear all" ein mystisches Rätsel. "clear variables" wäre sinnvoller, obwohl es immer noch recht brutal säubert.

Aber zurück zum eigentlichen Problem: Wie ich schon sagte, ist es ein schlechtes Programmdesign und ein typischer Anfänger-Fehler, für eine Zuweisung die linke Seite dynamisch zu erzeugen. Das ist zwar möglich, macht aber das Programm deutlich langsamer, heftig komplizierter und dadurch kaum debug- oder erweiterbar. Es führt ohne Not eine zusätzliche Abstraktions-Ebene ein.

Links vom "=" muss eine Variable stehen und kein String. Das sieht zwar im Source-Code irgendwie ähnlich aus, es sind ja beides Buchstabenketten. Aber die Strings sind von Quotes eingefasst, und die Variablennamen nicht.

Code:
clear

Q = cell(1, 6);
Data = cell(1, 6);

Data{1} = 1;  % Schneller als: Data(1) = {1}
Data{2} = 1;
Data{3} = 1;
Data{4} = 1;
Data{5} = 1;
Data{6} = 1;

length_Q = length(Q);

for k = 1:length_Q
   for iData = 1:6
      Q{iData} = Data{iData};
   end
   % Oder gleich: Q = Data;
   % Oder : Q = Data(1:3);  R = Data(4:6);
   ...
 

Man macht sich also am besten erst gar nicht den Umstand, "R1", "R2", ... als Strings oder Variablen zu definieren, sondern benutzt gleich ein Array oder cell Array wie "R{1}", "R{2}", ...
Wenn man wirlich einen Variablen-Namen dynamisch produzieren muss, weil es deutlich übersichtlicher ist, verwendet man "dynamic fieldnames":
Code:
for k = 1:10
  S.(sprintf('Field%d', k)) = rand;
end
disp(S)


Donald E. Knuth, einer der größten Computer-Forscher überhaupt, propagierte das leicht zu merkende Motto:
Zitat:
KISS: Keep it simple stupid

D.h., man soll ein Programm so einfach formulieren wie irgend möglich. Dann hat man die geringesten Schwierigkeiten beim Programmieren, Debuggen und der Rechner auch den geringsten Aufwand beim Abarbeiten. Deshalb solte man vermeiden, Variablen in Variablen zu speichern, nur um ihnen Werte zuzuweisen.
Ist dies etwas klarer geworden?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Waldemar
Themenstarter

Forum-Century

Forum-Century


Beiträge: 100
Anmeldedatum: 14.10.11
Wohnort: Neuss
Version: R2011b
     Beitrag Verfasst am: 18.01.2013, 16:25     Titel:
  Antworten mit Zitat      
Hallo Jan S,
Hallo Seban,

hier meine funktionierende Lösung (natürlich durch euch inspiriert (VIELEN DANK)):

Code:

WUrspr=cell(1, 6); % Wichtungen des optimalen MP-Reglers! R1, R2, R3, Q1, Q2 und Q3!

WUrspr{1}=1;
WUrspr{2}=1;
WUrspr{3}=1;
WUrspr{4}=1;
WUrspr{5}=1;
WUrspr{6}=1;

length_WUrspr=length(WUrspr);

V=cell(1,50); % Variation der Wichtungen! Die Wichtungen sollen von 1...
length_V=length(V);

for v=1:length_V % ....bis 50 variiert werden!
    V{v}=v;
end


for k=1:length_WUrspr
   
    W=WUrspr;
   
for j=1:length_V
   
    W{k}=V{j};
   
    R1=W{1};
    R2=W{2};
    R3=W{3};
    Q1=W{4};
    Q2=W{5};
    Q3=W{6};
   
    Aktuelle_Wichtungen={[Q1,Q2,Q3,R1,R2,R3]};
    Akt_Wicht_Matrix(j,k)=Aktuelle_Wichtungen;
   
end
end
 



Zusätzlich führe ich mal das ganze Skript auf:
(Die R1, R2, R3, Q1, Q2 und Q3 brauche ich nämlich im Simulink-Modell)


Code:
% M-File zum Starten der Modellsimulation um die optimalen
% Elemente der Wichtungsmatrizen Q und R je Betriebspunkt zu ermitteln!

% Ziel ist, für jeden Betriebspunkt die Elemente der Wichtungsmatrizen EINZELN zu variieren und die dazugehörige Regelguete_Ges in Zusammenhang mit den aktuellen Werten der Wichtungsmatrizen abzuspeichern!

% Unterordner einbinden
path(genpath(pwd),path);
path(genpath('..\MODELLBILDUNG'),path);

% Simulationsschrittweite
stepSize = 0.03; % 10 ms % Anstelle von 0.06!

% Simulationsdauer vordefinieren
simTime = 18;

% PT1-Zeitkonstante
T_PT1    = 2; % für AGRstat --> AGRdyn

% Laden der MAT-Files für die Streckenmodelle und Ableitungsmodelle
load('modLOLIMOT_3In_CA50');
load('modLOLIMOT_3In_IMEP');
load('modLOLIMOT_3In_DPMAX');
load('modLOLIMOT_3In_HC');
load('modLOLIMOT_3In_NOX');


% BETRIEBSPUNKTE folgen aus den Messdaten, die zur Ermittlung der Regelstrecke (Ableitungs- und Streckenmodell) genutzt wurden! Andernfalls oder auch in Kombination damit können Betriebspunkte aus den Randbedingungen des Prüfstandes (siehe Konzeptentwurf) gewonnen werden!

  Betriebspunkt=[6.70,2.50,58;
                 -8.30,2.30,397;]; % Im Orginalskript gibt es viel mehr Betriebspunkte! (Hier verkürzte Version).

size_Betriebspunkt=size(Betriebspunkt);
             
for i=1:size_Betriebspunkt(1,1)
             
      CA50=Betriebspunkt(i,1);      
      IMEP=Betriebspunkt(i,2);
      NOx=Betriebspunkt(i,3);
   
      % CA50, IMEP und NOx geben in den Sprüngen den Wert vor!
      % Schnittstellen zwischen Script und Model!!
   
   
% Jetzt möchte ich alle Elemente - zu variieren sind: R1, R2, R3, Q1, Q2 und Q3 - der Wichtungsmatrizen Q und R (Diagonalmatrix) einzeln und nacheinander ("einzeln und nacheinander"---> k-SCHLEIFE) in einem vordefinierten Bereich (j-SCHLEIFE) für jeden Betriebspunkt (i-SCHLEIFE) variieren und den resultierenden Wert der Regelgüte mit den aktuellen Werten der Elemente (R1, R2, R3, Q1, Q2, Q3) abspeichern!!!
% Die aktuellen Werte der Elemente werden in:
% Ins_Matrix(j,(i-1)*length_WUrspr+k)=Insgesamt; abgespeichert!
% Die aktuelle Regelguete_ges wird in:
% Regelguete_Ges_Matrix(j,(i-1)*length_WUrspr+k)=Regelguete_Ges; abgespeichert!

      % R1, R2, R3, Q1, Q2 und Q3 sind weitere Schnittstellen zwischen dem Script und dem Model!!

%%%%% Wichtungen_var.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
WUrspr=cell(1, 6);

WUrspr{1}=1;
WUrspr{2}=1;
WUrspr{3}=1;
WUrspr{4}=1;
WUrspr{5}=1;
WUrspr{6}=1;

length_WUrspr=length(WUrspr);

V=cell(1,50);
length_V=length(V);

for v=1:length_V
    V{v}=v;
end


for k=1:length_WUrspr
   
    W=WUrspr;
   
for j=1:length_V
   
    W{k}=V{j};
   
    R1=W{1};
    R2=W{2};
    R3=W{3};
    Q1=W{4};
    Q2=W{5};
    Q3=W{6};
   
%%%%% Wichtungen_var.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    

% Modell öffnen und Simulation starten:
MDLsim  = 'Regelung_DREIxDREI_hnBx_Vll_Bp_Nstll_nDr_LIN_NOx_OPT';
open(MDLsim);
set_param('Regelung_DREIxDREI_hnBx_Vll_Bp_Nstll_nDr_LIN_NOx_OPT','SimulationCommand','start');

% Matlab ist schneller, als das Simulink-Modell! Da ich allerdings in der weiteren Berechnung auf toWorkspace-Variablen (Regelguete_ges) zurückgreife, muss ich Matlab anhalten:

pause(35)

% Regelguete_ges.signals.values resultiert aus der Simulation!
Regelguete_Ges=max(Regelguete_ges.signals.values);
Regelguete_Ges_Matrix(j,(i-1)*length_WUrspr+k)=Regelguete_Ges;

Insgesamt={[Regelguete_Ges,Q1,Q2,Q3,R1,R2,R3,CA50,IMEP,NOx]};
Ins_Matrix(j,(i-1)*length_WUrspr+k)=Insgesamt;

clear Regelguete_Ges
clear Insgesamt
     
end

end

end
     
 



Hätte zum Abschluss noch 3 Fragen:

- Wenn sich jemand mein Skript (unteres) anschaut, wo könnte ich Zeit sparen!?
- Wie suche ich in Matlab am besten nach vorprogrammierten Funktionen? Hätte da jemand ein Kochrezept für mich?
- Kennt jemand von euch eine Funktion, die optimale Eingangsgrößen berechnet? Konkreter Fall:
Also ich habe ein Simulink-Modell, dass ich durch R1, R2, R3, Q1, Q2 und Q3 (weitere Eingangsgrößen sind CA50, IMEP und NOx (sollen nicht optimiert werden)) beeinflussen kann. Als Ausgangsgröße habe ich 1 Größe (Regelguete_Ges). Die Eingangsgrößen R1, R2, R3, Q1, Q2 und Q3 sollen so optimiert werden, dass die Ausgangsgröße Regelguete_Ges MINIMAL wird!!! Dabei ist zu achten, dass diese Eingangsgrößen größer Null sind!
Gibt es eine Funktionen, die auch das Zusammenspiel zwischen Matlab und Simulink händeln kann?



Wäre super, wenn ihr paar Tipps geben könntet.
Jedenfalls bis hier schonmal ein großes Danke.


MfG, Waldemar
_________________

Im "ich brauch Hilfe"-Status
Private Nachricht senden Benutzer-Profile anzeigen
 
Waldemar
Themenstarter

Forum-Century

Forum-Century


Beiträge: 100
Anmeldedatum: 14.10.11
Wohnort: Neuss
Version: R2011b
     Beitrag Verfasst am: 19.01.2013, 17:28     Titel:
  Antworten mit Zitat      
Hallo Zusammen,

meine ürbigen Fragen konnte ich auf Grundlage einer Internet-Recherche beantworten! (Suche:" Simulink optimieren")

Gucken, ob ich es zusammen bekomme!

Jedenfalls vielen Dank für eure Hilfe!

MfG, Waldemar
_________________

Im "ich brauch Hilfe"-Status
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.