Verfasst am: 14.12.2010, 15:18
Titel: Zeitachse dynamisch in Intervalle einteilen
Hallo,
ich habe folgendes Problem: Ich möchte eine beliebige Kurve mit Geraden annähern. Dafür plotte ich mir eine eine Funktion über die Zeit t. Nun zeichne ich eine Ausgleichsgerade durch die Punkte der Funktion. Als nächstes teile ich meine Zeitachse in zwei Intervalle und zeichne in jedem Intervall jeweils eine neue Ausgleichsgerade durch die Punkte der Kurve. Dieses Schema möchte ich nun n Mal wiederholen, bis irgenein Abbruchkriterium erfüllt ist. Das zeichnen der Kurve und der ersten Ausgleichgeraden kriege ich noch hin. Auch nach dem ersten Schnitt geht es noch. Mein Problem ist jetzt, dass ich für jedes Mal, wenn ich mein t schneide, neue Zeitvektoren definieren muss, um die Funktionswerte in jedem Teilintervall zu erzeugen. Bei wenigen durchläufen kann man das ja noch manuell programmieren, aber wie kann man das für n durchläufe geschickter machen?
Vielleicht kann mir jemand einen kleinen Stupser in die richtige Richtung geben. Bin für jede Anregung dankbar.
vielen vielen Dank. Das ist schon mal eine sehr große Hilfe für mich. Bin nämlich noch blutiger Matlabanfänger. Deswegen habe ich doch noch einige Fragen offen. Und zwar, wird jetzt in deiner Lösung das Hauptintervall in gleich große Stücke unterteilt? Hbe ich das richtig verstanden? Könnte man auch Teilstücke erzeugen, deren Größe sich nach jedem Durchlauf der Schleife ändert? Also ich habe da konkreter an sowas gedacht:
Das mit den Unstetigkeitsstellen ist in der Tat ein Problem. Hab ich jetzt auch gemerkt. Die Idee mit Splinefit ist ganz gut, allerdings soll ich das mit Geradenstücken annähern. Die nächste Idee ist es, das ganze rekursiv zu programmieren. Eine Funktion soll sich immer wieder selber aufrufen und somit das Hauptintervall immer feiner unterteilen. Wie das gehen soll, weiss ich noch nicht. Muss ich mich erstmal reinfuchsen. Bin nach wie vor dankbar für jede Anregung.
ich hab hier mal einen code geschrieben der das gewünschte macht. Einfach mal speichern und lin_approx eintippen. Allerdings wird die Funktion nicht sonderlich gut approximiert. Der maximale Abstand ist kein gutes Kriterium zum hinzufügen eines neuen "Knotenpunktes". Ich hoffe du kannst damit was anfangen
for l = 1:10 % mypp ist so ähnlich wie pchip nur mit der Möglichkeit auch lineare Polynome (Ordnung = 2) zu erstellen
pp = mypp(t(ind)',eye(length(ind)),2);
phi = ppval(pp,t)';
% Parameterschätzung
par = phi\data;
% Simulation sim = phi*par;
% Punkt mit maximaler Abweichung finden,der noch nicht in ind enthalten ist
temp = data - sim;
temp(ind) = 0;
[v_max,i_max] = max(abs(temp));
% neuen Punkt hinzufügen
ind = [ind,i_max];
ind = sort(ind);
end
function pp = mypp(breakpoints,data,order) % generates piecewise polynom that interpolates data % pp = mypp(breaks,data,order) % breaks - arguments % data - corresponding data vector % order - interpolation order (2=linear,4=cubic) % breakpoints müssen äquidistant sein
if size_data(1) ~= 1
coef = zeros(size_data(1)*(length(breakpoints)-1),order);
for k = 1:size_data(1)
p = mypp(breakpoints,data(k,:),order);
coef(k:length(breakpoints):size_data(1)*(length(breakpoints)-1),:) = p.coefs;
end end
Tausend Dank für deine Mühen. Jetzt muss ich mich erstmal in deinen Code reindenken und verstehen wo was passiert;) Ist aber schon mal ne Riesenhilfe. Jetzt hab ich zumindest schon Mal etwas, wo ich schauen kann wie es geht.
Viele Grüsse.
matlab!
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 25.12.2010, 14:28
Titel:
Hallo, hab das gleiche Problem mal bearbeitet. Wenn ich meine alte USB-HD finde poste ich die .m
War irgendwie einfacher als oberhalb.
Matlab!
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 25.12.2010, 16:48
Titel:
Code:
function[xc,yc]= d1comp(x,y,delta)
%D1COMP [xc,yc]= d1comp(x,y,delta) % [x,y] wird so zu xc,yc komprimiert, dass die Abweichung zwischen [x,y] und % der Gerade mit den Stützpunkten [xc,yc] kleiner ist als delta. if ~issorted(x), error('x nicht sortiert'), end
len=length(x);
xc=zeros(1,len);
yc=zeros(1,len);
%Startpunkt
xc(1)=x(1);
yc(1)=y(1);
%maximale Steigungen, die alle vorhergehenden Punkte beinhaltet
mup=+inf;
mlow=-inf;
% aktueller index komp. daten
kc=1;
for k=2:len
% Neue Steigung
m=(y(k) -yc(kc))/(x(k)-xc(kc));
% sind die neuen Steigungen zu hoch oder zu niedrig, dann ist der % vorhergehende punkt neuer startpunkt. if(m>mup)||(m<mlow)
kc=kc+1;
xc(kc)=x(k-1);
yc(kc)=y(k-1);
mup=(y(k)+delta -yc(kc))/(x(k)-xc(kc));
mlow=(y(k)-delta -yc(kc))/(x(k)-xc(kc));
else
%ggf Anpassung der Grenzen.
mup=min(mup,(y(k)+delta -yc(kc))/(x(k)-xc(kc)));
mlow=max(mlow,(y(k)-delta -yc(kc))/(x(k)-xc(kc)));
end end
% punkte cutten
xc(kc+1:end)=[];
yc(kc+1:end)=[];
fprintf('Kompression auf %d%%\n',ceil(100*kc/len));
naja, nicht wirklich einfacher...
Allerdings verwende ich diesen Algorithmus, dessen Name bekannt ist, mir aber nicht einfällt in der Arbeit zur Echzeitkompression von Messdaten. (Die forloop wird hierbei als callback fcn und schreibt nur dann in die Datenbank, wenn die Abweichung von der Gerade größer ist als delta.
Hey,
vielen Dank auch für diesen Lösungsvorschlag. Werde ich mir mal gleich anschauen. Hab in der Zwischenzeit auch ein eigenes Programm geschrieben. Allerdings läuft es noch nicht ganz rund. Poste es mal die tage.
Viele Grüße.
Einstellungen und Berechtigungen
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
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.