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?
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);
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.
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.
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.
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?
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.
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....
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.
Hallo
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
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.