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

Funktionsvektorisierung (inkl. logische Operationen)-GELÖST

 

gurke111
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.01.09
Wohnort: http://gehrcke.de
Version: ---
     Beitrag Verfasst am: 13.01.2009, 17:47     Titel: Funktionsvektorisierung (inkl. logische Operationen)-GELÖST
  Antworten mit Zitat      
Hallo! Mein erster Beitrag hier; ich hoffe er entspricht gewissen Normen Smile

Kommen wir auch gleich zu meinem Problem: Ich habe eine Funktion function tri = triangle_periodic(t) geschrieben, die einen Parameter t übergeben bekommt und den Wert tri zurückgibt, wobei folgendes der entscheidende Funktionsinhalt ist:

Code:

    t = mod(t,1);
    if (0 <= t) && (t < 1/4)
        tri = 4*t;
    elseif (1/4 <= t) && (t < 3/4)
        tri = 2 - 4*t;
    else
        tri = 4*t - 4;
    end
 


Innerhalb der Funktion wird der Rückgabewert also u.a. mithilfe von logischen Ausdrücken berechnet.

Nun würde ich der Funktion gerne einen Vektor mit mehreren t-Werten übergeben können, sodass diese einen Vektor zurückgibt, dessen Komponenten den tri-Ergebnissen zu den einzelnen t-Werten entsprechen. Unkompliziert ausgedrückt: Eigentlich möchte ich das selbe Verhalten erzielen, wie sich z.B. die sin()-Funktion verhält:
Code:

t_vector = 0:1/1000:2;
result_vector = sin(t_vector);
 


Ich muss die Funktion also nun verändern/vektorisieren; weiß aber nicht wie, weil mich die logischen Ausdrücke dabei ungemein stören Smile

Auf eine for-Schleife sollte ich aus Performancegründen wohl verzichten, denn ich habe später vor, recht große t-Vektoren zu übergeben.

Die Frage ist also: Wie vektorisiere ich diese Funktion? Ich hoffe, dass ich nur etwas übersehe und die Lösung eigentlich ganz einfach ist..

Vielen Dank für Eure Hilfe im Voraus!

Zuletzt bearbeitet von gurke111 am 14.01.2009, 16:27, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen


gurke111
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.01.09
Wohnort: http://gehrcke.de
Version: ---
     Beitrag Verfasst am: 14.01.2009, 16:24     Titel:
  Antworten mit Zitat      
Ich habe meine eigene Denkmaschine nochmal angeschmissen und folgende Lösung erarbeitet:

Nochmals gepasted hier (dort sieht es vll schöner aus..):
http://paste.pocoo.org/show/wmpwoL0LlE7hvf4tJJDH/

Code:

function triangle_vec = triangle_periodic(t_vec)
    % PERIODIC TRIANGLE FUNCTION
    % first period:
    % zero for t = 0; 1 for t = 1/4; -1 for t = 3/4; 0 for t = 1
    % and so on... Smile
    % by Jan-Philip Gehrcke, v 0.2
    %
    % How it works:
    % At first the input timestamps are mapped to the first period using
    % modulo function. Then the several timestamps are assorted in three
    % bins: I) the first quarter of the period; II) the second and the
    % third quarter of the period; III) the fourth quarter.
    % For each bin there is a linear transformation between timestamp and
    % triangle value:
    % first bin: if (0 <= t) && (t < 1/4) => tri = 4*t
    % second bin: if (1/4 <= t) && (t < 3/4) => tri = 2 - 4*t
    % third bin: tri = 4*t - 4
    %
    % By applying logical operations on the timestamp-vector and combining
    % these with the mentioned linear transformations, the resulting
    % triangle-value vector is built up.
    %
    % changelog:
    % 0.2:
    %   completely rewritten (vectorized)
    % 0.1:
    %   first version (using for-loop)
    %
    % This function is released to the public domain; any use is allowed.
   
   
    % build in periodicity (project t value on interval [0,1[
    t_vec = mod(t_vec,1);
    % determine size of vector with input values
    t_vec_size = size(t_vec);
    % build zero- and one-  vectors for logical operations
    the_zeros = zeros(t_vec_size);
    the_ones = ones(t_vec_size);

    % build binary vector for first quarter period of triangle function
    % (consisting of zeros and ones), describing the affiliation of input
    % values to the first quarter of the period (1 yes, 0 no)
    firstquartofperiod_binary_vec = (the_zeros <= t_vec) & (t_vec < the_ones*1/4);

    % t-values within the first period must be multiplied with 4 (tri = 4*t).
    % Keep the rest of values unchanged. So the binary vector must be mapped in
    % the following way:
    % 1->4; 0->1. This is done by y=3x+1.
    % After this, t_vec will be multiplied with this vector containing 1 and 4.
    % This results is a vector containing triangle and time values mixed!
    triangle_t_mixed_vec =  t_vec .* (3 * firstquartofperiod_binary_vec + 1);

    % build binary vector for second/third quarter period of triangle function
    secondthirdquartofperiod_binary_vec = (the_ones*1/4 <= t_vec) & (t_vec < the_ones*3/4);

    % t-values within the second/third quarter period must be mapped like this: tri = 2 - 4*t;
    % So the binary vector has to be mapped twice:
    % I)1->-4; 0->1 (y=-5x+1) and
    % II) 0->0; 1->2 (y=2x)
    triangle_t_mixed_vec =  triangle_t_mixed_vec  .* (-5 * secondthirdquartofperiod_binary_vec + 1) + secondthirdquartofperiod_binary_vec * 2;

    % build binary vector for fourth quarter period of triangle function
    % this is done by the negative or() connection between both existing binary
    % vectors.
    fourthquartofperiod_binary_vec = ~or(firstquartofperiod_binary_vec,secondthirdquartofperiod_binary_vec);

    % t-values within the fourth quarter period must be mapped like this: tri = 4*t - 4;;
    % So map the binary vector two times again: 1 -> 4; 0 -> 1
    % I)1->4; 0->1 (y=3x+1) and
    % II) 0->0; 1->-4(y=-4x)
    triangle_vec =  triangle_t_mixed_vec  .* (3 * fourthquartofperiod_binary_vec + 1) + fourthquartofperiod_binary_vec * -4;
 


