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

Vektorisierung der Berechnung eines Beugungsmusters

 

bligg
Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 15.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.10.2010, 11:01     Titel: Vektorisierung der Berechnung eines Beugungsmusters
  Antworten mit Zitat      
Hallo ihr,

ich möchte ein Beugungsbild ausrechnen, dazu muss ein Integral über die geometrische Projektion des beugenden Körpers gerechnet werden. Ich habe es jetzt näherungsweise einfach durch eine Summe ersetzt und schon teilweise vektorisiert. Diese Phi-Vektorisierung hat schon einen Faktor ~100 in der Rechenzeit gebracht.

Kann man die for-Schleife über die Theta auch noch vektorisieren oder irgendwie anders schneller machen?

Code:
   for iRay=1:100
        x = rand()*2-1;
        y = rand()*2-1;
       
        if x^2+y^2<=1
            max = max + 1;
       
            for iTheta=1:nTheta
                    [xObs,yObs,zObs] = sph2cart(thetaVal(iTheta),phiVal+pi/2,1);
                    D(:,iTheta) = D(:,iTheta) + exp(-1i*k*scale*[x y 0]*[xObs; yObs; zObs])';
            end
        end
    end


k, scale etc. sind Konstanten des Problems, in thetaVal und phiVal stehen die Raumrichtungen, unter denen die Beugungsfigur berechnet wird.

Im Moment rechne ich das für eine kreisförmige Blende/Kugel, später habe ich als Eingangsdaten nur die (x,y)-Koordinaten von Punkten, an denen ich den Körper "getroffen" habe, die also einen Beitrag leisten.

Würde mich über Anregungen oder andere Ideen freuen.

Liebe Grüße
bligg
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: 18.10.2010, 18:42     Titel: Re: Vektorisierung der Berechnung eines Beugungsmusters
  Antworten mit Zitat      
Hallo bligg,

Zitat:
Code:

            for iTheta=1:nTheta
                    [xObs,yObs,zObs] = sph2cart(thetaVal(iTheta),phiVal+pi/2,1);
                    D(:,iTheta) = D(:,iTheta) + exp(-1i*k*scale*[x y 0]*[xObs; yObs; zObs])';
            end
 

Schau Dir doch mal den Code von SPH2CART an:
Code:

z = r .* sin(elev);
x = r .* cos(elev) .* cos(az);
y = r .* cos(elev) .* sin(az);
 

Nun ist "r" bei Dir immer 1, und "elev" ist auch konstant, und damit auch der Z-Wert. Damit kannst Du die Berechnung auch deutlich vereinfachen. Ausserdem kannst Du SPH2CART auch gleich für einen ganzen Vektor ausrechnen lassen.

Es sieht so aus, als sei D pre-allociert, wohl mit ZEROS, oder?

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 15.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.10.2010, 10:13     Titel:
  Antworten mit Zitat      
Hallo Jan,

vielen Dank für deine Antwort!

Ich bin davon ausgegangen, dass sph2cart built-in sein würde, und deshalb gar nicht erst auf die Idee gekommen, mal in den Code zu schauen (obwohl natürlich klar ist, was dort passiert).
Insofern war deine Anregung mit den konstanten Werten, die ich jedes Mal auf's Neue ausrechne, natürlich absolut richtig.

Für's Protokoll und eventuell später drauf Stoßende, das Problem lässt sich mittels

Code:


auch komplett vektorisieren:

Code:
phiVal = 0:pi/180:pi;
thetaVal = 0:pi/20:2*pi;

nPhi = length(phiVal);
nTheta = length(thetaVal);

cartVal = zeros(nPhi,nTheta,3);

for iTheta = 1:nTheta
   for iPhi = 1:nPhi
      [xObs,yObs,zObs] = sph2cart(thetaVal(iTheta),phiVal(iPhi)+pi/2,1);
      cartVal(iPhi,iTheta,:) = [xObs yObs zObs];
   end
end

D = zeros(nPhi,nTheta);

[..]

   for iRay=1:nRay
   x = xy(1,iRay); %random points
        y = xy(2,iRay);
       
        if x^2+y^2<=1
            vec(1,1,:) = [x y 0];
       D = D + exp(-1i*k*scale*sum(bsxfun(@times,cartVal,vec),3));
        end
    end
 


Allerdings wird ein großer Teil der Rechenzeit (plausibelerweise) in der Berechnung der e-Funktion verbraucht. Viel hat das also leider nicht mehr gebracht.
Dafür hat man in dieser Form mit bsxfun ziemlich genau lineare Laufzeitabhängigkeit von nRay (klar), aber auch der Anzahl der Beobachtungsstellen (phiVal, thetaVal).

Leider ist die Laufzeit mit ~60s / 10^5 Strahlen immer noch einige Größenordnungen zu teuer für mich, so dass ich mich dennoch auf die Suche nach einem anderen Ansatz zur Berechnung machen werde.

Vielen Dank dir trotzdem, Jan. Smile

Liebe Grüße
bligg
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: 19.10.2010, 11:17     Titel:
  Antworten mit Zitat      
Hallo bligg,

wenn Du eine vollständige lauffähige Version posten würdest, könnten wir damit experimentieren.

Es sieht so aus, als habest Du den Aufruf von SPH2CART nicht beschleunigt, oder? In den Schleifen über iTheta und iPhi könnte man also noch viel Zeit sparen. Mit BSXFUN lassen sich sogar beide Schleifen ganz weglassen.

