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

Optimierung

 

Andfirst1

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 21.03.2009, 12:35     Titel: Optimierung
  Antworten mit Zitat      
Hallo,

Habe leider ein nicht ganz unerhebliches Gechwindigkeitsproblem bei den drei nachfolgenden functions. Diese laufen zwar für sich alleine mit kleinen Matrizen recht schnell, sollten aber in meinem Hauptprogramm schneller laufen, dieses würde momentan leider mehrere Tage rechnen. Wenn jemandem was auffällt wie ich bei den beiden for schleifen im oberen Teil noch Geschwindigkeit gewinnen kann, wärs super. Cool

Danke im vorraus Cool

Code:
function [erg_matrix] = footrot(alpha, ausschnitt,mask,off_zeil,off_spalt,arcsec)

% Funktion footrot, dreht eine Matrix erg_matrix der selben Gr??e wie mask um alpha.
% Es entstehen Koordinaten im Koordinatensystem der Matrix ausschnitt. Gedreht wird
% um den Mittelpunkt des mittleren Pixels von Ausschnitt und dem Mittelpunkt der erg_matrix Die
% Werte der Matrix erg_matrix entstehen durch eine bilineare interpolation
% auf Basis der umliegenden Pixel in ausschnitt. Zur Interpolation werden
% die Koordinaten auf das links oben liegende Pixel abgerundet und davon
% ausgehend alle weiteren Pixel bestimmt. off_zeil und off_sp verschiebt
% die endgueltigen Koordinaten um den Abstand des Ice_Sat Punktes vom Mittelpunkt des Pixels.
% Denn dieser f?llt nicht genau auf Mittelpunkt des Pixels.
% Dies ist notwendig um eine korrekte Interpolation mit subpixel Genauigkeit zu gewaehrleisten.
% F?r Ausschnitt sind nur Matrizen mask mit ungerader Spalten und Zeilen zahl
% zugelassen.
% Die bilineare interpolation wird nicht durchgef?hrt sobald einer der vier
% betroffenen Werte 999999 ist

alpha = alpha * pi /180;

[iline,isamp] = size(ausschnitt);

[mline,msamp] = size(mask);
% osamp = round(abs(isamp * cos(alpha*pi)) + abs(iline * sin(alpha*pi)))
% oline = round(abs(isamp * sin(alpha*pi)) + abs(iline * cos(alpha*pi)))
% osamp = round(abs(msamp * cos(alpha)) + abs(mline * sin(alpha)))
% oline = round(abs(msamp * sin(alpha)) + abs(mline * cos(alpha)))

osamp = msamp;
oline = mline;

[li,co] = size(ausschnitt);
ausschnitt2 = ausschnitt';
ibuf = ausschnitt2(1:(li*co));

for i = 1 : oline;
    y0 = i - oline/2 -0.5;
    for j = 1 : osamp;
        x0 = j - osamp/2 -0.5;
       
        x1 =  (x0 * cos(alpha) + y0 * sin(alpha)) * (0.1/arcsec) + isamp/2+0.5; % Ausschnitt
        y1 = (-x0 * sin(alpha) + y0 * cos(alpha)) * (0.1/arcsec) + iline/2+0.5;


        d = calculate_ivalue(x1,y1,ibuf,isamp,iline,off_zeil,off_spalt);


        erg_matrix(i,j) = d;
    end
end
% Drehpunkt ist Mittelpunkt des mittleren Pixels des Ausschnitts!!!



Code:
function [value] = calculate_ivalue(x1,y1,ibuf,isamp,iline,off_zeil,off_spalt)

% [li,co] = size(ausschnitt);
% ausschnitt2 = ausschnitt';
% ibuf = ausschnitt2(1:(li*co));

% Koordinaten, um die herum interpoliert wird, werden um den Abstand vom
% Mittelpunkt des Pixels verschoben. --> Interpolation an korrekter Stelle
% abh?ngig vom Abstand zum Drehmittelpunkt.
x1 = x1 + off_spalt;
y1 = y1 + off_zeil;


% x_0 y_0 linkes oberes eck der Interpolation
x_0 = floor(x1);
y_0 = floor(y1);

% Matrixpositionen ausschliessen!!!!!!!!!!!!!!!!!!!!

% !!!!!!! x_0 = 0!!!!!!!!!!!

