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

Löschen von Daten während einer Schleife

 

Steini
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 15.11.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 23.11.2018, 01:10     Titel: Löschen von Daten während einer Schleife
  Antworten mit Zitat      
Hallo,

ich habe hierbei ein kleines Problem: ich habe eine Matrix mit Einträgen, aus der ich in jedem Durchgang meiner Schleife (falls bestimmte Bedingungen erfüllt sind) die entsprechende Zeile rauslöschen möchte. Manchmal läuft er einwandfrei durch, manchmal bringt er eine Fehlermeldung, dass der Index in Position 1 die Array Grenzen überschreitet. Hier ist mal mein Code:

Code:

Lm=length(MarrM);
Lf=length(MarrF);
for L=Lm:-1:1
% ... conditions...
% if true
MarrM(L,:)=[];
MarrF(m2,:)=[];
% if false
end
end
 


hab bereits schon von hinten angefangen, da er mir sonst immer Zeilen überspringt wenn ich L=1:Lm eingebe und in der Schleife Zeilen lösche. Ich habe auch extra vor die Schleife die Länge der Matrix, aus der gelöscht wird, abgerufen um die Schleife auch exakt so oft durchlaufen zu lassen wie ich Einträge in der Matrix habe. Er dürfte also eigentlich meines Verständnisses nach nie den Fehler mit der Überschreitung der Arraygrenzen produzieren. Und doch kommt bei einigen Simulationsdurchläufen - und zwar immer dann, wenn in MarrM noch genau 1 Zeile drin ist. Aus irgendeinem Grund ist L im Workspace dann auch nicht =1 sondern =2. Wenn L=2 aber nur noch 1 Element in meiner Matrix ist versteh ich ja den Fehler, allerdings hab ich wie ich dachte dem Problem mit den ersten 3 Zeilencodes vorgesorgt..

Was überseh ich hier?
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 23.11.2018, 11:42     Titel:
  Antworten mit Zitat      
Hallo,

length ist bei Matrizen gefährlich. Ich würde size, ggf. mit einem Zusatzargument verwenden.
Kommt die Fehlermeldung in der Zeile für MarrF oder für MarrM?
Wie wird m2 ermittelt?

Ein reproduzierbares Beispiel wäre hilfreich.

Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Steini
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 15.11.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 23.11.2018, 13:28     Titel:
  Antworten mit Zitat      
Hallo

dank dir für deine Antwort. Warum ist length bei Matrizen problematisch? Und würde es helfen, wenn ich z.B. length(M(:,1)) verwenden würde, also nur die erste Spalte der Matrix (und mir so künstlich einen Vektor erschaffe)?

Der Fehler kommt bei MarrM bzw dem L, was m2 ist müsste hier also irrelevant sein. ich hab extra eine abgespeckte Version des Codes reingemacht, weil da über 100 Zeilen Code drinstecken - und das ist nur das Skript für die Partnerfindung. Um ein reproduzierbares Beispiel zu posten müsste ich das komplette Programm posten, das hätte aber über 1000 Zeilen. Aber wenn es weiterhilft, hier mal das Skript zur Partnerfindung (bitte nicht über den unschönen Code wundern. Der geht sicherlich schöner, da ich aber das erste Mal programmiere, fühle ich mich mit der Wiederholung von if-Schleifen sicherer):

MarrM und MarrF beinhalten Individuen, die ausgewählt wurden, dieses Jahr zu heiraten. (MarrM(1,: )= ID des Individuums, MarrM(2,: )= Alter. Analog für MarrF) Jetzt muss ich diese miteinander verlinken. In MarriageProbM stehen die Wahrscheinlichkeiten, dass z.b. ein 30 Jähriger eine Partnerin unter 20, zwischen 20-24, 25-29 usw. heiratet.

Code:

