goMatlab - Mein MATLAB Forum

Mein MATLAB Forum

 
Login  | Registrieren
Bücher:

Einstieg in das Programmieren mit MATLAB

Fachkräfte:
Softwareentwickler - Schwerpunkt Codegenerierung aus Matlab/Simulink (m/w)
Modellentwicklung und automatische Codegenerierung mittels Matlab/Simulink
SILVER ATENA Electronic Systems Engineering GmbH - München

Software-Entwicklungsingenieur (m/w) DSP-Entwicklung
Implementierung der Signalverarbeitungsalgorithmen
Rohde & Schwarz GmbH & Co. KG - München

Engineer - Experte für Leistungselektronik für Mobilität (m/w)
Thermal Management/Kühlung, Simulation, Projektarbeit
Siemens AG - München

Aeromechaniker (m/w)
Aerodynamische und flugmechanische Vor-/Feinauslegung von Lenkflugkörpern
LFK-Lenkflugkörpersysteme GmbH - Unterschleißheim (ab 2011 Schrobenhausen)

TargetLink Resident Engineer für Audi (w/m)
Erarbeitung innovativer Lösungen im Bereich der modellbasierten Entwicklung und Seriencodegenerierung
dSPACE GmbH - Ingolstadt

weitere Angebote

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

X aufeinanderfolgende Zeichen in Vektor suchen

 

pooz
Forum-Anfänger
Forum-Anfänger

Beiträge: 26
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.07.2010, 18:44     Titel: X aufeinanderfolgende Zeichen in Vektor suchen
  Antworten mit Zitat      
Hi,

kurz und knackig:

Suche in Vektor
Code:
0     0     1     1     1     1     1     0     0     1     1

jene Stellen, die mindestens 4 x die "1" hintereinander enthält.

Also:
Start = 3
Ende = 7


Intention:
Suche in gegebenen Vektor jene Start- und Endpositionen, die immer mindestens 4 Samples lang (1 Sample = 1 Element) auf True waren.

Vielen Dank
Private Nachricht senden Benutzer-Profile anzeigen


denny
Supporter
Supporter

Beiträge: 1537
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2007b, R2009b
     Beitrag Verfasst am: 14.07.2010, 20:39     Titel:
  Antworten mit Zitat      
Hallo

z.B so:
Code:

Laenge  = 4
A       =  [0 ,0 ,1 ,1 ,1,1 ,1,0,0,1,1]
Start  = strfind([0 A], [0 ones(1,Laenge)])
Ende  = strfind([A 0], [ones(1,Laenge) 0])+Laenge-1
 
Private Nachricht senden Benutzer-Profile anzeigen
 
josekamara
Forum-Meister
Forum-Meister

Beiträge: 514
Anmeldedatum: 26.04.08
Wohnort: München
Version: ---
     Beitrag Verfasst am: 14.07.2010, 21:02     Titel:
  Antworten mit Zitat      
Hier bitte:
Code:

laenge = 4;

x = [0   0   1    1    1    1    1    0    0    1    1];
p = ones(1,laenge);

A=[];
B=[];

for i=1:(length(x)-laenge)
   
    A(end+1,:) = x(i:i+laenge-1) - p;
   
    if A(end,:) == zeros(1,laenge)
    B(end+1,:) = [i    i+laenge-1];
    end
   
end
 


B Stellt Alle Start und Ende für den zugehörigen Vektor. bei laenge 4 kriegst du 2 Fälle und bei laenge 5 kriegst du einen Fall von 3 bis 7.

Gruß

Jose
_________________

Simulation

Zuletzt bearbeitet von josekamara am 14.07.2010, 21:06, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen
 
pooz
Forum-Anfänger
Forum-Anfänger

Beiträge: 26
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.07.2010, 21:04     Titel:
  Antworten mit Zitat      
@denny
Tatsache! Nicht schlecht. Vorallem liefert Tic/Toc schnelle Zeiten.
Jedenfalls schneller als meine Methode.