Diese Funktion nimmt Vektoren entgegen und verarbeitet diese (nur mithilfe von Vektoroperationen), sodass am Ende auch ein Ergebnisvektor dabei herauskommt.

Die Funktion aus meinem ersten Post habe ich um eine for-Schleife erweitert, sodass sie bei selbem Input das selbe Ergebnis erzeugt, wie meine vektorisierte Funktion:

Code:

function triangle_vec = triangle_periodic(t_vec)
    t_vec = mod(t_vec,1);
    triangle_vec = [];
    n = length(t_vec);

    for m = 1:n
        t = t_vec(m);
        if (0 <= t) && (t < 1/4)
            triangle_vec(m) = 4*t;
        elseif (1/4 <= t) && (t < 3/4)
            triangle_vec(m) = 2 - 4*t;
        else
            triangle_vec(m) = 4*t - 4;
        end    
    end
 


Die Profiler-Ergebnisse...
...sind überzeugend! Für einen 100000 Elemente großen t_vec ist die vektorisierte Funktion ca. 1900 mal schneller; für einen 200000 Elemente großen Vektor ist sie sogar schon 5000 mal schneller! Es gibt also einerseits einen riesigen Geschwindigkeitsunterschied ansich und zusätzlich noch ein stark verschiedenes Skalierungsverhalten für größer werdenden Input.
Private Nachricht senden Benutzer-Profile anzeigen
 
gurke111
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.01.09
Wohnort: http://gehrcke.de
Version: ---
     Beitrag Verfasst am: 14.01.2009, 17:19     Titel:
  Antworten mit Zitat      
Die Profiler-Ergebnisse oben sind unfair gegenüber der for-Schleife. Wie sich unschwer erkennen lässt, kann ich durch ändern dieser Stelle die Performance der for-Schleife erhöhen:
Code:
triangle_vec = [];


Hier weiß ich ja bereits, wie groß triangle_vec werden wird:

Code:

n = length(t_vec);
triangle_vec = zeros(1,length);
 


Die oben genannten Ergebnisse ändern sich dadurch drastisch. Die Warnung blabla might be growing inside a loop. Consider preallocating for speed hat starke Berechtigung:

t_vec mit 1.000.000 Elementen:
Die vektorisierte Funktion ist 4.68 mal so schnell wie die for-Methode

t_vec mit 2.000.000 Elementen:
Die vektorisierte Funktion ist 5.08 mal so schnell wie die for-Methode

t_vec mit 4.000.000 Elementen:
Die vektorisierte Funktion ist 5.17 mal so schnell wie die for-Methode

Die Skalierung bei größerem Input ist also gar nicht so verschieden zwischen for-Methode und vektorisierter Funktion.

Ein Geschwindigkeitsgewinn um den Faktor 5 spricht dennoch deutlich für die vektorisierte Funktion.
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 - 2024 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.