% if x_0 >= 0 && x_0 < isamp && y_0 >=0 && y_0<iline;
  if x_0 >= 0 && x_0 <= isamp && y_0 >0 && y_0<=iline;

   % k = x_0+y_0*isamp %%% zeilen die ?bersprungen weren + position in der zeile
   
   k = x_0+(y_0-1)*isamp; % ????????? weiter gehts

   
   v(1) = ibuf(k);


   % if x_0 < isamp-1;
   if x_0 < isamp & x_0 > 0;
       v(2) = ibuf(k+1);
   else
       v(2) = v(1); % Randbehandlung: Pixel ausserhalb selber Wert wie Randpixel
   end
   
   %if y_0<iline-1
   if y_0 < iline & y_0 > 0;
       v(3) = ibuf(k+isamp);
       %if x_0<isamp-1;
       if x_0<isamp & x_0 > 0;
           v(4) = ibuf(k+isamp+1);
       else
           v(4) = v(3);
       end
   else
       v(3) = v(1);
       v(4) = v(2);
   end
 else
      disp('Ausschnitt zu klein!')
 end

dx = x1 - x_0; %- 0.5;   %%% Distance to v0 pixel center  warum 0.5?????
dy = y1 - y_0; %- 0.5;

% billineare interpolation
value = calc_bi (v,dx,dy);



Code:
function wert = calc_bi(v,dx,dy)
% faengt ab, dass sobald einer der vier Werte = 999999 ist, wird der Wert
% verworfen

if v(1) == 999999 | v(2) == 999999 | v(3) == 999999 | v(4) == 999999;
    wert = 999999;
else
if dx < 0.0;
    if dy < 0.0;
        d0 = dx * dy;
        d1 = (1+dx)*abs(dy);
        d2 = abs(dx)*(1+dy);
        d3 = (1+dx)*(1+dy);
    else
        d0 =  abs(dx)*(1.0-dy);
        d1 = (1.0+dx)*(1.0-dy);
        d2 =  abs(dx)*     dy;
        d3 = (1.0+dx)*     dy;
    end
else
    if dy < 0;
        d0 = (1.0-dx)* abs(dy);
        d1 =      dx * abs(dy);
        d2 = (1.0-dx)*(1.0+dy);
        d3 =      dx *(1.0+dy);
    else
        d0 = (1.0-dx)*(1.0-dy);
        d1 =      dx *(1.0-dy);
        d2 = (1.0-dx)*     dy;
       
        d3 =      dx *     dy;
    end
end
wert = v(1)*d0 + v(2)*d1 + v(3)*d2 + v(4)*d3;
end


Edit by Bijick: Code-Umgebung ergänzt. Bitte in Zukunft selbst dran denken (Code-Button mittig über dem Eingabefeld)! Danke Smile


Bijick
Ehrenmitglied

Ehrenmitglied



Beiträge: 914
Anmeldedatum: 18.06.07
Wohnort: Nürnberg
Version: R2006b, R2008b
     Beitrag Verfasst am: 21.03.2009, 15:16     Titel:
  Antworten mit Zitat      
Hallo Andfirst1,

da lässt sich einiges verbessern. Bitte stell uns doch noch Testwerte für

Code:
footrot(alpha, ausschnitt,mask,off_zeil,off_spalt,arcsec)


zur Verfügung, damit wir den Code auch ausführen können.

Herzliche Grüße
Bijick
_________________

>> why
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Andfirst1

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 21.03.2009, 19:01     Titel:
  Antworten mit Zitat      
Code:
alpha = 30

Code:
arcsec = 1

Code:
off_zeile = 0.2

Code:
off_spalte = 0.2


zu Testzwecke habe ich für ausschnitt eine Random Matrix mit 1000x1000 gewählt

Code:


und für mask
Code:



Das wird nicht unbedingt "langsam" sein beim ausführen.

Nur wird das ganze für 20000 Kacheln auf der Erde ausgeführt und pro Kachel ein paar Hundert Mal. Cool
 
Bijick
Ehrenmitglied

Ehrenmitglied



Beiträge: 914
Anmeldedatum: 18.06.07
Wohnort: Nürnberg
Version: R2006b, R2008b
     Beitrag Verfasst am: 24.03.2009, 14:29     Titel:
  Antworten mit Zitat      
Hallo Andfirst1,

das hat etwas länger gedauert. Aber es gibt doch eine deutliche Verbesserung. Mit diesem Code

Code:
alpha = 30;
arcsec = 1;
off_zeile = 0.2;
off_spalte = 0.2;
ausschnitt = rand(1000);
mask = zeros(500);

tic
erg_matrix_alt = footrot_alt(alpha,ausschnitt,mask,off_zeile,off_spalte,arcsec);
toc

tic
erg_matrix = footrot_neu(alpha,ausschnitt,mask,off_zeile,off_spalte,arcsec);
toc

Fehler = max(erg_matrix(:)-erg_matrix_alt(:))


bekomme ich das Ergebnis

