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

Hilfe bei der Verarbeitung von mehreren Struct Inhalten

 

elcachon
Forum-Century

Forum-Century


Beiträge: 190
Anmeldedatum: 03.05.11
Wohnort: ---
Version: 7.6.0(R2008a), 7.8.0(R2009a)
     Beitrag Verfasst am: 09.11.2011, 16:09     Titel: Hilfe bei der Verarbeitung von mehreren Struct Inhalten
  Antworten mit Zitat      
Hallo,

habe folgendes Progrämmchen:

Code:

% Anzahl der ausgewählten Panels feststellen
laenge = length(PanelData); % PanelData ist ein 3x1 struct

for xx = 1:laenge

    % Auslesen der entsprechenden Grenzwerte
    untereGrenze = PanelData(xx).edit1;
    obereGrenze  = PanelData(xx).edit2;

    % Aufruf der Funktion Peak_Detection für den Peak plot!
    [peak_data, legendData] = Peak_Detection(voltage, PanelData(xx).pop1, PanelData(xx).pop2, abtastfreq);
   
    % Untere Grenze
    [value, zeile] = min(abs(peak_data(:,1)-untereGrenze));
   
    % Übernehmen von Grenzwert bis Ende
    peak_data = peak_data((zeile:end),:);
   
    % Obere Grenze
    [value, zeile] = min(abs(peak_data(:,1)-obereGrenze));
   
    % Übernehmen von Anfang bis Grenzzeile
    peak_data = peak_data((1:zeile),:);


   
    semilogx(peak_data(:,1),20*log10((peak_data(:,2))/1e-06));grid on
end


Der Programmdurchlauf funktioniert bei einem 1x1 struct ohne Probleme:

Jetzt ist aber mein struct 3x1 groß, d.h meine Schleife läuft dreimal durch.

Ich möchte nach jedem Schleifendurchlauf die Variable
Zitat:
peak_data
nach der jeweiligen oberen und untern Grenze anpassen und die übriggebliebenen Daten an die daten des ersten Schleifendurchlaufs anfügen, doch bis jetzt hab ich noch keine Ahnung wie ich das anstellen soll, vor allem weil sich bei jedem Schleifendurchlauf auch die obere und untere Grenze ändern können

lg elcachon
Private Nachricht senden Benutzer-Profile anzeigen


elcachon
Themenstarter

Forum-Century

Forum-Century


Beiträge: 190
Anmeldedatum: 03.05.11
Wohnort: ---
Version: 7.6.0(R2008a), 7.8.0(R2009a)
     Beitrag Verfasst am: 09.11.2011, 16:56     Titel:
  Antworten mit Zitat      
Habs jetzt vorläufig so gelöst:
Code:

% Anzahl der ausgewählten Panels feststellen
laenge = length(PanelData); % PanelData ist ein 3x1 struct

for xx = 1:laenge

    % Auslesen der entsprechenden Grenzwerte
    untereGrenze = PanelData(xx).edit1;
    obereGrenze  = PanelData(xx).edit2;

    % Aufruf der Funktion Peak_Detection für den Peak plot!
    [peak_data, legendData] = Peak_Detection(voltage, PanelData(xx).pop1, PanelData(xx).pop2, abtastfreq);
   
    % Untere Grenze
    [value, zeile] = min(abs(peak_data(:,1)-untereGrenze));
   
    % Übernehmen von Grenzwert bis Ende
    peak_data = peak_data((zeile:end),:);
   
    % Obere Grenze
    [value, zeile] = min(abs(peak_data(:,1)-obereGrenze));
   
    % Übernehmen von Anfang bis Grenzzeile
    peak_data = peak_data((1:zeile),:);
   
    if (xx>1)
       % jeweils neuer schleifendurchlauf ab 2 wird an temp angehängt
        temp = [temp;peak_data];
       
    else
       % beim ersten Schleifendurchlauf
        temp = peak_data;
    end

        semilogx(temp(:,1),20*log10((temp(:,2))/1e-06));grid on
end
 


Aber wie könnte ich das noch effektiver, sprich schneller programmieren, evtl ohne for - Schleife??

