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

Zeitachse dynamisch in Intervalle einteilen

 

jid
Forum-Newbie

Forum-Newbie


Beiträge: 6
Anmeldedatum: 19.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.12.2010, 15:18     Titel: Zeitachse dynamisch in Intervalle einteilen
  Antworten mit Zitat      
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.

Viele Grüße.
Private Nachricht senden Benutzer-Profile anzeigen


Thomas84
Forum-Meister

Forum-Meister


Beiträge: 546
Anmeldedatum: 10.02.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.12.2010, 12:37     Titel:
  Antworten mit Zitat      
Code:

t = 0:1000;
data = randn(size(t));

n = 7;

ind = linspace(1,length(t),7);
ind  = floor(ind);

for k = 2:n
p(k,:) = polyfit(t(ind(k-1):ind(k)),data(ind(k-1):ind(k)),1);    % koeffizienten
end
 


so?
Private Nachricht senden Benutzer-Profile anzeigen
 
jid
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 6
Anmeldedatum: 19.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.12.2010, 13:33     Titel:
  Antworten mit Zitat      
Hey,

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:

Code:

FEHLER = abs(ausgleichsgerade'-funktion);
FEHLER_max = max(FEHLER)
t_index = find(FEHLER(:)>=FEHLER_max);
 


Jedes Mal, wenn die Differenz zwischen Ausgleichsgerade und Funktion maximal ist, soll er genau an dieser Stelle schneiden.

Gruß. Danke nochmals.
Private Nachricht senden Benutzer-Profile anzeigen
 
Thomas84
Forum-Meister

Forum-Meister


Beiträge: 546
Anmeldedatum: 10.02.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.12.2010, 14:31     Titel:
  Antworten mit Zitat      
wenn du deine daten nur irgendwie approximieren willst kannst du z.B. auch splinefit verwenden:

http://www.mathworks.com/matlabcent.....eexchange/13812-splinefit

Bei deiner Methode muss die Approximationsfunktion nicht stetig sein. Ist das so gewollt?
Private Nachricht senden Benutzer-Profile anzeigen
 
jid
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 6
Anmeldedatum: 19.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 20.12.2010, 14:27     Titel:
  Antworten mit Zitat      
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.
Private Nachricht senden Benutzer-Profile anzeigen
 
Thomas84
Forum-Meister

Forum-Meister


Beiträge: 546
Anmeldedatum: 10.02.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 21.12.2010, 07:38     Titel:
  Antworten mit Zitat      
Hallo

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

viele Grüße
Thomas


Code:


function lin_approx(t,data)

if nargin == 0
    t = (linspace(0,10,1000))';
    data = asinh(t) + 0.1*randn(size(t));
end

%v_max = 1;
ind = [1,length(t)];

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

plot(t,[data,sim]);zoom on;

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

size_data = size(data);

if size_data(2) ~= length(breakpoints)
    warning('MATLAB:mypp:InvalidSize','the length of data does not match length of breakpoints');
end

if nargin == 2
    order = 4;
end

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

pp.form = 'pp';
pp.breaks = breakpoints;

coefs = zeros(length(breakpoints)-1,order);
dl = breakpoints(2)-breakpoints(1);

if order == 4
    up = [-2/dl^3 3/dl^2 0 0];
    down = [2/dl^3 -3/dl^2 0 1];
elseif order == 2
    up = [1/dl,0];
    down = [-1/dl,1];
end
   
coefs(1,:) = data(1)*down;

for k = 2:length(breakpoints)-1
    coefs(k-1,:) = coefs(k-1,:) + data(k)*up;
    coefs(k,:) = coefs(k,:) + data(k)*down;
end

coefs(end,:) = coefs(end,:) + data(end)*up;

pp.coefs = coefs;
pp.pieces = length(breakpoints)-1;
pp.order = order;
pp.dim = 1;

if size_data(1) ~= 1
    pp.dim = size_data(1);
    pp.coefs = coef;
end
 
Private Nachricht senden Benutzer-Profile anzeigen
 
jid
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 6
Anmeldedatum: 19.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 21.12.2010, 12:47     Titel:
  Antworten mit Zitat      
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.
Private Nachricht senden Benutzer-Profile anzeigen
 
matlab!

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.12.2010, 14:28     Titel:
  Antworten mit Zitat      
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: ---
     Beitrag Verfasst am: 25.12.2010, 16:48     Titel:
  Antworten mit Zitat      
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.
 
jid
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 6
Anmeldedatum: 19.05.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.12.2010, 13:08     Titel:
  Antworten mit Zitat      
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.
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.