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

Konstante Y-Werte erzeugen- Interpolation?

 

petra24
Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 24.08.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.03.2013, 16:05     Titel: Konstante Y-Werte erzeugen- Interpolation?
  Antworten mit Zitat      
Hallo zusammen,
ich habe einen Spaltenvektor der die x-Werte darstellt. Dieser beginnt bei -49,8 hat eine Schrittweite von 0.6 und endet bei 42.
Dazu sind in einer Matrix jeweils spaltenweise für Bauteile die entsprechenden Y-Werte gemessen worden. (Zum Beispiel: Vorgabe x ist die Spannung und y werte stellen den strom dar.)

Jetzt will ich die Spannungen der einzelnen Bauteile addieren (Reihenschaltung). Dazu brauche ich aber konstante Stromwerte. Momentan mach ich es mit dem Befehl interp1. Dies ist aber sehr langsam- benötige für die 7000 Spalten bzw. Bauteile ca. 20s.

Hat jemand eine Idee wie dies schneller gehen könnte?

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


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 25.03.2013, 22:23     Titel:
  Antworten mit Zitat      
Hallo,

ich verstehe die Frage nicht. Vielleicht ist es einfacher, wenn du deinen bisherigen Code postest anstatt zu beschreiben, was du da machst.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
petra24
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 24.08.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 26.03.2013, 09:36     Titel:
  Antworten mit Zitat      
Ok, ist glaub ich dann echt leichter verständlich. z(2) stellt dabei die Anzahl der Spalten von IVCurves.Current also die Bauteile dar. Jede Reihe wird interpoliert, so dass man konstante Stromwerte bekommt und die Spannung für die Reihenschaltung addiert werden kann. IVCurves.Voltage ist dabei lediglich ein Vektor, da bei der Messung für die vorgegebenen Spannungswerte die Stromwerte gemessen worden sind.

Code:
for j=1:1:z(2);
        %% Interpolation auf konstante I Werte fuer Reihenschaltung
            x=IVCurves.Current(:,j);
            y=IVCurves.Voltage(:,1);

           n=0:delta:(ceil(max((1/delta)*max(IVCurves.Current(:,:)))))...
            /(1/delta);
            xx=n;

            yy=interp1(x,y,xx);
            IVCurvesInt.Voltage(:,j)=yy;
            IVCurvesInt.Current(:,j)=xx;

        end

Ich hoffe jetzt ist es verständlicher....

Viele Grüße
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 26.03.2013, 11:07     Titel:
  Antworten mit Zitat      
Hallo,

zunächst Verständnisfragen:
muss es nicht
Code:
y=IVCurves.Voltage(:,j);

heißen?

Ist es sinnvoll, n bzw. xx in der Schleife jedes Mal neu zu definieren? Bei einer Interpolation sollte es zwar kein neues Maximum oder Minimum geben, aber übersichtlicher ist es wohl, wenn du das einmalig außerhalb der Schleife definierst.

Hinsichtlich Geschwindigkeit habe ich Zweifel, ob man viel herausholen kann. Da würden Testdaten helfen.

Grüße,
Harald
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: 26.03.2013, 11:37     Titel:
  Antworten mit Zitat      
Hallo petra24,