Und ich bräuchte noch eine Sicherheitseinrichtung, z.B wenn die Grenzen beim 2. Schleifendurchlauf kleiner sind als beim ersten, dann sollten sie ja VOR die Daten des ersten Durchlaufs angehängt werden!!

Ich hoffe ihr könnt mir helfen!!

lg elcachon
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: 10.11.2011, 09:53     Titel:
  Antworten mit Zitat      
Hallo elcachon,

Wenn die Schleife nur über 3 Iteration läuft, wird man auch mit einer Pre-allocation nicht viel gewinnen. Ist die Schleife denn überhaupt das geschwindigkeites-limittierende Problem? Ich vermute, die Funktion Peak_Detection benötigt viel länger. Das kannst Du mit dem Profiler testen.

Das Zeichnen läßt sich beschleunigen:
Code:

  ...    
  if (xx>1)
    % jeweils neuer schleifendurchlauf ab 2 wird an temp angehängt
    temp = [temp;peak_data];
    set(LineH, 'XData', temp(:,1), ...
          'YData', 20*log10((temp(:,2))/1e-06));
  else
     % beim ersten Schleifendurchlauf
      temp = peak_data;
      LineH = semilogx(temp(:,1), 20*log10((temp(:,2))/1e-06));
      grid('on');
  end
  drawnow;
end

Wenn die Graphik immer neu gezeichnet wird, wird viel Zeit verschwendet um die vorherige Kurve zu löschen und eine neue zu erzeugen. So werden nur die Werte upgedated (oder geupdated)?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
elcachon
Themenstarter

Forum-Century

Forum-Century


Beiträge: 190
Anmeldedatum: 03.05.11
Wohnort: ---
Version: 7.6.0(R2008a), 7.8.0(R2009a)
     Beitrag Verfasst am: 10.11.2011, 11:00     Titel:
  Antworten mit Zitat      
Hallo Jan,

vielen Dank das du es dir angesehen hast!
Ja kann sein das mein Unterprogramm das Problem ist. Das hab ich übrigens auch schon mal gepostet und du und DSP haben mir dabei geholfen, aber ich hab seitdem wieder viel verändert!!

Vielleicht findest du ja noch was, was man besser machen könnte!!

Code:

%% PEAK - Detektion Sub - Function
 function [spec_peak, legendData] = Peak_Detection(voltage,  fenster, filterbreite, abtastfreq)

%%  Welche Fensterbreite wurde ausgewählt
switch (filterbreite)  
   
    case 1 % Filterbreite 200 Hz
       
        win_length = 5000;     % = 5000 µSec
       
    case 2 % Filterbreite 500 Hz
       
        win_length = 2000;     % = 2000 µSec
       
    case 3 % Filterbreite 9 kHz
       
       win_length = 111.11;   % 111.11 µSec
       
    case 4 % Filterbreite 120 kHz
       
        win_length = 8.33;     % 8.33µSec
       
    case 5 % Filterbreite 1 MHz
       
        win_length = 1;        % 1µSec
       
end

% load data_Rect_10ns.mat;
% voltage = data(:,2);
if(mod(length(voltage),2))
    voltage = voltage(1:end-1);                                             % Letzter Wert wird gelöscht
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% voltage = voltage(1:end-1);             % Letzter Wert wird gelöscht #### noch mit Abfrage realisieren##
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

N = length(voltage);                                                        % ursprüngliche Signallänge bestimmen
nfftx = win_length*1000;                                                    % Fensterlänge auf ns
optimal = nfftx * 3;                                                        % Erweiterung auf dreimalige

k   = round(optimal/N);                                                     % Anzahl ganzer Segmente
r   = mod(optimal,N);                                                       % Rest

sig_neu = repmat(voltage,k,1);                                              % Vervielfachen des Ursprungssignals auf ganze Segmente
sig_neu(optimal-r + 1:optimal) = voltage(1:r);                              % Rest anhängen um auf 3*Fensterlänge zu kommen
overlap = nfftx/2;                                                          % Überlappung zweier aufeinanderfolgender Fenster = 50%

