Verfasst am: 16.06.2014, 23:03
Titel: Anfängerksript zum Matrix auslesen und schreiben
Hallo,
ich brauche ein kleines Skript, das aus 3 verschiedenen Matrizen Schrittweise die Daten ausliest und in einer Formel verarbeitet. Die Ausgegebenen Werte sollen geplottet werden.
Die Matrizen heißen "S13", "S14" und "S15". Sie besitzen jeweils 13001 Zeilen und 4117 Spalten.
In dem Skript sollen nun die Werte aus Spalte i, Zeile j aus S13, aus S14 und S15 gelesen werden. Also der Wert an der selben Position, jeder Matrix.
Aus den 3 ausgelesenen Werten, soll ein neuer Wert berechnet werden:
Wenn du weißt, wie groß deine Matrix sein wird spart es dir unheimlich viel Rechenzeit einfach eine null-Matrix dieser Größe zu definieren und diese dann innerhalb der Schleife zu befüllen.
Ich habe die Punktquadrierung (.^2) mal entfernt, da du in der Schleife immer einen expliziten Punkt in der Matrix ansteuerst. Operationen mit einem Punkt machen es leichter mit Matritzen zu arbeiten.
Entweder quadrierst du also vorher die gesamte Matrix mit S13 = S13.^2
oder du machst es in der Schleife ganz normal.
Hoffe, ich konnte dir damit das Skripten etwas näher führen.
Wenn du weißt, wie groß deine Matrix sein wird spart es dir unheimlich viel Rechenzeit einfach eine null-Matrix dieser Größe zu definieren und diese dann innerhalb der Schleife zu befüllen.
Das macht Sinn, dass das dann schneller geht. Danke!
Ich habe die Punktquadrierung (.^2) mal entfernt, da du in der Schleife immer einen expliziten Punkt in der Matrix ansteuerst. Operationen mit einem Punkt machen es leichter mit Matritzen zu arbeiten.
Entweder quadrierst du also vorher die gesamte Matrix mit S13 = S13.^2
oder du machst es in der Schleife ganz normal.
Achso, das heißt mit den Punkt-Operatoren kann ich komplette Matrizen bearbeiten? Oha, das habe ich nicht gewusst, danke. Dann passt das ja auch soweit.
Jetzt gehts ums Plotten. Aus der neu erstellten Matrix "v_res_i" sollen Spaltenweise Plots erstellt werden. Also Plot 1 mit allen Einträgen der Spalte 1. Nach erstellung des Plots, soll dieser als .eps und als .emf gespeichert werden. (Ich arbeite unter Ubuntu, mein Betreuer unter Windows. Daher für mich eps und für ihn .emf)
Gleiches natürlich für alle Spalten von 1 bis 4117.
ah der Vorschlag von Nras ist der beste Weg. Hab ich irgendwie nicht daran gedacht
Was den Plot angeht muss es anders gemacht werden.
Der plot-Funktion kannst du einen Vektor übergeben und diese werden dann auf der y-Achse über eine normierte x-Achse geplotet.
Sieht also wie folgt aus:
Code:
for i = 1:4117 % : steht für die gesamte Spalte bzw. Zeile plot(v_res_i(:,i));
vielen Dank für den Tip! Damit geht es wirklich viel schneller. Habe bisher immer nur geguckt, dass es "irgendwie" geht und wenig werd auf Eleganz und Effizienz gelegt. So hat das immer ein paar Minuten gedauert. Jetzt rauscht das in 3 Sekunden durch
Im Moment hab ich 13001 Samples. Die Samplingfrequenz beim Aufzeichnen Betrug 1/10000. In einer Spalte befinden sich also 1,3 Sekunden des fortlaufenden Signals. Statt der Samples sollen aber die Sekunden/ms auf der X-Achse stehen. Wie rechne ich die Samples in Sekunden um und skaliere die X-Achse entsprechend?
Welche Matlab Version benutzt du?
Als Alternative könntest du evtl. ein anderes Dateiformat versuchen, statt -dmeta
Oder dein Betreuer schafft sich mal Ghostscript oder EPS Viewer o.Ä. an
zu 2.
du hast im Grunde deine Lösung in deiner Frage geschrieben, ohne es zu merken
Die Messung verläuft mit einer Frequenz von 1/10.000
Also musst du nur einen Zeitvektor erstellen, der dein Messspektrum abdeckt.
z.B.:
Code:
% Messfrequenz f
f = 1/10000;
% Zeitvektor für die x-Achse % von 0 bis zur Länge der Matrix v_res_i (in Sekunden) in den Schritten f
zeit = 0 : f : length(v_res_i)*f;
Ich glaube da stimmt was mit der Reihenfolge nicht. xlim und xlabel sind klar, auch wo sie hingehören. Zum Plot. f ist eine Konstante und damit kann sie ja gleich zu Anfang geschrieben werden. zeit ist von v_res_i abhängig und sollte demnach danach kommen.
Kann es sein, dass die Matrix invertiert werden muss? Wenn er über die Länge des Vekotrs meckert? Oder liegt es daran, dass zeit hier 13002 Werte, also einen mehr als v_res_i hat. Er fängt bei 0 an. Also müsste Zeit bei 0 ++ beginnen?
Edit: Wenn ich manuell, eingreife und die erste Spalte des Vektors Zeit lösche, sodass dieser nur noch 13001 Werte aufweißt, klappt die Sache. Der Plot ist allerdings um 90° verdreht. Demnach muss zeit tatsächlich invertiert werden.
Kann es sein, dass die Matrix invertiert werden muss? Wenn er über die Länge des Vekotrs meckert? Oder liegt es daran, dass zeit hier 13002 Werte, also einen mehr als v_res_i hat. Er fängt bei 0 an. Also müsste Zeit bei 0 ++ beginnen?
Hoppla - du hast natürlich recht! Die Syntax lautet schließlich plot(x, y) also muss der Zeitvektor zuerst kommen.
Das mit der Länge des Vektors hast du auch richtig erkannt. Ich habs nicht mehr getestet, sondern hab es nur so heruntergeschrieben und das wieder übersehen.
Ich würde eher sagen nicht bei 0++ beginnen, sondern bei length(y) - 1 enden. Also..
Code:
zeit = 0 : f : (length(v_res_i)*f)-1;
% den Zeitvektor transponieren
zeit = zeit';
Ich glaube die -1 gehört hier vor das "mal" *. Damit klappt es dann. Ich bin mir allerdings nicht ganz sicher ob das so korrekt ist. Denn: Der Vektor soll ja nicht zwangsläufig bei 0 anfangen. Er soll mit dem ersten Wert beginnen. Mit der obigen Lösung wird ja der letzte Wert weg geschnitten, statt die Null am Anfang zu unterdrücken. Ich möchte nicht kleinlig sein... aber ich bin mir da nicht ganz sicher.
Weiterhin ist der Plot, oder vielmehr sein Inhalt um 90° verdreht. Die X-Achse stimmt, da wir ja die Beschriftung selbst festgelegt haben. Das kommt auf jeden Fall durch die Skalierung, die da in den Plot mit reingeschrieben wird. Ich denke das mit der Orientierung des Vektors noch etwas nicht stimmt.
% Zeitvektor für die x-Achse % von 0 bis zur Länge der Matrix v_res_i (in Sekunden) in den Schritten f
zeit = 0 : f : ((length(v_res_i)-1)*f);
zeit_vert = zeit';
% Vektoren der Geschwindigkeit, aufgeteilt auf die einzelnen Schlagfenster plotten
for i = 1:4117 plot(zeit_vert,v_res_i(:,i))
%xlim([01.5]);
xlabel('t [s]');
Entschuldige, du hast natürlich wieder Recht. Das -1 muss von der Länge abgezogen werden und dann mit der Frequenz aufmultipliziert werden und nicht so, wie ich es geschrieben habe.
Ich sollte wohl doch lieber vorher einen kleinen Test durchlaufen lassen, bevor ich meinen Vorschlag schreibe
Welches delta t du betrachtest ist ja dir überlassen. Ich habe es einfach bei 0 beginnen lassen, weil ich es normaler weise so kenne bei Messreihen.
An den Ergebnissen sollte das ja nichts ändern, da du nichts davon verrechnest, sondern einfach die bildliche Darstellung richtig gestalten möchtest.
Kein Problem, ich bin dir mehr als dankbar für deine Hilfe. Sonst wäre ich nie so weit gekommen, bzw. es wäre wesentlich mühseliger geworden. Habe die Geschichte oben noch mal editiert. Also den Punkt mit den vertauschten X- und Y-Achsen.
So es geht weiter, bin endlich wieder da und am Ball
Neue Aufgabe:
Ich habe 5 Matrizen. Jede Matrix ist 13001 (Zeilen) x 4117 (Spalten) groß.
Ich Muss aus Matrix 1 das Maximum der ersten Spalte suchen. Gleiches gilt für alle 5 Matrizen. Also immer das Maximum der ersten Spalte. Alle 5 Werte sollen dann in eine Datei geplottet werden. Danach gehts weiter mit der zweiten Spalte, der Dritten und so weiter...
Aber irgendwie klappt es nicht. Es kommen nur einzelne Plots mit Punkten, nicht mit einer Kurve heraus. Es soll eigentlich eine Abklingkurve sichtbar werden. In jedem Plot müssten ja 5 Punkte, also die 5 Maxima der 5 verschiedenen Matrizen in den jeweiligen Spalten vorhanden sein. Was raus kommt, ist aber sowas, wie im Anhang befindlich.
ich möchte ein paar kleine Verbesserungen vorschlagen
Der befehl hold on muss nur ein Mal aufgerufen werden. Dieser gilt für alle ausgeführten plots, bis du wieder hold off aufrufst.
Du musst es also nicht mehrfach innerhalb der Schleife aufrufen, sondern kannst es ein Mal außerhalb der Schleife aufrufen.
Die Punkte liegen alle auf 1, weil du keine x-Achse angibst. Da du für jeden einzelnen Punkt den Plot Befehl immer wieder aufrufst, betrachtet Matlab diese nicht als zusammengehörenden Vektor, sondern als einzelnen Punkt, bei denen du "zufällig" jeden fünften mit der gleichen Farbe versehst. Also werden die immer schön über der 1 aufgetragen.
Mein Vorschlag wäre die Maxima immer in einen Zwischenvektor zu packen, so dass du am Ende wirklich einen Vektor hast. Wenn du den dann plottest, wird ihm eine normierte x-Achse zugewiesen und alles sollte fein sein.
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.