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

Abbilden/Zuweisen von Vektoren unterschiedlicher Größe

 

pooz
Forum-Anfänger

Forum-Anfänger


Beiträge: 49
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.08.2010, 19:09     Titel: Abbilden/Zuweisen von Vektoren unterschiedlicher Größe
  Antworten mit Zitat      
Hallo,

mein Problem ist sehr einfach. Es ist allerdings etwas schwierig in Worte zu fassen. Ich probiere es:

Ich habe 2 Vektoren unterschiedlicher Größe.
Vektor a ist M lang und enthält Werte im Bereich 1:N.
Vektor b ist N lang und enthält ausschließlich binäre Daten (true/false).

Jetzt möchte ich jene Indizes von a bekommen, bei denen im Intervall a-Toleranz bis a+Toleranz der Vektor b mindestens ein True enthält.

Code:

a   = [ 2 5 10 15];
b   = [ 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1];
Tol = [ 3 3 4 1];

% Ergebnis soll sein:
erg = [0 1 1 1]
 


Begründung:
Bereich -1:5 ist in b keine 1 vorhanden.
Bereich 2:8 ist mind. eine 1 vorhanden.
Bereich 6:14 ist mind. eine 1 vorhanden.
Bereich 14:16 ist mind. eine 1 vorhanden.

Problem: Der Bereich kann auch negative Grenzen haben (siehe 1. Bereich)
Das ganze möglichst ohne Schleife, da es ressourcenschonend sein soll (der Code wird später nach C++ portiert für eine Echtzeitanwendung)

Ich hoffe, es kann mir jemand helfen.
Vielen Dank und viele Grüße
Private Nachricht senden Benutzer-Profile anzeigen


denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 09.08.2010, 19:40     Titel:
  Antworten mit Zitat      
Hallo,

zumindest eine Schleife wird hier nötig sein:
Code:

a   = [ 2 5 10 15];
b   = logical([ 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1]);
Tol = [ 3 3 4 1];
res = false(size(a));

for k=1:length(a)
   
   s= max(a(k)-Tol(k),1);
   e= min(a(k)+Tol(k), length(b));
   res(k) =  any(b(s:e));
end

res
 
Private Nachricht senden Benutzer-Profile anzeigen
 
pooz
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 49
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.08.2010, 20:13     Titel:
  Antworten mit Zitat      
Hi denny,

vielen Dank.
Deine Lösung scheint schneller als meine zu sein:

Code:
clc
clear all
a   = [ 2 5 10 15];
Tol = [ 6 3 4 1];
b   = [ 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1];

res = zeros(1,length(a));

q = find (b);
for i = 1:length(a)
        res(i) = any (intersect( (a(i)-Tol(i) : a(i)+Tol(i)), q ));
end

res


Was ich mich immer gefragt habe, ist, ob man die Abfrage an b, in deinem Fall mittels "any" , nicht einmalig, also vektorbasiert machen kann? D.h. alle Intervalle werden auf einmal abgefragt.
(Siehe meine untere Frage hier, auf die noch keine Antwort kam Sad )

Dann könnte die Schleife auch noch eliminiert werden.
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: 09.08.2010, 22:32     Titel:
  Antworten mit Zitat      
Hallo Denny,

Vielleicht ist es schneller, auch den MIN/MAX Teil aus der Schleife zu ziehen:
Code:

a   = [ 2 5 10 15];
b   = logical([ 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1]);
Tol = [ 3 3 4 1];
res = false(size(a));

s = max(a-Tol,1);
e = min(a+Tol, length(b));
for k=1:length(a)
   res(k) =  any(b(s(k):e(k)));
end
 

Wenn es aber nach C++ portiert werden soll, ist es nicht notwendig, es möglichst schnell in Matlab laufen zu lassen, oder???

Gruß Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
pooz
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 49
Anmeldedatum: 04.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.08.2010, 22:43     Titel:
  Antworten mit Zitat      
Hi Jan,

vielen Dank.

Naja, ich dachte, ich programmiere es schon von vornherein so optimal, wie es geht. Dann fällt die Portierung auch leichter, und man muss nicht alles von vorn überlegen Smile

Aber es sieht schon alles mit eurer Hilfe ganz gut aus.
Gänzlich die Schleife vermeiden lässt sich nicht? Siehe link.
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: 09.08.2010, 23:51     Titel:
  Antworten mit Zitat      
Hallo Pooz,

ein in Matlab effizientes Programm ist im Allgemeinen nach einer direkten Protierung nach C++ nicht effizient - und umgekehrt.
Deshalb muss man eigentlich für eine Portierung die ganze Optimierei noch mal von vorne starten.

Während in Matlab Vektorisierung oft starke Vorteile bringt, ist in C im Allg. das Gegenteil der Fall, da dabei unnötige temporäre Arrays erzeugt werden.

Noch eine Idee die Schleife zu vermeiden: Wenn Tol riesig ist, ist es aufwändig den temporären Vektor "b(s(k):e(k))" zu erstellen. Falls alle Zahlen in diesem Vektor 0 sind, ist auch der erste und letzte Wert von "CUMSUM(b(s(k):e(k)))" gleich.

Code:

a   = [ 2 5 10 15];
Tol = [ 3 3 4 1];
b   = single([ 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1]);
% Je nach Anzahl der Einsen kann auch DOUBLE nötig sein.
% Schau mal nach, was schneller ist!
B = cumsum(b);

s = max(a-Tol,1);
e = min(a+Tol, length(b));
res = (B(s) ~= B(e));
% Für Tol == 0 muss res noch speziell getestet werden:
% index = a(Tol == 0);
% res(index) = logical(b(index));
 

Leider läuft CUMSUM nicht für UINT32 in Matlab 2009b. Wenn Du weniger als 2^32 oder 2^16 Einsen hast, wäre es eine gute Idee, ein eigenes CUMSUM als Mex zu schreiben.

Gruß, Jan
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.