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

for-Schleife Problem - logical indexing

 

Benno W.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.01.2015, 15:25     Titel: for-Schleife Problem - logical indexing
  Antworten mit Zitat      
Hallo,

ich habe ein Problem mit meiner viel zu komplexen for-Schleife. Meine Matrix (600.000 x 52) soll mit den Werten eines Vektors verglichen werden und bei entsprechender Übereinstimmung in einen neuen Vektor übergeben werden.
In der for-Schleife dauert dies zu lange:

Code:

for i=1:length(Matrix_A)
    for k=1:length(Matrix_A(:,i))
       
    if Matrix_A(k,i) > 0 & Matrix_A(k,i)>= Variable_A(i,1)
        Abruf(k,i) = 1;
       
    elseif Matrix_A(k,i) > 0 & Matrix_A(k,i)< Variable_A(i,1)
        Abruf(k,i) = 0;
       
    elseif Matrix_A(k,i) == 0
        Abruf(k,i) = 0;
       
    elseif Matrix_A(k,i) < 0 & Matrix_A(k,i)<= (-1*Variable_A(i,1))
        Abruf(k,i) = -1;
   
    elseif Matrix_A(k,i) < 0 & Matrix_A(k,i)> (-1*Variable_A(i,1))
        Abruf(k,i) = 0;
    end;
    end;
end;
 


und wenn ich k weglasse:

Code:

for i=1:length(Matrix_A)
       
    if Matrix_A(:,i) > 0 & Matrix_A(:,i)>= Variable_A(i,1)
        Abruf(:,i) = 1;
       
    elseif Matrix_A(k,i) > 0 & Matrix_A(:,i)< Variable_A(i,1)
        Abruf(:,i) = 0;
       
    elseif Matrix_A(:,i) == 0
        Abruf(:,i) = 0;
       
    elseif Matrix_A(:,i) < 0 & Matrix_A(:,i)<= (-1*Variable_A(i,1))
        Abruf(:,i) = -1;
   
    elseif Matrix_A(:,i) < 0 & Matrix_A(:,i)> (-1*Variable_A(i,1))
        Abruf(:,i) = 0;
    end;
end;
 


bekomme ich fehlermeldungen wie: Index exceeds matrix dimensions.

Leider kenne ich mich in logischer Indizierung nicht so sonderlich aus, und die Werte in meiner Matrix_A sind volatil von -500 bis + 500, weswegen ich auch keine min(abs(...)) Abfrage - bezüglich der Näherung nutzen - kann. Könnt ihr mir weiterhelfen?

Grüße


Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 05.01.2015, 16:03     Titel:
  Antworten mit Zitat      
halli hallo. bin grade nicht zu hause und hab nicht so viel zeit aber ein paar schnelle anmerkungen von mir: du benutz i einmal als zeilen index und einmal als spalten index. ist das gewollt ? 2. du solltest nicht
Code:
benutzen da das zu unerwarteten ergebnissen führen kann. benutze lieber
Code:
3. du hast 5 fall unterscheidungen aber nur 3 verschiedene ergebnisse. das heist 2 fälle sind überflüssig. du brauchst alsu nur 1 -1 fälle und der rest wird dann 0 gesetzt. wenn du abruf mit 0 initiallisierst brauchst du sogar nur die 2 fälle abarbeiten bei denen es nicht 0 ist.
Code:

_________________

richtig Fragen
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: 05.01.2015, 16:12     Titel:
  Antworten mit Zitat      
Hallo Benno,

Ist Variable_A 600000x1 groß?

Dein Bsp. mittels logischer Indizierung mit Variable_A als 1x1:
Code:
Matrix_A = randi(10, 50, 10) - 5;
Variable_A = 2;

log_1 = Matrix_A > 0 & Matrix_A >= Variable_A; % 1 wenn Bedingung erfüllt, sonst 0
log_2 = Matrix_A > 0 & Matrix_A < Variable_A;
log_3 = Matrix_A == 0;
log_4 = Matrix_A < 0 & Matrix_A <= (-1*Variable_A);
log_5 = Matrix_A < 0 & Matrix_A > (-1*Variable_A);

% TEST = sum(log_1 + log_2 + log_3 + log_4 + log_5);