Gibt es evtl eine noch effizientere Methode? Ich frage aus 2 Gründen:
Zum Einen möchte ich später diesen Algorithmus nach C portieren, zum Anderen wundert es mich, dass man einen Vektor-Vergleich (also finde A in B, wobei length(A)<length(B)) mit einem String-Befehl löst.

(Ich habe es vergeblich mit "ismember" und "intersect" versucht.)

Aber vielen Dank dafür!!
Private Nachricht senden Benutzer-Profile anzeigen
 
pooz
Forum-Anfänger
Forum-Anfänger

Beiträge: 26
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.07.2010, 22:19     Titel:
  Antworten mit Zitat      
@Jose,

vielen Dank.

Deins funktioniert auch!
Bei sehr großen Vektoren allerdings benötigt das viel mehr Rechenzeit. Ich vermute, das liegt an der FOR-Schleife.

Ich bin allerdings auf der Suche nach einem rechengünstigen Algorithmus. Mit der Version von denny bin ich schon auf dem guten Weg, denke ich Smile
Private Nachricht senden Benutzer-Profile anzeigen
 
denny
Supporter
Supporter

Beiträge: 1537
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2007b, R2009b
     Beitrag Verfasst am: 15.07.2010, 09:20     Titel:
  Antworten mit Zitat      
Hallo

es gibt noch eine Möglichkeit über DIFF das zu lösen

Code:

Laenge = 4
A       =  [0 ,0 ,1 ,1 ,1,1 ,1,0,0,1,1]

dA     = [diff(A)];

Start = find(dA==1)+1
Ende   = find(dA==-1)


if isempty(Start)&&~isempty(Ende) ||...
 (~isempty(Start)&& Start(1) > Ende(1) )
 Start= [1 Start];
end

if  ~isempty(Start)&&isempty(Ende)||...
 (~isempty(Ende)&& Start(end) > Ende(end))
   Ende = [Ende length(A)]
end

posOk = (Ende-Start) >=Laenge

Start = Start(posOk)
Ende = Ende(posOk)

 
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Forum-Guru
Forum-Guru

Beiträge: 393
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 6.5, 2009a
     Beitrag Verfasst am: 15.07.2010, 10:21     Titel:
  Antworten mit Zitat      
Hallo,

Denny's Methode ist schwer zu übertreffen:
Code:

Laenge  = 4
A       =  [0 ,0 ,1 ,1 ,1,1 ,1,0,0,1,1]
Start  = strfind([0 A], [0 ones(1,Laenge)])
Ende  = strfind([A 0], [ones(1,Laenge) 0])+Laenge-1
 

Das STRFIND auch mit nicht-CHAR-Arrays arbeitet ist sehr praktisch und sollte in der Dokumentation deutlicher betont werden.
Eine Schwachstlle ist "[0 A]" und [A, 0]" für sehr große Vektoren A: Es werden im schlimmsten Fall (2*(length(A)+1)*8) Bytes im Speicher blockiert. Das ist zwar nur temporär, wenn der Rechner aber den RAM-Inhalt auf die Platte schreiben muss, wird es unerträglich langsam.
Ich vermute für riesige A ist dies sicherer (also schneller):
Code:

Laenge  = 4
A       =  (rand(1, 1e8) > 0.5);  % Beispiel Daten
Start  = strfind(A, [0 ones(1,Laenge)]);
if all(A(1:Laenge)  == 1)
  Start = [1, Start];
end
Ende = strfind(A, [ones(1,Laenge) 0])+Laenge-1;
if all(A(end-Laenge+1:end)  == 1)
  Ende = [1, Ende];
end
 

Für kleine A ist das aber vermutlich langsamer.

Wenn Du das ganze in C schreibst, kannst Du die beiden STRFIND glichzeitig laufen lassen, was wohl etwa doppelt so schnell sein sollte.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
pooz
Forum-Anfänger
Forum-Anfänger

Beiträge: 26
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.07.2010, 17:45     Titel:
  Antworten mit Zitat      
Danke, ihr Beiden.