%% Matchmaking
Lm=length(MarrM);
Lf=length(MarrF);
for lm=Lm:-1:1
    rm=rand;
    % altersspezifische Spalte auswählen
    if MarrM(lm,2)>=15 && MarrM(lm,2)<20
        SpouseAgeProb=MarriageProbM(:,2)';
    elseif MarrM(lm,2)>=20 && MarrM(lm,2)<25
        SpouseAgeProb=MarriageProbM(:,3)';
    elseif MarrM(lm,2)>=25 && MarrM(lm,2)<30
        SpouseAgeProb=MarriageProbM(:,4)';
    elseif MarrM(lm,2)>=30 && MarrM(lm,2)<35
        SpouseAgeProb=MarriageProbM(:,5)';
    elseif MarrM(lm,2)>=35 && MarrM(lm,2)<40
        SpouseAgeProb=MarriageProbM(:,6)';
    elseif MarrM(lm,2)>=40 && MarrM(lm,2)<50
        SpouseAgeProb=MarriageProbM(:,7)';
    elseif MarrM(lm,2)>=50 && MarrM(lm,2)<60
        SpouseAgeProb=MarriageProbM(:,8)';
    else
        SpouseAgeProb=MarriageProbM(:,9)';
    end
    SpouseAge=sum(rm>=cumsum([0,SpouseAgeProb]));
    % 15-19 Jährige Partnerin
    if SpouseAge==2
        % weise Partnerin aus entsprechender Altersklasse per Zufall zu
        % (falls vorhanden)
        m=find(MarrF(:,2)<20);
        if m~=0
            m2=randi(length(m));
            % Verlinke ID des Ehegatten
            Pop(MarrM(lm,1),11)=MarrF(m2,1);
            Pop(MarrF(m2,1),11)=MarrM(lm,1);
            % setze Zivilstatus auf verheiratet
            Pop(MarrM(lm,1),4)=1;
            Pop(MarrF(m2,1),4)=1;
            % Lösche Paar aus Pool
            MarrF(m2,:)=[];
            MarrM(lm,:)=[];
            MarriageCounter=MarriageCounter+1;
        end
    % 20-24 Jährige Partnerin
    elseif SpouseAge==3
        m=find(MarrF(:,2)>=20 & MarrF(:,2)<25);
        if m~=0
            m2=randi(length(m));
            Pop(MarrM(lm,1),11)=MarrF(m2,1);
            Pop(MarrF(m2,1),11)=MarrM(lm,1);
            Pop(MarrM(lm,1),4)=1;
            Pop(MarrF(m2,1),4)=1;
            MarrF(m2,:)=[];
            MarrM(lm,:)=[];
            MarriageCounter=MarriageCounter+1;
        end
    % 25-29 Jährige Partnerin
    elseif SpouseAge==4
     % .... (analog die anderen Altersklassen)  
    % 60+ Partnerin
    else
        m=find(MarrF(:,2)>=60);
        if m~=0
            m2=randi(length(m));
            Pop(MarrM(lm,1),11)=MarrF(m2,1);
            Pop(MarrF(m2,1),11)=MarrM(lm,1);
            Pop(MarrM(lm,1),4)=1;
            Pop(MarrF(m2,1),4)=1;
            MarrF(m2,:)=[];
            MarrM(lm,:)=[];
            MarriageCounter=MarriageCounter+1;
        end
    end
end
 


Wenn keine passende Partnerin im Pool vorhanden ist, passiert nichts, dann wird auch nichts gelöscht. Wenn dies oft genug vorkommt und mehr als 1 Mann in MarrM bleibt bis zum letzten Durchlauf der Schleife, dann läuft das Programm durch. Sobald aber nur noch 1 Mann in MarrM verbleibt, bringt er die Fehlermeldung, dass lm die Array bounds von MarrM(lm,1) übersteigen. MarrM beinhaltet dann nur noch einen Wert (1x1 Matrix), lm ist dann aber immer =2. das macht für mich gar keinen sinn, weil er ja pro Durchlauf max. 1 Eintrag löscht und somit immer mindestens lm Einträge in der Matrix haben müsste.

Hoffe, das hilft weiter
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 23.11.2018, 14:09     Titel:
  Antworten mit Zitat      
Hallo,

length ist bei Matrizen die größte Dimension. Das mag in den meisten Fällen das Ergebnis bringen, was man erwartet. In Einzelfällen aber eben vielleicht auch nicht, und das wird dann schwierig nachzuvollziehen.

Ist jetzt schwierig für mich, da durchzusteigen. Am einfachsten wäre es, wenn man ein nachvollziehbares Beispiel im Debugging-Modus durchgehen könnte.

Ein Problem, das ich auf jeden Fall sehe: statt if m~=0 solltest du if ~isempty(m) verwenden, denn 0 kommt da nie heraus.

Statt
Code:
m=find(MarrF(:,2)<20);
        if m~=0

sollte auch
Code:
if any(MarrF(:,2)<20)

möglich sein.

Vielleicht hilft das ja schon mal weiter.

Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Steini
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 15.11.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 23.11.2018, 15:25     Titel:
  Antworten mit Zitat      
Hallo Harald

vielen Dank für deine Antwort. Genau das, was du in deinem ersten Satz beschreibst, war hier wohl das Problem. Wenn die Matrix auf eine Zeile geschrumpft ist (->1x2), hat er nicht mehr die Länge der Spalte genommen, sondern die Länge der Zeilen. Ich habe dies abgeändert und nun funktioniert es ohne Fehlermeldung. Vielen lieben Dank Smile

Auch die anderen Punkte habe ich abgeändert. Hab da wie gesagt leider keine Erfahrung mit dem Programm und nehme dann einfach das, was am naheliegendsten für mich ist und versuche bei Fehlermeldungen im Trial and Error Verfahren das zu lösen. Dass sich der Fehler hier ganz oben in der ersten Zeile verstecken könnte, darauf bin ich leider nicht gekommen Smile
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 - 2024 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.