Ein Vorschlag:
Code:
y=IVCurves.Voltage(:,1);  % Hängt nicht vom Schleifenzähler ab
% Division by delta moved out of MAX():
tmp = ceil(max(max(IVCurves.Current(:,:))) / delta) * delta;
xx = 0:delta:tmp;
IVCurvesInt.Voltage = zeros(length(xx), z(2));  % Pre-allocate!!!
IVCurvesInt.Current(:,k) = repmat(xx.', 1, z(2));
       
for k = 1:z(2)
   % Interpolation auf konstante I Werte fuer Reihenschaltung
   IVCurvesInt.Voltage(:,k) = interp1(IVCurves.Current(:,k), y, xx);
end

Ich habe einfach die Zeilen umsortiert: Alles, was nich vom Schleifenzähler abhängt, habe ich vor die Schleife gezogen. Die Ausgabe in "Voltage" habe ich per Pre-allocation in einem Stück reserviert. Ich kann es gerade nicht ausprobieren, aber ich vermute, es ist mekrbar schneller.

Allerdings ist Matlab's INTERP1 nicht sehr effizient. Eine angepasste Version könnte einiges mehr an Geschwindigkeit bieten. Ich werde demnächst eine Lineare Interpolation als C-Mex im FileExchange veröffentlichen, da das aktuelle http://www.mathworks.com/matlabcent.....eexchange/25463-scaletime das zwar prinzipiell auch löst, aber es wären noch Vorarbeiten mit HISTC nötig.

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 24.08.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 26.03.2013, 14:28     Titel:
  Antworten mit Zitat      
Hallo zusammen;
@Harald: Die Spannung wird vorgegeben und ist deshalb auch bei jedem Bauteil gleich. Deshalb auch nur ein Vektor.

Das n bzw. xx habe ich bei meinem kompletten Code schon in einem anderen Programmteil gemacht und wird deshalb auch nicht bei jeder Interpolation neu gemacht. Habe ich versehentlich falsch kopiert- Entschuldigung.

Ich glaube Hauptproblem ist die Funktion interp1. Diese ist an sich schon sehr langsam. Deshalb meine Frage ob ihr eine Idee hättet wie ich diese Funktion umgehen könnte? Habe es mit Scaletime und interp1q schon probiert- aber da ist eine Sortierung notwendig... vllt probier ich es doch mal auf diese variante

@Jan:Danke für den Vorschlag- ich probiers gleich mal so aus und gebe Rückmeldung. Werde auch die Variante mit histc testen.

Vielen Dank schonmal
Lg
Private Nachricht senden Benutzer-Profile anzeigen
 
petra24
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 24.08.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 26.03.2013, 15:18     Titel:
  Antworten mit Zitat      
Hey,
also durch die Umstellung ist der Code insgesamt um 0.8 s schneller. Braucht aber immernoch fast 10 s. Da ich eine riesenmaße solcher Datensätze habe- reicht dies leider immernoch nicht aus.

Will deshalb die Variante mit ScaleTime und histc versuchen. Bin aber noch ziemlich planlos wie dies funktionieren könnte. Wie muss ich histc verwenden damit dies richtig klappt?

VG, Petra
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 26.03.2013, 15:52     Titel:
  Antworten mit Zitat      
Hallo,

Verbesserung ist immer schön, wird aber irgendwann auf Grenzen stoßen. Gegebenenfalls sollte man auch Möglichkeiten wie Parallel Computing in Betracht ziehen.

Wieviele Dateien analysierst du momentan, und wie lange dauert das? Hast du mal den Profiler verwendet, um die Laufzeit zu analysieren? Ein beträchtlicher Teil der Zeit geht oft für das Einlesen der Daten und das Speichern der Ergebnisse drauf.

Wieviele solcher Dateien hast du denn?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
petra24
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 24.08.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 26.03.2013, 16:10     Titel:
  Antworten mit Zitat      
ich weiß, dass irgendwann schluss ist. aber es gibt eben die funktion scaletime, mit der würde ich es gerne noch ausprobieren.

Es handelt sich um messwerte für einen komplette monat. Momentan teste ich das ganze lediglich für eine Sekunde und benötige eben fast 10 s dafür. D.h. Um den Monat auszuwerten, benötige ich 10 Monate... mir ist bewusst dass ich mit parallel computing o.ä. arbeiten muss- aber trotzdem will ich den code vorher noch schneller bekommen. Ja schau mir die Zeiten mit dem Profiler an....die meiste zeit wird wirklich für interp1 benötigt....

VG, Petra
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: 26.03.2013, 17:32     Titel:
  Antworten mit Zitat      
Hallo petra24,

Code:
function Yi = myLinearInterpolate(X, Y, Xi)
[dummy, Bin] = histc(Xi, X);  %#ok<ASGLU>
H            = diff(X);       % Original step size

% Extra treatment if last element is on the boundary:
if Bin(length(Bin)) >= length(Y)
   Bin(length(Bin)) = length(Y) - 1;
end

Xj = Bin + (Xi - X(Bin)) ./ H(Bin);
Yi = ScaleTime(Y, Xj);

ScaleTime ist eigentlich also eine normale lineare Interpolation, bis auf die Einschränkung, dass X=1:length(Y) angenommen wird. Der obige Code konvertiert also nur die Original-X-Werte so, dass sie den Indices von Y entsprechen.

Viel Erfolg, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
petra24
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 24.08.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.03.2013, 12:03     Titel:
  Antworten mit Zitat      
Hallo Very Happy
habe den Quellcode mit HISTC probiert. Funktioniert aber leider nicht da der Abstand von den X bzw. Stromwerten unterschiedlich groß ist und auch nicht aufsteigend ist. Habe die Werte schon sortiert um das Problem mit der Sortierung zu lösen. Aber bei dem Problem mit dem unterschiedlichen Abstand weiß ich nicht weiter...
Hat diesbezüglich noch jemand einen Tip?

Viele Grüße
Petra
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.