@denny:
Dein neuer Algo findet nur das erste Paar. Weitere Folgen, die auch die Bedingungen erfüllen, werden nicht angezeigt.

@Jan:
Ich komme nicht auf das gleiche Ergebnis:
Das leichteste, was ich beheben konnte war, auf den Lösungsvektor "Start" 1 zu addieren. Dann klappts.
Aber der "Ende"-Vektor fängt mit 1 an? Und das Ende einer letzten Folge ist mir auch nicht ersichtlich (siehe Ende(end))

Viele Grüße!
Private Nachricht senden Benutzer-Profile anzeigen
 
denny
Supporter
Supporter

Beiträge: 1537
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2007b, R2009b
     Beitrag Verfasst am: 15.07.2010, 23:13     Titel:
  Antworten mit Zitat      
Hallo pooz,

habe kleinen Fehler beim Abziehen gemacht, im Beispiel kommen ja 5 Einsen hintereinander, habe ja darauf getestet, und deswegen übersehen dass mit 4 Einsen es nicht funktioniert hat.

so jetzt muss es passen
Code:


Laenge= 4;
A        =  [0 ,0 ,1 ,1 ,1,1 ,1,0,0,1,1,1,1]

dA     = [diff(A)];

Start = find(dA==1)+1
Ende   = find(dA==-1)


if isempty(Start)&&~isempty(Ende) ||...
 (~isempty(Start)&& Start(1) > Ende(1) )
 Start= [1 Start];
end

if  ~isempty(Start)&&isempty(Ende)||...
 (~isempty(Ende)&& Start(end) > Ende(end))
   Ende = [Ende length(A)]
end

% musste eine 1 dazu addieren
posOk = (Ende-Start+1) >=Laenge

Start = Start(posOk)
Ende = Ende(posOk)
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Forum-Guru
Forum-Guru

Beiträge: 393
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 6.5, 2009a
     Beitrag Verfasst am: 16.07.2010, 01:04     Titel:
  Antworten mit Zitat      
Hallo Pooz,

Stiimt, die letzte Version war fehlerreich. Nächster Versuch:
Code:

Laenge  = 4;
A       =  (rand(1, 1e8) > 0.5);  % Beispiel Daten
Start  = strfind(A, [0, ones(1, Laenge)]) + 1;
if all(A(1:Laenge)  == 1)
  Start = [1, Start];
end
Ende = strfind(A, [ones(1, Laenge), 0]) + (Laenge - 1);
if all(A(end - Laenge + 1:end)  == 1)
  Ende = [Ende, length(A)];
end
 


Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
pooz
Forum-Anfänger
Forum-Anfänger

Beiträge: 26
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.07.2010, 19:21     Titel:
  Antworten mit Zitat      
Vielen, Ihr beiden.
@ Jan: Funktioniert!
@ Denny: Bei folgender Sequenz gibts einen Fehler:
Code:
A = [zeros(1,1020) 1 1 1 1];

Eine Idee?

Zusätzlich hätte ich eine 2. Frage passend dazu, an Alle:
Wie kann ich am besten/effizientesten/einfachsten nun alle Bereiche in Vektor A auf Null setzen, die diese Bedingung (Mindestlänge) nicht erfüllen? Oder andersherum formuliert: Wie kann ich einen neuen Vektor A_neu erstellen, der in den zurückgegebenen Intervallen -also von Start bis Ende- true ist, und überall anders false?


Ich habe das leider nur mit einer For-Schleife lösen können:
Code:
 
    A_neu = zeros(1,length(A));
    for l = 1:length(Start)
        A(Start(l):Ende(l)) = true;
    end
 


Danke für Eure Hilfe!
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Forum-Guru
Forum-Guru

Beiträge: 393
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 6.5, 2009a
     Beitrag Verfasst am: 19.07.2010, 20:41     Titel:
  Antworten mit Zitat      
Hallo Pooz,

Du hast Denny geschrieben, dass es "einen Fehler gibt" - es ist immer praktisch auch zu lesen, wie die Fehlermeldung denn lautet.