Aber die Schleife über nRay ist wohl aufwändiger.
Zunächst mal kannst Du die Berechnung von "x^2+y^2<=1" aus der Schleife heraus ziehen und so unnötige Iterationen sparen.
Dann multiplizierst Du "cartVal" mit "[x y 0]". Das Multiplizieren mit 0 kann man sich aber sparen.
Wahrscheinlich ist
Code:
cartVal * x + cartVal * y

schneller als der BSXFUN Aufruf. (Kommt das gleiche Ergebnis heraus??)

Ich würde noch "-1i*k*scale" als Konstante definieren.
Ich vermute, das Einführen der 3. Dimension für BSXFUN ist nicht nötig, aber das würde ich besser noch mal auspobieren - deswegen meinte ich, es wäre gut eine lauffähige Version zu posten.
Private Nachricht senden Benutzer-Profile anzeigen
 
bligg
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 23
Anmeldedatum: 15.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.10.2010, 13:10     Titel:
  Antworten mit Zitat      
Hallo Jan,

ich will das Beugungsmuster eigentlich als Modul eines größeren Programms benutzen (wie gesagt, lochförmige Blende ist nur zur Validierung), deshalb funktioniert das Abfrage rausziehen zur Beschleunigung nicht.

Ja, die sph2cart habe ich nicht beschleunigt, weil die Schleifen tatsächlich nur einen kleinen Teil ausmachen, und nur einmal bei der Initialisierung anfallen. Insbesondere sind sie von der Anzahl der Testrays unabhängig.

Das Ausrechnen der Konstante ist natürlich prinzipiell eine komfortable Möglichkeit, Performance zu gewinnen, ich suche aber Rechenzeitersparnis in der Größenordnung 100 oder mehr.
Ich denke, da muss man diesen Ansatz einfach als gescheitert bezeichnen. Wink

Es geht darum, dass ich später auf eine beliebig komplizierte Geometrie (die Kollisionsabfrage und Konsorten stehen) diese Strahlen haue, um die Brechung zu berechnen. Ich interessiere mich insbesondere nur für die über (hier) Theta gemittelten Werte.

(Kleiner Einschub: Ist es im englischsprachigen Raum üblich, die Kugelkoordinaten mit gegenüber der mir im deutschsprachigen Raum bekannten Winkelnamenkonvention verdrehten Namen zu bezeichnen?)

Etwas klarer: mir reicht die über den Azimut gemittelte Beugungsfigur in Abhängigkeit der Elevation/Polarwinkel.

Prinzipiell muss man dafür ein Integral auswerten, das wie eine Fourier-Transformation aussieht (Fourier-Optik), allerdings ist mir bei diesem Ansatz nicht klar, wie ich dort meine Winkel wieder rausfinde. Es gibt ein Beispiel von TMW: http://www.mathworks.com/help/techdoc/math/brentm1-1.html#brfb2uq
Ab dem Bild fehlt mir die Idee, wie ich an die Winkel komme.

Noch ein anderer Ansatz wäre, das Oberflächenintegral über die Projektion des Körpers in ein äquivalentes Konturintegral umzuwandeln (Satz von Stokes), das man dann wahrscheinlich noch ein Stück weit analytisch lösen kann.
Dort stellt sich aber das Problem, dass ich die Kontur irgendwie bestimmen müsste. Das ist ohne weitere Einschränkungen nur für konvexe Hüllen möglich.

Ich bekomme aus meiner Kollisionsabfrage sozusagen entweder an zufälligen Stellen oder in einem regelmäßigen Grid eine "getroffen" oder "nicht getroffen"-Ansage. Ich bekomme also eine Punktwolke, so oder so, um die ich eine Hülle bestimmen müsste, um das Konturintegral ausrechnen zu können.

Das nur zur Einordnung allgemein, ich hänge noch den etwas unaufgeräumten, weil so erstmal nur zum Testen geschriebenen, Code an. Es ist aber meines Erachtens verschenkte Liebesmüh', dort nach den letzten Optimierungsmöglichkeiten zu suchen; dieser stumpfe Zugang, das Oberflächenintegral direkt auszurechnen, scheint mir dann in Hinblick auf computational aspects ungeeignet.

Code:
phiVal = 0:pi/360:pi;
thetaVal = 0:pi/40:2*pi;

nPhi = length(phiVal);
nTheta = length(thetaVal);

cartVal = zeros(nPhi,nTheta,3);

for iTheta = 1:nTheta
    for iPhi = 1:nPhi
        [xObs,yObs,zObs] = sph2cart(thetaVal(iTheta),phiVal(iPhi)+pi/2,1);
        cartVal(iPhi,iTheta,:) = [xObs yObs zObs];
    end
end

D = zeros(nPhi,nTheta);
k = 2*pi/0.55;

scale = 25;

nRay = 10000;
xy = rand(2,nRay);

vec = zeros(1,1,3);

tic
   
for iRay=1:nRay
    x = xy(1,iRay);
    y = xy(2,iRay);
       
    if x^2+y^2<=1
        vec(1,1,:) = [x y 0];
        D = D + exp(-1i*k*scale*sum(bsxfun(@times,cartVal,vec),3));
    end
end
   
toc

S11 = k^2/(8*pi^2)*sum(D,2)'.*(cos(phiVal)+cos(phiVal).^2);
S22 = k^2/(8*pi^2)*sum(D,2)'.*(cos(phiVal)+1);

semilogy(phiVal,abs(S11).^2+abs(S22).^2);
%print -djpeg foo;


Die Aufteilung und das einzelne Auslesen von x und y auch nur, weil das die Form ist, in der ich später die Punkte eingeben würde, da bin ich mir der Unsauberkeiten bewusst! Very Happy

Liebe Grüße
bligg
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.