%% Fensterauswahl und Berechnung der Filterbreite
switch lower(fenster)
    case 'hamming'
        win_seg = hamming(nfftx,'periodic');      
       
    case 'blackman'
        win_seg = blackman(nfftx,'periodic');
       
    case 'kaiser'
        win_seg = kaiser(nfftx,0.5);
       
    case 'flattop'
        win_seg = flattopwin(nfftx,'periodic');
       
    case 'hanning'
        win_seg = hann(nfftx,'periodic');
       
    case 'bartlett'
        win_seg = bartlett(nfftx);
       
    case 'boxcar'
        win_seg = rectwin(nfftx);                
end

if(optimal <= N)                                                            % Signal länger als dreifache Filterlänge --> nur 3fache Filterlänge  übernehmen
    sig_neu = voltage(1:optimal);        
    % optimal = N;
    % return;
end
 
k_win = ((optimal - overlap)/(length(win_seg) - overlap));                  % Anzahl der zu bearbeitenden Segmente feststellen
H = zeros(nfftx,1);                                                         %#ok<NASGU> % Ergebnismatrix--> k Segmente der Länge nfft transformieren
H_pos0 = zeros(length(0:(nfftx/2)),k_win);
m = 1;                                                                      % Indexstartwert für die einzelnen Segmente

%% Erste FFT mit Fensterung

c1 = (nfftx/2)+1;                                                           % Zwischenspeichern der Grenzweite bis zur Nyquistfrequenz

ii = 1;
signal_win = sig_neu(m:nfftx+m-1) .* win_seg*nfftx/sum(win_seg);            % entnehme aus Signal das Segment der Länge nfft und multipliziere mit dem Fenster
H          = fft(signal_win, nfftx)/nfftx;                                  % Segment transformieren
H_pos0(1:c1,ii) = abs(H(1:c1));                                             % Nur positives Frequenzen werden benötigt

H_pos0(2:(nfftx/2),ii) = 2 * H_pos0(2:(nfftx/2),ii);                        % Normierung
m = m + nfftx - overlap;                                                    % Indexstartwert für nächstes Segement bestimmen  

%% Zweite FFT mit Fensterung
ii = 2;
signal_win      = sig_neu(m:nfftx+m-1) .* win_seg*nfftx/sum(win_seg);       % entnehme aus Signal das Segment der Länge nfft und multipliziere mit dem Fenster
H               = fft(signal_win, nfftx)/nfftx;                             % Segment transformieren
H_pos0(1:c1,ii) = abs(H(1:c1));                                             % Nur positives Frequenzen werden benötigt

H_pos0(2:(nfftx/2),ii) = 2 * H_pos0(2:(nfftx/2),ii);                        % Normierung
spec_peak(:,2)         = max(H_pos0(:,1), H_pos0(:,2));                     % max Werte in spec_peak 2.Spalte

m = m  +  nfftx - overlap;                                                  % Indexstartwert für nächstes Segement bestimmen  

%% For Schleife für die verbeleibenden Segmente
for ii=3:k_win
     
      signal_win      = sig_neu(m:nfftx+m-1) .* win_seg*nfftx/sum(win_seg); % entnehme aus Signal das Segment der Länge nfft und multipliziere mit dem Fenster
      H               = fft(signal_win, nfftx)/nfftx;                       % Segment transformieren
      H_pos0(1:c1,ii) = abs(H(1:c1));                                       %  aus H werden nur die Werte 1...257 = (nfftx/2) + 1 entnommen wenn nfftx = 512
     
      H_pos0(2:(nfftx/2),ii) = 2 * H_pos0(2:(nfftx/2),ii);                  % Normierung
       
      spec_peak(:,2)         = max(spec_peak(:,2), H_pos0(:,ii));           % bei jedem Schleifendurchlauf wird spec_peak upgedated                      
      m = m + nfftx - overlap;                                              % Indexstartwert für nächstes Segement bestimmen  
end

spec_peak(:,1) = abtastfreq/nfftx*(0:nfftx/2);                              % 1.Spalte von spec_peak ist Frequenzvektor

%% PEAK PLOT
% Auflösung des Spektrums
% f_peak = abtastfreq/nfftx*(0:nfftx/2);                                    % Frequenzvektor angepasst auf Fensterlänge

legendData = 'PEAK';

% semilogx(f_peak, 20*log10((spec_peak)/1e-06));

 


lg elcachon
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.