Die gepostete FOR-Schleife läßt sich beschleunigen: Bisher ist "A_neu" ein DOUBLE Vektor, in den Du "true"-Werte schreibst. Diese werden intern von LOGICAL (eigentlich ein uint8) nach DOUBLE gecastet (heißt das so auf Deutsch?). Schneller wäre es, gleich ein LOGICAL Vektor zu erstellen:
Code:
A2 = false(1, length(A));
on = true;
for l = 1:length(Start)
    A2(Start(l):Ende(l)) = on;   % Nicht "A"
end

Ausserdem habe ich die Antwort der Funktion(!) TRUE abgespeichert, weil ein Funktionsaufruf einen größeren Overhead hat, als das Kopieren einer Variable.

Eine andere Lösung als die FOR-Schleife wäre CUMSUM:
Code:
A2 = zeros(1, length(A));
A2(Start) = 1;
A2(Ende) = -1;
A2 = logical(cumsum(A2));

Leider arbeitet CUMSUM nicht mit INT8 Vektoren, so dass man etwas Speicherplatz für den DOUBLE Vektor verschwendet.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
denny
Supporter
Supporter

Beiträge: 1537
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2007b, R2009b
     Beitrag Verfasst am: 19.07.2010, 22:48     Titel:
  Antworten mit Zitat      
Hallo pooz

Du hast recht , es kommt zu einem Fehler in der IF-Bedingung,
Zitat:

??? Attempted to access Ende(1); index out of bounds because numel(Ende)=0.


Habe Klammer falsch gesetzt, jetzt soll es laufen.
Code:

Laenge= 4;
% A        =  [0 ,0 ,1 ,1 ,1,1 ,1,0,0,1,1,1,1]
A = [zeros(1,1020) 1 1 1 1];

dA     = diff(A);

Start = find(dA==1)+1;
Ende   = find(dA==-1);


if ~isempty(Ende)&&( isempty(Start) ||...
 ~isempty(Start)&& Start(1) > Ende(1))
 Start= [1 Start];
end

if  ~isempty(Start)&&( isempty(Ende)||...
  ~isempty(Ende)&& Start(end) > Ende(end))
   Ende = [Ende length(A)];
end

% musste eine 1 dazu addieren
posOk = (Ende-Start+1) >=Laenge;

Start = Start(posOk);
Ende = Ende(posOk);
 
 
Private Nachricht senden Benutzer-Profile anzeigen
 
pooz
Forum-Anfänger
Forum-Anfänger

Beiträge: 26
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.07.2010, 18:45     Titel:
  Antworten mit Zitat      
Vielen Dank an alle, für die Hilfe.

jetzt habe ich eine 2. Frage, passend dazu:

Wie kann ich nun die vielen Start&Ende-Paare, aus den jeweiligen Vektoren "Start" und "Ende" in einem Schritt zur Adressierung verwenden?
Zur Zeit gehe ich noch mit einer Schleife durch, und erhalte einzelnd ein Start&Ende-Paar, was ich zur Adressierung verwende:
Code:
% Start = (1, 5, 20);
% Ende  = (3, 9, 30);

for i = 1:length(Ende)
        x(Start(i):Ende(i)) = true;
end

Geht es effizienter? Vielleicht ohne Schleife?

Vielen Dank für eure Hilfe!
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Forum-Guru
Forum-Guru

Beiträge: 393
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 6.5, 2009a
     Beitrag Verfasst am: 30.07.2010, 14:47     Titel:
  Antworten mit Zitat      
Hallo Pooz,

mir war so, als hätte ich das am 19.07.2010, 20:41 bereits beantwortet.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

Options and Permissions
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
.


goMatlab ist ein Teil des goForen-Labels
goForen.de goMATLAB.de goLaTeX.de goPCB.de


 Impressum  | Werbung/Mediadaten | Studentenversion | FAQ | goMatlab RSS Button RSS


Copyright © 2007 - 2010 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks
Partner: LabVIEWforum.de

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.