diff options
-rw-r--r-- | epost.lpr | 13 | ||||
-rw-r--r-- | epost.lps | 197 | ||||
-rw-r--r-- | epostunit.pas | 205 | ||||
-rw-r--r-- | werteunit.pas | 209 |
4 files changed, 473 insertions, 151 deletions
@@ -284,7 +284,7 @@ begin aufraeumen; halt(1); end; - if startetMit('Fitte Gauße an ',s) then begin + if startetMit('fitte Gauße an ',s) then begin i:=findeWerte(s,nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; @@ -358,6 +358,17 @@ begin aufraeumen; halt(1); end; + if startetMit('extrahiere Einhüllende von ',s) then begin + i:=findeWerte(s,nil,@wertes,@Konturen,false); + if i<0 then begin + aufraeumen; + halt(1); + end; + if wertes[i].extrahiereEinhuellende(syntaxtest,inf,maxthreads,Warnstufe) then + continue; + aufraeumen; + halt(1); + end; if startetMit('integriere ',s) then begin j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin @@ -7,9 +7,10 @@ <Unit0> <Filename Value="epost.lpr"/> <IsPartOfProject Value="True"/> - <TopLine Value="29"/> - <CursorPos Y="46"/> - <FoldState Value=" T0iUg4A123111221]6515]6[A431313[4421[U4121[85]eh"/> + <IsVisibleTab Value="True"/> + <TopLine Value="61"/> + <CursorPos X="21" Y="79"/> + <FoldState Value=" T0iUg4A123111221]6515]6[A431313[8621[W4121[85]g+"/> <UsageCount Value="202"/> <Loaded Value="True"/> </Unit0> @@ -24,9 +25,9 @@ <Filename Value="epostunit.pas"/> <IsPartOfProject Value="True"/> <EditorIndex Value="1"/> - <TopLine Value="3959"/> - <CursorPos X="24" Y="3980"/> - <FoldState Value=" T0=8k{V0G1C191N"/> + <TopLine Value="490"/> + <CursorPos X="21" Y="523"/> + <FoldState Value=" T0=9k{V0G1C191I"/> <UsageCount Value="201"/> <Loaded Value="True"/> </Unit2> @@ -40,20 +41,19 @@ <Unit4> <Filename Value="werteunit.pas"/> <IsPartOfProject Value="True"/> - <IsVisibleTab Value="True"/> - <EditorIndex Value="3"/> - <TopLine Value="382"/> - <CursorPos Y="417"/> - <FoldState Value=" T0uAkl051X111V"/> + <EditorIndex Value="4"/> + <TopLine Value="1811"/> + <CursorPos X="64" Y="1844"/> + <FoldState Value=" T0wDkl051X1116"/> <UsageCount Value="200"/> <Loaded Value="True"/> </Unit4> <Unit5> <Filename Value="typenunit.pas"/> <IsPartOfProject Value="True"/> - <EditorIndex Value="5"/> - <TopLine Value="1864"/> - <CursorPos X="59" Y="1883"/> + <EditorIndex Value="6"/> + <TopLine Value="1278"/> + <CursorPos X="14" Y="1283"/> <UsageCount Value="200"/> <Loaded Value="True"/> </Unit5> @@ -62,7 +62,7 @@ <IsPartOfProject Value="True"/> <EditorIndex Value="-1"/> <CursorPos X="3" Y="15"/> - <UsageCount Value="142"/> + <UsageCount Value="155"/> </Unit6> <Unit7> <Filename Value="../units/fftunit.inc"/> @@ -70,14 +70,14 @@ <EditorIndex Value="-1"/> <TopLine Value="10"/> <CursorPos X="22" Y="10"/> - <UsageCount Value="139"/> + <UsageCount Value="152"/> </Unit7> <Unit8> <Filename Value="gauszFit.inc"/> <IsPartOfProject Value="True"/> - <EditorIndex Value="4"/> + <EditorIndex Value="5"/> <CursorPos X="35" Y="10"/> - <UsageCount Value="45"/> + <UsageCount Value="58"/> <Loaded Value="True"/> </Unit8> <Unit9> @@ -85,82 +85,83 @@ <EditorIndex Value="-1"/> <TopLine Value="1612"/> <CursorPos X="2" Y="1675"/> - <UsageCount Value="3"/> + <UsageCount Value="0"/> </Unit9> <Unit10> <Filename Value="../units/mystringlistunit.pas"/> <EditorIndex Value="-1"/> <TopLine Value="289"/> <CursorPos X="74" Y="300"/> - <UsageCount Value="15"/> + <UsageCount Value="12"/> </Unit10> <Unit11> <Filename Value="../units/lowlevelunit.pas"/> - <EditorIndex Value="2"/> - <TopLine Value="383"/> - <CursorPos X="17" Y="412"/> - <UsageCount Value="51"/> + <EditorIndex Value="3"/> + <TopLine Value="21"/> + <CursorPos X="3" Y="39"/> + <UsageCount Value="58"/> <Loaded Value="True"/> </Unit11> <Unit12> <Filename Value="../units/randomunit.pas"/> <EditorIndex Value="-1"/> - <UsageCount Value="3"/> + <UsageCount Value="0"/> </Unit12> <Unit13> <Filename Value="../units/matheunit.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="185"/> - <CursorPos X="21" Y="188"/> - <UsageCount Value="30"/> + <EditorIndex Value="2"/> + <TopLine Value="517"/> + <CursorPos X="21" Y="393"/> + <UsageCount Value="32"/> + <Loaded Value="True"/> </Unit13> <Unit14> <Filename Value="../units/systemunit.pas"/> <EditorIndex Value="-1"/> <TopLine Value="186"/> <CursorPos Y="161"/> - <UsageCount Value="15"/> + <UsageCount Value="12"/> </Unit14> <Unit15> <Filename Value="/usr/lib/fpc/src/rtl/inc/objpash.inc"/> <EditorIndex Value="-1"/> <TopLine Value="182"/> <CursorPos X="21" Y="202"/> - <UsageCount Value="6"/> + <UsageCount Value="3"/> </Unit15> <Unit16> <Filename Value="/usr/lib/fpc/src/rtl/unix/bunxovlh.inc"/> <EditorIndex Value="-1"/> <TopLine Value="61"/> <CursorPos X="10" Y="99"/> - <UsageCount Value="4"/> + <UsageCount Value="1"/> </Unit16> <Unit17> <Filename Value="/usr/lib/fpc/src/rtl/unix/baseunix.pp"/> <UnitName Value="BaseUnix"/> <EditorIndex Value="-1"/> <TopLine Value="61"/> - <UsageCount Value="4"/> + <UsageCount Value="1"/> </Unit17> <Unit18> <Filename Value="/usr/lib/fpc/src/rtl/unix/bunxovl.inc"/> <EditorIndex Value="-1"/> <TopLine Value="414"/> <CursorPos X="20" Y="434"/> - <UsageCount Value="4"/> + <UsageCount Value="1"/> </Unit18> <Unit19> <Filename Value="/usr/lib/fpc/src/rtl/linux/bunxsysc.inc"/> <EditorIndex Value="-1"/> <TopLine Value="16"/> - <UsageCount Value="4"/> + <UsageCount Value="1"/> </Unit19> <Unit20> <Filename Value="/usr/lib/fpc/src/rtl/unix/bunxh.inc"/> <EditorIndex Value="-1"/> <TopLine Value="74"/> <CursorPos X="15" Y="102"/> - <UsageCount Value="4"/> + <UsageCount Value="1"/> </Unit20> <Unit21> <Filename Value="/usr/lib/fpc/src/packages/fcl-image/src/fpimage.pp"/> @@ -168,143 +169,141 @@ <EditorIndex Value="-1"/> <TopLine Value="10"/> <CursorPos X="3" Y="30"/> - <UsageCount Value="4"/> + <UsageCount Value="1"/> </Unit21> <Unit22> <Filename Value="../fpGUI/src/corelib/render/software/agg_basics.pas"/> <EditorIndex Value="-1"/> <TopLine Value="327"/> <CursorPos X="12" Y="347"/> - <UsageCount Value="7"/> + <UsageCount Value="4"/> </Unit22> <Unit23> <Filename Value="/usr/lib/fpc/src/rtl/objpas/classes/classesh.inc"/> <EditorIndex Value="-1"/> <TopLine Value="673"/> <CursorPos X="42" Y="705"/> - <UsageCount Value="7"/> + <UsageCount Value="4"/> </Unit23> </Units> <JumpHistory Count="30" HistoryIndex="29"> <Position1> - <Filename Value="typenunit.pas"/> - <Caret Line="1630" Column="47" TopLine="1613"/> + <Filename Value="epostunit.pas"/> + <Caret Line="318" TopLine="300"/> </Position1> <Position2> - <Filename Value="typenunit.pas"/> - <Caret Line="1755" Column="19" TopLine="1729"/> + <Filename Value="epostunit.pas"/> + <Caret Line="321" Column="16" TopLine="306"/> </Position2> <Position3> - <Filename Value="typenunit.pas"/> - <Caret Line="2196" TopLine="2178"/> + <Filename Value="epostunit.pas"/> + <Caret Line="383" Column="41" TopLine="354"/> </Position3> <Position4> - <Filename Value="typenunit.pas"/> - <Caret Line="1445" TopLine="1427"/> + <Filename Value="epostunit.pas"/> + <Caret Line="4638" Column="29" TopLine="4609"/> </Position4> <Position5> - <Filename Value="typenunit.pas"/> - <Caret Line="2196" TopLine="2178"/> + <Filename Value="epostunit.pas"/> + <Caret Line="6235" Column="28" TopLine="6232"/> </Position5> <Position6> - <Filename Value="typenunit.pas"/> - <Caret Line="1445" TopLine="1427"/> + <Filename Value="epostunit.pas"/> </Position6> <Position7> - <Filename Value="typenunit.pas"/> - <Caret Line="1912" Column="75" TopLine="1890"/> + <Filename Value="epostunit.pas"/> + <Caret Line="269" Column="13" TopLine="240"/> </Position7> <Position8> - <Filename Value="typenunit.pas"/> - <Caret Line="321" Column="36" TopLine="293"/> + <Filename Value="epostunit.pas"/> + <Caret Line="2734" Column="42" TopLine="2705"/> </Position8> <Position9> - <Filename Value="typenunit.pas"/> - <Caret Line="413" Column="86" TopLine="387"/> + <Filename Value="epostunit.pas"/> + <Caret Line="2757" Column="17" TopLine="2729"/> </Position9> <Position10> - <Filename Value="typenunit.pas"/> - <Caret Line="439" Column="36" TopLine="410"/> + <Filename Value="epostunit.pas"/> + <Caret Line="2780" Column="17" TopLine="2752"/> </Position10> <Position11> - <Filename Value="typenunit.pas"/> - <Caret Line="456" Column="36" TopLine="427"/> + <Filename Value="epostunit.pas"/> + <Caret Line="5294" Column="14" TopLine="5295"/> </Position11> <Position12> - <Filename Value="typenunit.pas"/> - <Caret Line="468" Column="36" TopLine="439"/> + <Filename Value="epostunit.pas"/> + <Caret TopLine="52"/> </Position12> <Position13> - <Filename Value="typenunit.pas"/> - <Caret Line="1738" Column="48" TopLine="1709"/> + <Filename Value="epostunit.pas"/> + <Caret Line="196" Column="13" TopLine="167"/> </Position13> <Position14> - <Filename Value="typenunit.pas"/> - <Caret Line="1748" Column="45" TopLine="1719"/> + <Filename Value="epostunit.pas"/> + <Caret Line="391" Column="33" TopLine="362"/> </Position14> <Position15> - <Filename Value="typenunit.pas"/> - <Caret Line="1802" Column="53" TopLine="1788"/> + <Filename Value="epostunit.pas"/> + <Caret Line="4594" Column="18" TopLine="4583"/> </Position15> <Position16> - <Filename Value="typenunit.pas"/> - <Caret Line="1872" Column="51" TopLine="1861"/> + <Filename Value="epostunit.pas"/> </Position16> <Position17> - <Filename Value="typenunit.pas"/> - <Caret Line="1889" TopLine="1861"/> + <Filename Value="epostunit.pas"/> + <Caret Line="196" Column="13" TopLine="200"/> </Position17> <Position18> - <Filename Value="typenunit.pas"/> - <Caret Line="2321" Column="51" TopLine="2292"/> + <Filename Value="epostunit.pas"/> + <Caret Line="151" Column="36" TopLine="123"/> </Position18> <Position19> - <Filename Value="typenunit.pas"/> - <Caret Line="2173" Column="60" TopLine="2166"/> + <Filename Value="epostunit.pas"/> + <Caret Line="3504" Column="63" TopLine="3484"/> </Position19> <Position20> - <Filename Value="typenunit.pas"/> - <Caret Line="321" Column="36" TopLine="305"/> + <Filename Value="epostunit.pas"/> + <Caret Line="3410" Column="89" TopLine="3392"/> </Position20> <Position21> - <Filename Value="typenunit.pas"/> - <Caret Line="355" Column="36" TopLine="326"/> + <Filename Value="werteunit.pas"/> + <Caret Line="965" Column="79" TopLine="950"/> </Position21> <Position22> - <Filename Value="typenunit.pas"/> - <Caret Line="377" Column="36" TopLine="348"/> + <Filename Value="werteunit.pas"/> + <Caret Line="70" Column="21" TopLine="56"/> </Position22> <Position23> - <Filename Value="typenunit.pas"/> - <Caret Line="413" Column="36" TopLine="384"/> + <Filename Value="werteunit.pas"/> + <Caret Line="1714" Column="71" TopLine="1694"/> </Position23> <Position24> - <Filename Value="typenunit.pas"/> - <Caret Line="439" Column="36" TopLine="410"/> + <Filename Value="werteunit.pas"/> + <Caret Line="71" Column="22" TopLine="53"/> </Position24> <Position25> - <Filename Value="typenunit.pas"/> - <Caret Line="456" Column="36" TopLine="427"/> + <Filename Value="epostunit.pas"/> + <Caret Line="3504" Column="70" TopLine="3486"/> </Position25> <Position26> - <Filename Value="typenunit.pas"/> - <Caret Line="468" Column="36" TopLine="439"/> + <Filename Value="epost.lpr"/> + <Caret Line="203" TopLine="98"/> </Position26> <Position27> - <Filename Value="typenunit.pas"/> - <Caret Line="1738" Column="48" TopLine="1709"/> + <Filename Value="epostunit.pas"/> + <Caret Line="133" Column="25" TopLine="116"/> </Position27> <Position28> - <Filename Value="typenunit.pas"/> - <Caret Line="1748" Column="45" TopLine="1719"/> + <Filename Value="epostunit.pas"/> + <Caret Line="134" Column="25" TopLine="116"/> </Position28> <Position29> - <Filename Value="typenunit.pas"/> - <Caret Line="1802" Column="53" TopLine="1773"/> + <Filename Value="epostunit.pas"/> + <Caret Line="517" Column="28" TopLine="488"/> </Position29> <Position30> - <Filename Value="werteunit.pas"/> - <Caret Line="458" Column="52" TopLine="448"/> + <Filename Value="epostunit.pas"/> + <Caret Line="519" Column="13" TopLine="490"/> </Position30> </JumpHistory> </ProjectSession> diff --git a/epostunit.pas b/epostunit.pas index e083d6d..e8fa7e9 100644 --- a/epostunit.pas +++ b/epostunit.pas @@ -142,12 +142,13 @@ type procedure ermittleMinMaxDichten(st: boolean; threads: longint; symmetrisch: boolean); overload; procedure ermittleMinMaxDichten(st: boolean; threads,xmin,xmax,tmin,tmax: longint; symmetrisch: boolean); overload; procedure gleicheMinMaxDichtenAn(st: boolean; f: tMyStringlist; symmetrisch: boolean); - function fft(threads: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fen: tFenster; out pvFehler: extended; Warn: tWarnstufe): boolean; overload; + function fft(threads: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fen: tFenster; hg: extended; out pvFehler: extended; Warn: tWarnstufe): boolean; overload; procedure initFuerGauszFit(st: boolean; daten: tWerte; senkrecht: boolean; adLaenge: longint; adStart,adStop: extended); function fitteGausze(st: boolean; f: tMyStringlist; threads: longint): boolean; function berechneZeitfrequenzanalyse(st: boolean; f: tMyStringlist; threads: longint; quelle: tWerte; Warn: tWarnstufe): boolean; function berechneVerzerrung(st: boolean; f: tMyStringlist; threads: longint; quelle: tWerte; Warn: tWarnstufe): boolean; function berechneLambdaZuOmegaVerzerrung(st: boolean; f: tMyStringList; threads: longint; quelle: tWerte): boolean; + function extrahiereEinhuellende(st: boolean; f: tMyStringlist; threads: longint; Warn: tWarnstufe): boolean; function berechneIntegral(st: boolean; f: tMyStringlist; threads: longint; quelle: tWerte): boolean; function berechneFFT(st: boolean; f: tMyStringlist; threads: longint; Warn: tWarnstufe): boolean; function berechneFFT2d(st: boolean; f: tMyStringlist; threads: longint; Warn: tWarnstufe): boolean; @@ -198,6 +199,7 @@ type raisedException: exception; function rFertig: boolean; public + erfolg: boolean; property fertig: boolean read rFertig write _fertig; @@ -267,12 +269,12 @@ type tFFTThread = class(tLogThread) smi,sma: longint; fen: tFenster; - erfolg,sen,inv: boolean; + sen,inv: boolean; algo: tFFTAlgorithmus; pW: tWerte; - pvFehler: extended; - constructor create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fenster: tFenster); overload; - constructor create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; algorithmus: tFFTAlgorithmus; fenster: tFenster); overload; + pvFehler,hg: extended; + constructor create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fenster: tFenster; hintergrund: extended); overload; + constructor create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; algorithmus: tFFTAlgorithmus; fenster: tFenster; hintergrund: extended); overload; procedure stExecute; override; end; tGauszFitThread = class(tLogThread) @@ -313,14 +315,13 @@ type tSortiereNachYThread = class(tLogThread) Kont: tKontur; vo,bi,mt: longint; - erfolg: boolean; constructor create(K: tKontur; threads,von,bis: longint); procedure stExecute; override; end; tBefehlThread = class(tLogThread) bg: boolean; p: tProcess; - constructor create(st: boolean; cmd: string; out erfolg: boolean); + constructor create(st: boolean; cmd: string; out erzeugungsErfolg: boolean); destructor destroy; override; procedure stExecute; override; end; @@ -2710,7 +2711,7 @@ begin end; end; -function tWerte.fft(threads: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fen: tFenster; out pvFehler: extended; Warn: tWarnstufe): boolean; +function tWerte.fft(threads: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fen: tFenster; hg: extended; out pvFehler: extended; Warn: tWarnstufe): boolean; var fftThreads: array of tFFTThread; i: longint; @@ -2718,13 +2719,15 @@ var begin result:=false; if senkrecht then begin - if length(fen.Werte)<>_tsiz then + if assigned(fen) and + (length(fen.Werte)<>_tsiz) then fen.berechneWerte(_tsiz); if threads>_xsteps then threads:=_xsteps; end else begin - if length(fen.Werte)<>_xsteps then + if assigned(fen) and + (length(fen.Werte)<>_xsteps) then fen.berechneWerte(_xsteps); if threads>_tsiz then threads:=_tsiz; @@ -2741,7 +2744,8 @@ begin invers, vor, nach, - fen); + fen, + hg); for i:=1 to threads-1 do fftThreads[i]:= tFFTThread.create( @@ -2751,7 +2755,8 @@ begin senkrecht, invers, fftThreads[0].algo, - fen); + fen, + hg); end else begin fftThreads[0]:= @@ -2763,7 +2768,8 @@ begin invers, vor, nach, - fen); + fen, + hg); for i:=1 to threads-1 do fftThreads[i]:= tFFTThread.create( @@ -2773,7 +2779,8 @@ begin senkrecht, invers, fftThreads[0].algo, - fen); + fen, + hg); end; repeat sleep(10); @@ -3154,7 +3161,7 @@ begin for i:=0 to length(eWerte.werte)-1 do total:=total+sqr(eWerte.werte[i]); gibAus('... fertig ('+floatToStr(total)+'), berechne Fouriertransformation ...',3); - if not fft(threads,senkrecht,false,doRes,doBetrQdr,wavelet,pvFehler,Warn) then begin + if not fft(threads,senkrecht,false,doRes,doBetrQdr,wavelet,0,pvFehler,Warn) then begin gibAus('Es traten Fehler auf!',3); wavelet.free; fenster.free; @@ -3400,6 +3407,117 @@ begin result:=true; end; +function tWerte.extrahiereEinhuellende(st: boolean; f: tMyStringlist; threads: longint; Warn: tWarnstufe): boolean; +var + Zeit,pvFehler,hintergrund,xFak,yFak: extended; + Fensters: array[boolean] of tSin2Fenster; + s: string; + b,hintergrundAbziehen: boolean; + betraege: tWerte; +begin + result:=false; + Zeit:=now; + if not st then + gibAus('Einhüllende extrahieren ...',3); + for b:=false to true do + Fensters[b]:=tSin2Fenster.create; + hintergrundAbziehen:=false; + hintergrund:=0; + xFak:=1; + yFak:=1; + repeat + if not f.metaReadln(s,true) then begin + gibAus('Unerwartetes Dateiende!',3); + exit; + end; + if s='Ende' then break; + if (pos('-Fenster:',s)=2) and (s[1] in ['x','t']) then begin + b:=s[1]='t'; + delete(s,1,pos(':',s)); + s:=trim(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; + continue; + end; + if s='Hintergrund abziehen' then begin + hintergrundAbziehen:=true; + continue; + end; + if startetMit('Abstandsmetrik ',s) then begin + xFak:=round(kont2diskFak('x',exprtofloat(st,erstesArgument(s)))); + yFak:=round(kont2diskFak('t',exprtofloat(st,s))); + end; + gibAus('Verstehe Option '''+s+''' nicht beim Extrahieren der Einhüllenden!',3); + exit; + until false; + Fensters[true].Breite:=_tsiz-Fensters[true].Breite; + Fensters[false].Breite:=_xsteps-Fensters[false].Breite; + + if st then begin + for b:=false to true do + Fensters[b].free; + result:=true; + exit; + end; + + if hintergrundAbziehen then begin + case Genauigkeit of + gSingle: + hintergrund:=sWerte.ermittleHintergrund; + gDouble: + hintergrund:=dWerte.ermittleHintergrund; + gExtended: + hintergrund:=eWerte.ermittleHintergrund; + end{of case}; + end; + + gibAus('berechne t-FFT ...',3); + if not fft(threads,true,false,doRes,doResSmi,Fensters[true],hintergrund,pvFehler,Warn) then begin + gibAus('Es traten Fehler auf!',3); + exit; + end; + gibAus(' (Parseval-Fehler = '+floattostr(pvFehler)+')',3); + gibAus('berechne x-FFT ...',3); + if not fft(threads,false,false,doRes,doResSmi,Fensters[false],0,pvFehler,Warn) then begin + gibAus('Es traten Fehler auf!',3); + exit; + end; + gibAus(' (Parseval-Fehler = '+floattostr(pvFehler)+')',3); + for b:=false to true do + Fensters[b].free; + + gibAus('spektrale Beträge ermitteln',3); + betraege:=tWerte.create(self,0,_xsteps-1); + betraege.fft2dNachbearbeitung(threads,doBetrQdr); + + gibAus('hohe Frequenzen filtern',3); + case Genauigkeit of + gSingle: + sWerte.filtereHoheFrequenzen(betraege.sWerte,xFak,yFak); + gDouble: + dWerte.filtereHoheFrequenzen(betraege.dWerte,xFak,yFak); + gExtended: + eWerte.filtereHoheFrequenzen(betraege.eWerte,xFak,yFak); + end{of case}; + betraege.free; + + gibAus('berechne inverse x-FFT ...',3); + if not fft(threads,false,true,doResSmi,doRes,nil,0,pvFehler,wsLasch) then begin + gibAus('Es traten Fehler auf!',3); + exit; + end; + gibAus(' (Parseval-Fehler = '+floattostr(pvFehler)+')',3); + gibAus('berechne inverse t-FFT ...',3); + if not fft(threads,true,true,doResSmi,doRes,nil,hintergrund,pvFehler,Warn) then begin + gibAus('Es traten Fehler auf!',3); + exit; + end; + gibAus(' (Parseval-Fehler = '+floattostr(pvFehler)+')',3); + gibAus('... fertig '+timetostr(now-Zeit),3); + result:=true; +end; + function tWerte.berechneIntegral(st: boolean; f: tMyStringlist; threads: longint; quelle: tWerte): boolean; var i,tmin,tmax,xmin,xmax: longint; @@ -3553,7 +3671,7 @@ begin Fenster.Breite:=_xsteps - Fenster.Rand; if not st then begin gibAus('berechne FFT ...',3); - if not fft(threads,senkrecht,false,doRes,NB,Fenster,pvFehler,Warn) then begin + if not fft(threads,senkrecht,false,doRes,NB,Fenster,0,pvFehler,Warn) then begin gibAus('Es traten Fehler auf!',3); Fenster.free; exit; @@ -3633,28 +3751,23 @@ begin gibAus('... fertig! '+timetostr(now-Zeit),3); end; gibAus('berechne t-FFT ...',3); - if not fft(threads,true,false,doRes,preOrd,Fensters[true],pvFehler,Warn) then begin + if not fft(threads,true,false,doRes,preOrd,Fensters[true],0,pvFehler,Warn) then begin gibAus('Es traten Fehler auf!',3); exit; 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,preOrd,Fensters[false],pvFehler,Warn) then begin + if not fft(threads,false,false,doRes,preOrd,Fensters[false],0,pvFehler,Warn) then begin gibAus('Es traten Fehler auf!',3); exit; end; gibAus(' (Parseval-Fehler = '+floattostr(pvFehler)+')',3); gibAus('... fertig! '+timetostr(now-Zeit),3); gibAus('Wertenachbearbeiten ...',3); - case genauigkeit of - gSingle: sWerte.fft2dNachbearbeitungA(nb); - gDouble: dWerte.fft2dNachbearbeitungA(nb); - gExtended: eWerte.fft2dNachbearbeitungA(nb); - end{of case}; case NB of doBetr,doBetrQdr: - fft2dNachbearbeitung(threads,nb); // die Hauptarbeit + fft2dNachbearbeitung(threads,nb); end{of case}; gibAus('... fertig! '+timetostr(now-Zeit),3); for b:=false to true do @@ -4403,10 +4516,18 @@ var i: longint; FNTs: array of tFFT2dNBThread; fertig: boolean; -begin // bearbeitet nur den Hauptteil (außer erster und mittlerer Zeile/Spalte) nach! +begin + // der "Rand" + case genauigkeit of + gSingle: sWerte.fft2dNachbearbeitungA(nb); + gDouble: dWerte.fft2dNachbearbeitungA(nb); + gExtended: eWerte.fft2dNachbearbeitungA(nb); + end{of case}; + + // der Hauptteil (alles außer erster und mittlerer Zeile/Spalte) setlength(FNTs,threads); for i:=0 to length(FNTs)-1 do - FNTs[i]:=TFFT2dNBThread.create( + FNTs[i]:=tFFT2dNBThread.create( round(i*(_xsteps div 2 -1)/length(FNTs))+1, round((i+1)*(_xsteps div 2 -1)/length(FNTs)), self, @@ -4481,12 +4602,13 @@ begin raisedException:=nil; freeonterminate:=false; fertig:=false; + erfolg:=true; end; destructor tLogThread.destroy; begin raisedException.free; - if (not behalteLogs) and not odd(__ausgabenMaske) then cleanupLog(threadID); + if (not behalteLogs) and erfolg and not odd(__ausgabenMaske) then cleanupLog(threadID); inherited destroy; end; @@ -5172,7 +5294,7 @@ end; // tFFTThread ****************************************************************** -constructor tFFTThread.create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fenster: tFenster); +constructor tFFTThread.create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; const vor,nach: tFFTDatenordnung; fenster: tFenster; hintergrund: extended); var tmpFFTAlgo: tFFTAlgorithmus; begin @@ -5180,11 +5302,11 @@ begin tmpFFTAlgo:=createFFTAlgorithmus(werte._tsiz,vor,nach) else tmpFFTAlgo:=createFFTAlgorithmus(werte._xsteps,vor,nach); - create(werte,smin,smax,senkrecht,invers,tmpFFTAlgo,fenster); + create(werte,smin,smax,senkrecht,invers,tmpFFTAlgo,fenster,hintergrund); tmpFFTAlgo.free; end; -constructor tFFTThread.create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; algorithmus: tFFTAlgorithmus; fenster: tFenster); +constructor tFFTThread.create(werte: tWerte; smin,smax: longint; senkrecht,invers: boolean; algorithmus: tFFTAlgorithmus; fenster: tFenster; hintergrund: extended); begin inherited create; pW:=werte; @@ -5194,6 +5316,7 @@ begin inv:=invers; algo:=createFFTAlgorithmus(algorithmus); fen:=fenster; + hg:=hintergrund; erfolg:=false; gibAus('FFTthread kreiert ('+inttostr(pW._xsteps)+' x '+inttostr(pW._tsiz)+': '+inttostr(smi)+' .. '+inttostr(sma)+'): '+algo.className,3); suspended:=false; @@ -5203,9 +5326,9 @@ procedure tFFTThread.stExecute; begin gibAus('FFTthread gestartet ('+inttostr(pW._xsteps)+' x '+inttostr(pW._tsiz)+': '+inttostr(smi)+' .. '+inttostr(sma)+'): '+algo.className+' ...',1); case pW.Genauigkeit of - gSingle: erfolg:=pW.sWerte.fft(smi,sma,sen,inv,algo,fen,pvFehler); - gDouble: erfolg:=pW.dWerte.fft(smi,sma,sen,inv,algo,fen,pvFehler); - gExtended: erfolg:=pW.eWerte.fft(smi,sma,sen,inv,algo,fen,pvFehler); + gSingle: erfolg:=pW.sWerte.fft(smi,sma,sen,inv,algo,fen,hg,pvFehler); + gDouble: erfolg:=pW.dWerte.fft(smi,sma,sen,inv,algo,fen,hg,pvFehler); + gExtended: erfolg:=pW.eWerte.fft(smi,sma,sen,inv,algo,fen,hg,pvFehler); end{of case}; gibAus('... und fertig! ',1); end; @@ -5340,7 +5463,7 @@ begin for j:=0 to qu._tsiz-1 do in0:=in0 and (zi.eWerte.werte[i+j*zi._xsteps]=0); gibAus('FFT berechnen ...',1); tmpFFTAlgo:=createFFTAlgorithmus(zi._tsiz,doRes,doResIms); - zi.eWerte.fft(true,false,tmpFFTAlgo,nil,pvF); + zi.eWerte.fft(true,false,tmpFFTAlgo,nil,0,pvF); tmpFFTAlgo.free; pvFehler:=pvF+pvFehler; if wl.typ=wtSin2 then // Das Sin²-Wavelet besteht eigntlich aus zwei! @@ -5373,11 +5496,11 @@ begin end; gibAus('... fertig, iFFT berechnen ...',1); tmpFFTAlgo:=createFFTAlgorithmus(zi._tsiz,doResIms,doBetrQdr); - zi.eWerte.fft(xmi,xma,true,true,tmpFFTAlgo,nil,pvF); + zi.eWerte.fft(xmi,xma,true,true,tmpFFTAlgo,nil,0,pvF); pvFehler:=pvF+pvFehler; case wl.typ of wtSin2: begin // Das Sin²-Wavelet besteht eigntlich aus zwei! - tmpW.eWerte.fft(true,true,tmpFFTAlgo,nil,pvF); + tmpW.eWerte.fft(true,true,tmpFFTAlgo,nil,0,pvF); pvFehler:=(pvF+pvFehler)/3; for i:=xmi to xma do for j:=0 to zi._tsiz-1 do begin @@ -6047,7 +6170,7 @@ end; // tBefehlThread *************************************************************** -constructor tBefehlThread.create(st: boolean; cmd: string; out erfolg: boolean); +constructor tBefehlThread.create(st: boolean; cmd: string; out erzeugungsErfolg: boolean); var nichtLeeresArgument: boolean; function shellParseNextArg(var s: string): string; @@ -6060,7 +6183,7 @@ begin if startetMit('"',s) then begin if pos('"',s)=0 then begin gibAus('Kein passendes zweites Anführungszeichen im Argument für den Befehl gefunden!',3); - erfolg:=false; + erzeugungsErfolg:=false; exit; end; result:=erstesArgument(s,'"'); @@ -6086,7 +6209,7 @@ begin if not st then inherited create; - erfolg:=cmd<>''; + erzeugungsErfolg:=cmd<>''; if st then begin endetMit('&',cmd); shellParseNextArg(cmd); @@ -6098,7 +6221,7 @@ begin p.Executable:=shellParseNextArg(cmd); end; nichtLeeresArgument:=cmd=''; - if not erfolg then begin + if not erzeugungsErfolg then begin if not st then begin p.free; p:=nil; @@ -6110,7 +6233,7 @@ begin shellParseNextArg(cmd) else p.Parameters.Add(shellParseNextArg(cmd)); - if not erfolg then begin + if not erzeugungsErfolg then begin if not st then begin p.free; p:=nil; diff --git a/werteunit.pas b/werteunit.pas index 4d67c4c..9a068a4 100644 --- a/werteunit.pas +++ b/werteunit.pas @@ -19,6 +19,7 @@ type Auch die korrekte Parallelisierung obliegt dem übergeordneten Programmteil. } private + procedure sortiereMaxima(var maxima: tIntPointArray); public werte: array of wgen; params: tExtrainfos; @@ -46,8 +47,8 @@ type procedure kopiereLOVerzerrt(original: pTLLWerteExtended; xmin,xmax,tmin,tmax: longint; verhHo,verhVe: extended); overload; destructor destroy; override; function liesDateien(dateien: tGenerischeInputDateiInfoArray): boolean; - function fft(senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; out pvFehler: extended): boolean; overload; inline; - function fft(smin,smax: longint; senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; out pvFehler: extended): boolean; overload; + function fft(senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; hg: extended; out pvFehler: extended): boolean; overload; inline; + function fft(smin,smax: longint; senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; hg: extended; out pvFehler: extended): boolean; overload; procedure spiegle; overload; procedure spiegle(tmin,tmax: longint); overload; procedure fft2dNachbearbeitungA(nb: tFFTDatenordnung); @@ -66,6 +67,8 @@ type procedure integriereDouble(qu: pTLLWerteDouble; xmi,xma,tmi,tma,xof,tof: longint; richtung: tIntegrationsRichtung); procedure integriereExtended(qu: pTLLWerteDouble; xmi,xma,tmi,tma,xof,tof: longint; richtung: tIntegrationsRichtung); procedure gauszFit(amplituden,breiten,positionen,ueberlappe,hintergruende: pTLLWerteExtended; von,bis: longint; senkrecht: boolean; fensterBreite,maxBreite,maxVerschiebung: extended; positionsMitten: tExtendedArray); + function ermittleHintergrund: extended; + procedure filtereHoheFrequenzen(betraege: tLLWerte; xFak,yFak: extended); end; tLLWerteSingle = specialize tLLWerte<single>; tLLWerteDouble = specialize tLLWerte<double>; @@ -90,6 +93,92 @@ implementation uses systemunit; +// tLLWerte ******************************************************************** + +procedure tLLWerte.sortiereMaxima(var maxima: tIntPointArray); +var + mins,maxs: tExtendedArray; + pivot,wert,wertLi,wertRe: extended; + vons,biss: tLongintArray; + tmp: tIntPoint; + i,li,re,cnt: int64; +begin + setlength(vons,1); + vons[0]:=0; + setlength(biss,1); + biss[0]:=length(maxima)-1; + setlength(mins,1); + setlength(maxs,1); + mins[0]:=0; + maxs[0]:=0; + for i:=vons[0] to biss[0] do begin + wert:=werte[maxima[i]['x']+maxima[i]['y']*params.xsteps]; + if (i=vons[0]) or (wert>maxs[0]) then + maxs[0]:=wert; + if (i=vons[0]) or (wert<mins[0]) then + mins[0]:=wert; + end; + cnt:=1; + + while cnt>0 do begin + li:=vons[cnt-1]; + re:=biss[cnt-1]; + + if (li>=re) or (mins[cnt-1]=maxs[cnt-1]) then begin + dec(cnt); + continue; + end; + + if cnt>=length(vons) then begin + setlength(vons,cnt+100); + setlength(biss,cnt+100); + setlength(mins,cnt+100); + setlength(maxs,cnt+100); + end; + + pivot:=sqrt(maxs[cnt-1]*mins[cnt-1]);//(maxs[cnt-1]+mins[cnt-1])/2; + + mins[cnt]:=mins[cnt-1]; + biss[cnt]:=biss[cnt-1]; + maxs[cnt]:=mins[cnt]; + mins[cnt-1]:=maxs[cnt-1]; + + while li<=re do begin + wertLi:=werte[maxima[li]['x']+maxima[li]['y']*params.xsteps]; + if wertLi>=pivot then begin + if wertLi<mins[cnt-1] then + mins[cnt-1]:=wertLi; + inc(li); + continue; + end; + wertRe:=werte[maxima[re]['x']+maxima[re]['y']*params.xsteps]; + if wertRe<=pivot then begin + if wertRe>maxs[cnt] then + maxs[cnt]:=wertRe; + dec(re); + continue; + end; + if wertLi>maxs[cnt] then + maxs[cnt]:=wertLi; + if wertRe<mins[cnt-1] then + mins[cnt-1]:=wertRe; + tmp['x']:=maxima[re]['x']; + tmp['y']:=maxima[re]['y']; + maxima[re]['x']:=maxima[li]['x']; + maxima[re]['y']:=maxima[li]['y']; + maxima[li]['x']:=tmp['x']; + maxima[li]['y']:=tmp['y']; + inc(li); + dec(re); + end; + + vons[cnt]:=li; + biss[cnt-1]:=re; + + inc(cnt); + end; +end; + constructor tLLWerte.create(ps: tExtrainfos); begin inherited create; @@ -902,19 +991,19 @@ begin end; end; -function tLLWerte.fft(senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; out pvFehler: extended): boolean; +function tLLWerte.fft(senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; hg: extended; out pvFehler: extended): boolean; begin if senkrecht then - result:=fft(0,params.xsteps-1,senkrecht,invers,algo,fen,pvFehler) + result:=fft(0,params.xsteps-1,senkrecht,invers,algo,fen,hg,pvFehler) else - result:=fft(0,params.tsiz-1,senkrecht,invers,algo,fen,pvFehler); + result:=fft(0,params.tsiz-1,senkrecht,invers,algo,fen,hg,pvFehler); end; -function tLLWerte.fft(smin,smax: longint; senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; out pvFehler: extended): boolean; +function tLLWerte.fft(smin,smax: longint; senkrecht,invers: boolean; algo: tFFTAlgorithmus; fen: tFenster; hg: extended; out pvFehler: extended): boolean; var i,j,pmax,pstep,sstep: longint; in0,out0: boolean; - vorher,nachher: extended; + vorher,nachher,offset: extended; begin result:=false; if senkrecht then begin @@ -929,12 +1018,15 @@ begin end; if assigned(fen) and fen.aktiv then begin + if invers then + gibAus('fft: Warnung, hier wird bei einer inversen FFT gefenstert - soll das so sein?',1); + offset:=byte(not invers)*hg; if length(fen.Werte)<>pmax+1 then fen.berechneWerte(pmax+1); for i:=smin to smax do // Werte fenstern for j:=0 to pmax do werte[i*sstep+j*pstep]:= - werte[i*sstep+j*pstep]*fen.Werte[j]; + (werte[i*sstep+j*pstep]-offset)*fen.Werte[j]; end; vorher:=0; @@ -972,6 +1064,12 @@ begin if (nachher=0) and (vorher=0) then pvFehler:=0 else pvFehler:=abs(nachher-vorher)/(nachher+vorher); + if invers and (hg<>0) then + for i:=smin to smax do // Hintergrund addieren + for j:=0 to pmax do + werte[i*sstep+j*pstep]:= + werte[i*sstep+j*pstep]+hg; + gibAus(inttostr(byte(senkrecht))+' '+inttostr(byte(invers))+' (Parseval-Fehler = '+floattostr(pvFehler)+') ... nämlich von '+floattostr(vorher)+' zu '+floattostr(nachher),1); if in0 then gibAus('Nur Nullen im Input der FFT!',1); if out0 then gibAus('Nur Nullen im Output der FFT!',1); @@ -1137,7 +1235,7 @@ begin // bearbeitet nur den Hauptteil (außer erster und mittlerer Zeile/Spalte) for j:=1 to params.tsiz div 2 -1 do begin werte[i+j*params.xsteps]:= sqr(extended(werte[i+j*params.xsteps]-werte[params.xsteps-i+(params.tsiz-j)*params.xsteps])) // Re^2 - +sqr(extended(werte[params.xsteps-i+j*params.xsteps]+werte[i+(params.tsiz-j)*params.xsteps])); // Im^2 + +sqr(extended(werte[params.xsteps-i+j*params.xsteps]+werte[i+(params.tsiz-j)*params.xsteps])); // Im^2 werte[params.xsteps-i+j*params.xsteps]:=werte[i+j*params.xsteps]; werte[i+(params.tsiz-j)*params.xsteps]:=werte[i+j*params.xsteps]; werte[params.xsteps-i+(params.tsiz-j)*params.xsteps]:=werte[i+j*params.xsteps]; @@ -1656,6 +1754,97 @@ begin end; end; +function tLLWerte.ermittleHintergrund: extended; +var + i: int64; +begin + result:=0; + for i:=0 to params.xsteps-1 do + result:=result + werte[i]; + for i:=1 to params.tsiz-2 do + result:=result + werte[i*params.xsteps]; + for i:=0 to params.xsteps-1 do + result:=result + werte[i + (params.tsiz-1)*params.xsteps]; + for i:=1 to params.tsiz-2 do + result:=result + werte[params.xsteps-1 + i*params.xsteps]; + result:= + result/2/(params.xsteps+params.tsiz-2); +end; + +procedure tLLWerte.filtereHoheFrequenzen(betraege: tLLWerte; xFak,yFak: extended); +var + maxima: tIntPointArray; + i,im,j,jm,mCnt: int64; + wert,minWert,maxWert: extended; +begin + setlength(maxima,0); + mCnt:=0; + for j:=0 to params.tsiz div 2 + 1 do begin + jm:=j - 1 + params.tsiz*byte(j=0); + for i:=0 to params.xsteps div 2 + 1 do begin + im:=i - 1 + params.xsteps*byte(i=0); + wert:=betraege.werte[i+j*params.xsteps]; + if + (wert > betraege.werte[im+j*params.xsteps]) and + (wert > betraege.werte[i+jm*params.xsteps]) and + (wert > betraege.werte[(i+1)+j*params.xsteps]) and + (wert > betraege.werte[i+(j+1)*params.xsteps]) then begin + if length(maxima)<=mCnt then + setlength(maxima,length(maxima)+1024); + maxima[mCnt]['x']:=i; + maxima[mCnt]['y']:=j; + inc(mCnt); + end; + end; + end; + setlength(maxima,mCnt); + writeln(length(maxima),' (von ',params.xsteps*params.tsiz,')'); + + betraege.sortiereMaxima(maxima); + mCnt:=1; + maxWert:=0; + for i:=1 to length(maxima)-1 do begin + minWert:=0; + for j:=0 to i-1 do begin + wert:=sqr((maxima[j]['x']-maxima[i]['x'])*xFak)+sqr((maxima[j]['y']-maxima[i]['y'])*yFak); + if (j=0) or (wert<minWert) then begin + minWert:=wert; + if (minWert<=maxWert) and (i<>1) then + break; + end; + end; + if (i=1) or (minWert>maxWert) then begin + maxWert:=minWert; + mCnt:=i; + end; + end; + + im:=params.xsteps div 2 + 1; + jm:=params.tsiz div 2 + 1; + for j:=0 to jm do + for i:=0 to im do begin + wert:=(sqr(i)*xFak+sqr(j)*yFak)/(sqr(maxima[mCnt]['x'])*xFak+sqr(maxima[mCnt]['y'])*yFak); + if wert > 0.6 then + wert:=0 + else if wert > 0.4 then + wert:=(1+cos((wert-0.4)/0.2*pi))/2 + else + wert:=1; + + werte[i+j*params.xsteps]:= + werte[i+j*params.xsteps]*wert; + if (i>0) and (i<im) then + werte[params.xsteps-i+j*params.xsteps]:= + werte[params.xsteps-i+j*params.xsteps]*wert; + if (j>0) and (j<jm) then + werte[i+(params.tsiz-j)*params.xsteps]:= + werte[i+(params.tsiz-j)*params.xsteps]*wert; + if (i>0) and (i<im) and (j>0) and (j<jm) then + werte[params.xsteps-i+(params.tsiz-j)*params.xsteps]:= + werte[params.xsteps-i+(params.tsiz-j)*params.xsteps]*wert; + end; +end; + // tWavelet ******************************************************************** function tWavelet.setzeTyp(s: string): boolean; @@ -1711,7 +1900,7 @@ begin end; gibAus(inttostr(werte.params.xsteps)+' '+inttostr(werte.params.tsiz)+' '+inttostr(length(werte.werte)),1); tmpFFTAlgo:=createFFTAlgorithmus(2*hlen,doRes,doResIms); - werte.fft(true,false,tmpFFTAlgo,nil,pvFehler); + werte.fft(true,false,tmpFFTAlgo,nil,0,pvFehler); tmpFFTAlgo.free; end; wtFrequenzfenster: begin |