Abruf = Matrix_A;

Abruf(log_1) = 1; % Werte in Abruf auf 1 setzen, für die log_1 1 ist
Abruf(log_2 | log_3 | log_5) = 0;
Abruf(log_4) = -1;


Da du bei 3 der 5 Bedingungen aber eh die Werte auf 0 setzt, kann man das ganze, wie Winkow bereits schrieb, etwas vereinfachen:
Code:
log_1 = Matrix_A > 0 & Matrix_A >= Variable_A;
log_4 = Matrix_A < 0 & Matrix_A <= (-1*Variable_A);

Abruf = zeros(size(Matrix_A));
Abruf(log_1) = 1;
Abruf(log_4) = -1;


Grüße,
Seban
_________________

Richtig fragen
Debugging
Private Nachricht senden Benutzer-Profile anzeigen
 
Benno W.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.01.2015, 18:33     Titel:
  Antworten mit Zitat      
Hallo ihr beiden,



@ Winkow: Das mit dem Wechsel zwischen Zeilen & Spaltenindex ist gewollt^^ Danke für deine grundsätzlichen Tipps, ich habe Sie sofort eingebaut.

@ Seban:
Ist Variable_A 600000x1 groß? Sie ist 52x1 groß. Also die Matrix_A ist 600000x52 werden mit den 52 Datenpunkten der Variable_A verglichen. Wie kann ich dies dann in die logische Induzierung integrieren oder geht dies nur mit einer Schleife?

Klasse wie das Forum und insbesondere drei, vier Leute hier, alles am laufen halten und auch in Ihrer Freizeit, bzw. "zwischendurch" Leuten wie mir weiterhelfen!
 
Seban
Forum-Meister

Forum-Meister


Beiträge: 600
Anmeldedatum: 19.01.12
Wohnort: ---
Version: ab R2014b
     Beitrag Verfasst am: 05.01.2015, 19:03     Titel:
  Antworten mit Zitat      
Da die Schleife jetzt deutlich weniger Schritte ausführt, dauert es nicht mehr so lange wie im Eingangspost.

Code:
Matrix_A = randi(10, 600, 52) - 5;
Variable_A = rand(52, 1) - 0.5;

log_1 = false(size(Matrix_A));  % pre-allocate
log_2 = false(size(Matrix_A));
for ii = 1:size(Variable_A,1)
    log_1(:,ii) = Matrix_A(:,ii) > 0 & Matrix_A(:,ii) >= Variable_A(ii);
    log_2(:,ii) = Matrix_A(:,ii) < 0 & Matrix_A(:,ii) <= (-1*Variable_A(ii));
end

Abruf = zeros(size(Matrix_A));
Abruf(log_1) = 1;
Abruf(log_2) = -1;


Auf eine Lösung ohne Schleife komme ich im Moment auch nicht.

Grüße,
Seban
_________________

Richtig fragen
Debugging
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 05.01.2015, 21:28     Titel:
  Antworten mit Zitat      
Hallo,

Alternative zu Sebans Code ohne for-Schleife:

Code:
log_1_mod = Matrix_A > 0 & bsxfun(@ge, Matrix_A, Variable_A');
log_2_mod = Matrix_A < 0 & bsxfun(@le, Matrix_A, -Variable_A');


Grüße,
Harald
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: 06.01.2015, 16:01     Titel:
  Antworten mit Zitat      
Hallo Harald,

Das ist interessant. Jetzt kenne ich arrayfun, cellfun und bsxfun. Gerade habe ich noch structfun und spfun gefunden. Gibt es noch weitere Funktionen dieser Art?

Grüße,
Seban
_________________

Richtig fragen
Debugging
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 06.01.2015, 18:42     Titel:
  Antworten mit Zitat      
Hallo Seban,

auf Anhieb fallen mir noch datasetfun (für Dataset Arrays), varfun (für Tables, ab R2013b) und pagefun (blattweises Arbeiten mit Daten auf GPUs) ein.

Grüße,
Harald
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: 06.01.2015, 23:37     Titel:
  Antworten mit Zitat      
Super, vielen Dank!
_________________

Richtig fragen
Debugging
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.