Zitat:
Elapsed time is 10.670177 seconds.
Elapsed time is 1.720947 seconds.

Fehler =

0


Die neuen Dateien habe ich angehängt.

Herzliche Grüße
Bijick

alles_neu.m
 Beschreibung:

Download
 Dateiname:  alles_neu.m
 Dateigröße:  3.11 KB
 Heruntergeladen:  620 mal

_________________

>> why
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Andfirst1

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.03.2009, 23:31     Titel:
  Antworten mit Zitat      
Wow, jetz bin ich wirklich platt, vielen, vielen Dank Cool

Bloss noch für mich zu Erklärung: Was genau sind logische Indizes? Damit hab ich noch nie gearbeitet und sind mir auch noch nie aufgefallen. Wo kann man das ein bischen detaillierte nachlesen?

Der Vollständigkeit halber noch ein Code zum gleichen Problem, der etwa 2 Sekunden schneller geht als der alt, den ich am Wochenende gebastelt habe Cool

Danke nochmal



Code:
function [erg_matrix] = footrot3(alpha, ausschnitt,mask,off_zeil,off_spalt,arcsec)

% Funktion footrot, dreht eine Matrix erg_matrix der selben Gr??e wie mask um alpha.
% Es entstehen Koordinaten im Koordinatensystem der Matrix ausschnitt. Gedreht wird
% um den Mittelpunkt des mittleren Pixels von Ausschnitt und dem Mittelpunkt der erg_matrix Die
% Werte der Matrix erg_matrix entstehen durch eine bilineare interpolation
% auf Basis der umliegenden Pixel in ausschnitt. Zur Interpolation werden
% die Koordinaten auf das links oben liegende Pixel abgerundet und davon
% ausgehend alle weiteren Pixel bestimmt. off_zeil und off_sp verschiebt
% die endgueltigen Koordinaten um den Abstand des Ice_Sat Punktes vom Mittelpunkt des Pixels.
% Denn dieser f?llt nicht genau auf Mittelpunkt des Pixels.
% Dies ist notwendig um eine korrekte Interpolation mit subpixel Genauigkeit zu gewaehrleisten.
% F?r Ausschnitt sind nur Matrizen mask mit ungerader Spalten und Zeilen zahl
% zugelassen.
% Die bilineare interpolation wird nicht durchgef?hrt sobald einer der vier
% betroffenen Werte 999999 ist

alpha = alpha * pi /180;

[iline,isamp] = size(ausschnitt);

[mline,msamp] = size(mask);
% osamp = round(abs(isamp * cos(alpha*pi)) + abs(iline * sin(alpha*pi)))
% oline = round(abs(isamp * sin(alpha*pi)) + abs(iline * cos(alpha*pi)))
% osamp = round(abs(msamp * cos(alpha)) + abs(mline * sin(alpha)))
% oline = round(abs(msamp * sin(alpha)) + abs(mline * cos(alpha)))

osamp = msamp;
oline = mline;


ausschnitt2 = zeros(iline,isamp);
ausschnitt2 = ausschnitt';
ibuf = ausschnitt2(1:(iline*isamp));


erg_matrix = zeros(oline,osamp);
dhelp = zeros(osamp*oline,1);
y0 = 0;
x0 = 0;

for neu = 0 : oline* osamp-1;
   
        y0 = mod(neu,oline)+1 - oline/2 -0.5;
        x0 = floor(neu/oline)+1 - osamp/2 -0.5;
       
        x1 =  off_spalt+(x0 * cos(alpha) + y0 * sin(alpha)) * (0.1/arcsec) + isamp/2+0.5; % Ausschnitt
        y1 = off_zeil+(-x0 * sin(alpha) + y0 * cos(alpha)) * (0.1/arcsec) + iline/2+0.5;


        dhelp(neu+1) = calculate_ivalue(x1,y1,ibuf,isamp,iline);

end

erg_matrix = reshape(dhelp,oline,osamp);

% Drehpunkt ist Mittelpunkt des mittleren Pixels des Ausschnitts!!!!!!!


function [value] = calculate_ivalue(x1,y1,ibuf,isamp,iline)

% [li,co] = size(ausschnitt);
% ausschnitt2 = ausschnitt';
% ibuf = ausschnitt2(1:(li*co));


% Koordinaten, um die herum interpoliert wird, werden um den Abstand vom
% Mittelpunkt des Pixels verschoben. --> Interpolation an korrekter Stelle
% abh?ngig vom Abstand zum Drehmittelpunkt.
%y1 = y1 + off_zeil;
%x1 = x1 + off_spalt;


% % x_0 y_0 linkes oberes eck der Interpolation
x_0 = floor(x1);
y_0 = floor(y1);

