diff options
Diffstat (limited to 'epostunit.pas')
-rw-r--r-- | epostunit.pas | 155 |
1 files changed, 117 insertions, 38 deletions
diff --git a/epostunit.pas b/epostunit.pas index 0cc4cbf..37476d1 100644 --- a/epostunit.pas +++ b/epostunit.pas @@ -193,6 +193,7 @@ type procedure ermittlePhasenWinkel(threads: longint); procedure entspringe(threads: longint; entspringen: tEntspringModus); procedure fft2dNachbearbeitung(threads: longint; nB: tFFTDatenordnung; znt: boolean); + procedure fft2dQuadrieren(threads: longint; hcc,vcc: boolean); procedure schreibeWert(var f: textFile; p: tExtPoint; var letzterWert: extended; entspringen,verschiebung: extended; skalierung: string; linienIntegral: tLinienIntegral; tmpValues: tKnownValues); function exprToFloat(sT: boolean; s: string): extended; function findeZweitdominantestenPunkt(sT: boolean; f: tMyStringList): boolean; @@ -313,6 +314,13 @@ type constructor create(xMi,xMa: longint; pWerte: tWerte; endordnung: tFFTDatenordnung); procedure stExecute; override; end; + tFFT2dQThread = class(tLogThread) + xMin,xMax: longint; + pW: tWerte; + hcc,vcc: boolean; + constructor create(xMi,xMa: longint; pWerte: tWerte; hComplConj,vComplConj: boolean); + procedure stExecute; override; + end; tTauschThread = class(tLogThread) tMin,tMax: longint; pW: tWerte; @@ -5859,6 +5867,9 @@ var fensters: array[boolean] of tSin2Fenster; s: string; b: boolean; + c: char; + fftRichtungen: array[boolean] of char; + gespiegelt: array[boolean] of boolean; bekannteBefehle: tMyStringList; begin result:=false; @@ -5868,8 +5879,10 @@ begin gibAus('Eine 2d-Autokorrelation braucht (momentan) reelle Werte!',3); exit; end; - for b:=false to true do + for b:=false to true do begin fensters[b]:=tSin2Fenster.create; + gespiegelt[b]:=false; + end; bekannteBefehle:=tMyStringList.create; repeat if not f.metaReadln(s,true) then begin @@ -5881,14 +5894,18 @@ begin end; bekannteBefehle.clear; if istDasBefehl('Ende',s,bekannteBefehle,false) then break; - bekannteBefehle.add('''x-Fenster: ...'''); - bekannteBefehle.add('''t-Fenster: ...'''); - if (pos('-Fenster:',s)=2) and (s[1] in ['x','t']) then begin - b:=s[1]='t'; - erstesArgument(s,':'); - if b then fensters[b].rand:=round(kont2diskFak('t',exprToFloat(sT,s))) - else fensters[b].rand:=round(kont2diskFak('x',exprToFloat(sT,s))); - fensters[b].aktiv:=true; + for c in ['x','y','t'] do + if istDasBefehl(c+'-Fenster:',s,bekannteBefehle,true) then begin + fensters[c<>'x'].rand:=round(kont2diskFak(c,exprToFloat(sT,s))); + fensters[c<>'x'].aktiv:=true; + continue; + end; + if istDasBefehl('horizontal gespiegelt',s,bekannteBefehle,false) then begin + gespiegelt[false]:=true; + continue; + end; + if istDasBefehl('vertikal gespiegelt',s,bekannteBefehle,false) then begin + gespiegelt[true]:=true; continue; end; bekannteBefehle.sort; @@ -5922,40 +5939,39 @@ begin exit; end; - transformationen:=tFFTTransformation.create(transformationen,true,true,false); - gibAus('berechne t-FFT ...',3); - if not fft(threads,true,false,doRes,doResSmi,fensters[true],nil,pvFehler,warn) then begin - gibAus('Es traten Fehler auf!',3); - exit; + // sonst transformieren wir Zeilen, die nur Nullen beinhalten, in der 1. inversen FFT + if gespiegelt[true] and not gespiegelt[false] then begin + fftRichtungen[false]:='x'; + fftRichtungen[true]:='t'; + end + else begin + fftRichtungen[false]:='t'; + fftRichtungen[true]:='x'; end; - gibAus(' (Parseval-Fehler = '+floatToStr(pvFehler)+')',3); - gibAus('... fertig! '+timetostr(now-Zeit),3); - gibAus('berechne x-FFT ...',3); - if not fft(threads,false,false,doRes,doResSmi,fensters[false],nil,pvFehler,warn) then begin - gibAus('Es traten Fehler auf!',3); - exit; + + for b:=false to true do begin + gibAus('berechne '+fftRichtungen[b]+'-FFT ...',3); + if not fft(threads,fftRichtungen[b]='t',false,doRes,doResSmi,fensters[fftRichtungen[b]='t'],nil,pvFehler,warn) then begin + gibAus('Es traten Fehler auf!',3); + exit; + end; + gibAus(' (Parseval-Fehler = '+floatToStr(pvFehler)+')',3); + gibAus('... fertig! '+timetostr(now-Zeit),3); end; - gibAus(' (Parseval-Fehler = '+floatToStr(pvFehler)+')',3); - gibAus('... fertig! '+timetostr(now-Zeit),3); + for b:=false to true do + fensters[b].free; gibAus('Quadrieren ...',3); - fft2dNachbearbeitung(threads,doBetrQdr,false); - gibAus('... fertig! '+timetostr(now-Zeit),3); - gibAus('berechne inverse x-FFT ...',3); - if not fft(threads,false,true,doRes,doRes,nil,nil,pvFehler,warn) then begin - gibAus('Es traten Fehler auf!',3); - exit; - end; - gibAus(' (Parseval-Fehler = '+floatToStr(pvFehler)+')',3); + fft2dQuadrieren(threads,not gespiegelt[false],not gespiegelt[true]); gibAus('... fertig! '+timetostr(now-Zeit),3); - gibAus('berechne inverse t-FFT ...',3); - if not fft(threads,true,true,doRes,doRes,nil,nil,pvFehler,warn) then begin - gibAus('Es traten Fehler auf!',3); - exit; + for b:=true downto false do begin + gibAus('berechne inverse '+fftRichtungen[b]+'-FFT ...',3); + if not fft(threads,fftRichtungen[b]='t',true,doResSmi,doRes,nil,nil,pvFehler,warn) then begin + gibAus('Es traten Fehler auf!',3); + exit; + end; + gibAus(' (Parseval-Fehler = '+floatToStr(pvFehler)+')',3); + gibAus('... fertig! '+timetostr(now-Zeit),3); end; - gibAus(' (Parseval-Fehler = '+floatToStr(pvFehler)+')',3); - gibAus('... fertig! '+timetostr(now-Zeit),3); - for b:=false to true do - fensters[b].free; result:=true; end; @@ -7190,6 +7206,42 @@ begin end; end; +procedure tWerte.fft2dQuadrieren(threads: longint; hcc,vcc: boolean); +var + i: longint; + FQTs: array of tFFT2dQThread; + fertig: boolean; +begin + if istKomplex then + fehler('fft2Quadrieren kann (noch) keine voll-komplexen Werte quadrieren!'); + + // der "Rand" + case genauigkeit of + gSingle: sWerte.fft2dQuadrierenA(hcc,vcc); + gDouble: dWerte.fft2dQuadrierenA(hcc,vcc); + gExtended: eWerte.fft2dQuadrierenA(hcc,vcc); + end{of case}; + + // der Hauptteil (alles außer erster und mittlerer Zeile/Spalte) + setLength(FQTs,threads); + for i:=0 to length(FQTs)-1 do + FQTs[i]:=tFFT2dQThread.create( + round(i*(_xSteps div 2 -1)/length(FQTs))+1, + round((i+1)*(_xSteps div 2 -1)/length(FQTs)), + self, + hcc, + vcc); + repeat + sleep(10); + fertig:=true; + for i:=0 to length(FQTs)-1 do + fertig:=fertig and FQTs[i].fertig; + until fertig; + for i:=0 to length(FQTs)-1 do + FQTs[i].free; + gibAus('Alle FFT2dQThreads fertig!',1); +end; + function tWerte.exprToFloat(sT: boolean; s: string): extended; begin result:=matheunit.exprToFloat(sT,s,knownValues,@callBackGetValue); @@ -8121,6 +8173,33 @@ begin gibAus('... und fertig!',1); end; +// tFFT2dQThread *************************************************************** + +constructor tFFT2dQThread.create(xMi,xMa: longint; pWerte: tWerte; hComplConj,vComplConj: boolean); +begin + inherited create; + xMin:=xMi; + xMax:=xMa; + pW:=pWerte; + hcc:=hComplConj; + vcc:=vComplConj; + gibAus('FFT2d-Quadrierthread kreiert: '+intToStr(xMin)+'-'+intToStr(xMax),1); + suspended:=false; +end; + +procedure tFFT2dQThread.stExecute; +begin + gibAus('FFT2d-Quadrierthread gestartet: '+intToStr(xMin)+'-'+intToStr(xMax)+' ...',1); + if pW.istKomplex then + fehler('tFFT2dNBThread kann (noch) nicht komplex!'); + case pW.genauigkeit of + gSingle: pW.sWerte.fft2dQuadrierenB(xMin,xMax,hcc,vcc); + gDouble: pW.dWerte.fft2dQuadrierenB(xMin,xMax,hcc,vcc); + gExtended: pW.eWerte.fft2dQuadrierenB(xMin,xMax,hcc,vcc); + end{of case}; + gibAus('... und fertig!',1); +end; + // tTauschThread *************************************************************** constructor tTauschThread.create(tMi,tMa: longint; pWerte: tWerte); |