% Matrixpositionen ausschliessen!!!!!!!!!!!!!!!!!!!!

% !!!!!!! x_0 = 0!!!!!!!!!!!

% if x_0 >= 0 && x_0 < isamp && y_0 >=0 && y_0<iline;
  if x_0 >= 0 && x_0 <= isamp && y_0 >0 && y_0<=iline;

   % k = x_0+y_0*isamp %%% zeilen die ?bersprungen weren + position in der zeile
   
   k = x_0+(y_0-1)*isamp; % ????????? weiter gehts

   
   v(1) = ibuf(k);


   % if x_0 < isamp-1;
   if x_0 < isamp && x_0 > 0;
       v(2) = ibuf(k+1);
   else
       v(2) = v(1); % Randbehandlung: Pixel ausserhalb selber Wert wie Randpixel
   end
   
   %if y_0<iline-1
   if y_0 < iline && y_0 > 0;
       v(3) = ibuf(k+isamp);
       %if x_0<isamp-1;
       if x_0<isamp && x_0 > 0;
           v(4) = ibuf(k+isamp+1);
       else
           v(4) = v(3);
       end
   else
       v(3) = v(1);
       v(4) = v(2);
   end
 else
      disp('Ausschnitt zu klein!')
 end

dx = x1 - x_0; %- 0.5;   %%% Distance to v0 pixel center  warum 0.5?????
dy = y1 - y_0; %- 0.5;


% billineare interpolation
value = calc_bi (v,dx,dy);



function wert = calc_bi(v,dx,dy)
% faengt ab, dass sobald einer der vier Werte = 999999 ist, wird der Wert
% verworfen

if v(1) == 999999 ||  v(2) == 999999 || v(3) == 999999 || v(4) == 999999;
    wert = 999999;
else
if dx < 0.0;
    if dy < 0.0;
        d0 = dx * dy;
        d1 = (1+dx)*abs(dy);
        d2 = abs(dx)*(1+dy);
        d3 = (1+dx)*(1+dy);
    else
        d0 =  abs(dx)*(1.0-dy);
        d1 = (1.0+dx)*(1.0-dy);
        d2 =  abs(dx)*     dy;
        d3 = (1.0+dx)*     dy;
    end
else
    if dy < 0;
        d0 = (1.0-dx)* abs(dy);
        d1 =      dx * abs(dy);
        d2 = (1.0-dx)*(1.0+dy);
        d3 =      dx *(1.0+dy);
    else
        d0 = (1.0-dx)*(1.0-dy);
        d1 =      dx *(1.0-dy);
        d2 = (1.0-dx)*     dy;
       
        d3 =      dx *     dy;
    end
end
wert = v(1)*d0 + v(2)*d1 + v(3)*d2 + v(4)*d3;
end

 
 
Bijick
Ehrenmitglied

Ehrenmitglied



Beiträge: 914
Anmeldedatum: 18.06.07
Wohnort: Nürnberg
Version: R2006b, R2008b
     Beitrag Verfasst am: 25.03.2009, 12:15     Titel:
  Antworten mit Zitat      
Hallo Andfirst1,

vielleicht ist dies Video von Doug Hull etwas für dich, oder dieser Text von Steve Eddins und Loren Shure. Oder Du suchst mal im Forum nach "logische Indizierung" oder "logical indexing".

Herzliche Grüße
Bijick
_________________

>> why
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Andfirst1

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.03.2009, 14:34     Titel:
  Antworten mit Zitat      
Hi bijick,

Hab jetzt noch ausgiebig getestet. Leider haut das mit dem Fehler = 0 nicht hin bei mir. Lass mal in dem von dir zitierten Beispiel das max() weg, dann bekommst du einen Vektor, der negative Fehler beinhaltet. Der maximale davon is 0. Leider hab ich noch nicht rausgefunden wo der Fehler liegt, hast du da noch ne Ahnung, wos ein Problem geben könnte?

Danke trotzdem

ciao
Andfirst1
 
Bijick
Ehrenmitglied

Ehrenmitglied



Beiträge: 914
Anmeldedatum: 18.06.07
Wohnort: Nürnberg
Version: R2006b, R2008b
     Beitrag Verfasst am: 30.03.2009, 15:06     Titel:
  Antworten mit Zitat      
Hallo Andfirst1,

das ist natürlich peinlich. Korrekterweise hätte ich mit

Code:
Fehler = max(abs(erg_matrix(:)-erg_matrix_alt(:)))


testen müssen. Ich schaue es mir noch mal an.

Herzliche Grüße
Bijick
_________________

>> why
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
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.