summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2016-03-29 15:00:11 +0200
committerErich Eckner <git@eckner.net>2016-03-30 16:08:21 +0200
commit238e18a5ce087c3b2940722bda86b39a95a44065 (patch)
tree1520af6e6ae342de306905e2d64f01c1e7cbfb6e
parentda9fb8d996bbf50058d6ca40137fcc9eb14b4f82 (diff)
downloadepost-238e18a5ce087c3b2940722bda86b39a95a44065.tar.xz
Gaußfit eingebaut
-rw-r--r--epost.lpi6
-rw-r--r--epost.lpr11
-rw-r--r--epost.lps223
-rw-r--r--epostunit.pas272
-rw-r--r--gauszFit.inc17
-rw-r--r--typenunit.pas66
-rw-r--r--werteunit.pas179
7 files changed, 657 insertions, 117 deletions
diff --git a/epost.lpi b/epost.lpi
index 89d94c9..4f8aa37 100644
--- a/epost.lpi
+++ b/epost.lpi
@@ -39,7 +39,7 @@
<PackageName Value="LazUtils"/>
</Item1>
</RequiredPackages>
- <Units Count="8">
+ <Units Count="9">
<Unit0>
<Filename Value="epost.lpr"/>
<IsPartOfProject Value="True"/>
@@ -72,6 +72,10 @@
<Filename Value="../units/fftunit.inc"/>
<IsPartOfProject Value="True"/>
</Unit7>
+ <Unit8>
+ <Filename Value="gauszFit.inc"/>
+ <IsPartOfProject Value="True"/>
+ </Unit8>
</Units>
</ProjectOptions>
<CompilerOptions>
diff --git a/epost.lpr b/epost.lpr
index ab04b20..93fed13 100644
--- a/epost.lpr
+++ b/epost.lpr
@@ -284,6 +284,17 @@ begin
aufraeumen;
halt(1);
end;
+ if startetMit('Fitte Gauße an ',s) then begin
+ i:=findeWerte(s,nil,@wertes,@Konturen,false);
+ if i<0 then begin
+ aufraeumen;
+ halt(1);
+ end;
+ if wertes[i].fitteGausze(syntaxtest,inf,maxthreads) then
+ continue;
+ aufraeumen;
+ halt(1);
+ end;
if startetMit('Zeitfrequenzanalyse ',s) then begin
j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false);
if j<0 then begin
diff --git a/epost.lps b/epost.lps
index e90a86d..69c0fb7 100644
--- a/epost.lps
+++ b/epost.lps
@@ -3,13 +3,12 @@
<ProjectSession>
<Version Value="9"/>
<BuildModes Active="Default"/>
- <Units Count="23">
+ <Units Count="24">
<Unit0>
<Filename Value="epost.lpr"/>
<IsPartOfProject Value="True"/>
- <TopLine Value="80"/>
- <CursorPos X="14" Y="65"/>
- <FoldState Value=" T0icW39123111221]65151[84313[4421[Q4121[85]a9"/>
+ <TopLine Value="55"/>
+ <CursorPos Y="81"/>
<UsageCount Value="202"/>
<Loaded Value="True"/>
</Unit0>
@@ -23,11 +22,9 @@
<Unit2>
<Filename Value="epostunit.pas"/>
<IsPartOfProject Value="True"/>
- <IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
- <TopLine Value="2772"/>
- <CursorPos Y="2792"/>
- <FoldState Value=" T0/Cm$0C1~"/>
+ <TopLine Value="2748"/>
+ <CursorPos X="9" Y="2783"/>
<UsageCount Value="201"/>
<Loaded Value="True"/>
</Unit2>
@@ -41,10 +38,9 @@
<Unit4>
<Filename Value="werteunit.pas"/>
<IsPartOfProject Value="True"/>
- <EditorIndex Value="4"/>
- <TopLine Value="619"/>
- <CursorPos X="29" Y="627"/>
- <FoldState Value=" T0pekl05121U1S"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="3"/>
+ <FoldState Value=" T0pfkl05121U1V"/>
<UsageCount Value="200"/>
<Loaded Value="True"/>
</Unit4>
@@ -52,8 +48,8 @@
<Filename Value="typenunit.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="5"/>
- <TopLine Value="2329"/>
- <CursorPos X="29" Y="2391"/>
+ <TopLine Value="2072"/>
+ <CursorPos X="98" Y="2086"/>
<UsageCount Value="200"/>
<Loaded Value="True"/>
</Unit5>
@@ -62,7 +58,7 @@
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="3" Y="15"/>
- <UsageCount Value="113"/>
+ <UsageCount Value="127"/>
</Unit6>
<Unit7>
<Filename Value="../units/fftunit.inc"/>
@@ -70,232 +66,241 @@
<EditorIndex Value="-1"/>
<TopLine Value="10"/>
<CursorPos X="22" Y="10"/>
- <UsageCount Value="110"/>
+ <UsageCount Value="124"/>
</Unit7>
<Unit8>
+ <Filename Value="gauszFit.inc"/>
+ <IsPartOfProject Value="True"/>
+ <EditorIndex Value="4"/>
+ <CursorPos X="35" Y="10"/>
+ <UsageCount Value="30"/>
+ <Loaded Value="True"/>
+ </Unit8>
+ <Unit9>
<Filename Value="../fpGUI/src/corelib/render/software/agg_scanline_storage_aa.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="1612"/>
<CursorPos X="2" Y="1675"/>
- <UsageCount Value="5"/>
- </Unit8>
- <Unit9>
+ <UsageCount Value="4"/>
+ </Unit9>
+ <Unit10>
<Filename Value="../units/mystringlistunit.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="289"/>
<CursorPos X="74" Y="300"/>
- <UsageCount Value="18"/>
- </Unit9>
- <Unit10>
- <Filename Value="../units/lowlevelunit.pas"/>
- <EditorIndex Value="3"/>
- <CursorPos X="32" Y="11"/>
- <UsageCount Value="36"/>
- <Loaded Value="True"/>
+ <UsageCount Value="16"/>
</Unit10>
<Unit11>
- <Filename Value="../units/randomunit.pas"/>
- <EditorIndex Value="-1"/>
- <UsageCount Value="5"/>
+ <Filename Value="../units/lowlevelunit.pas"/>
+ <EditorIndex Value="2"/>
+ <TopLine Value="544"/>
+ <CursorPos Y="564"/>
+ <UsageCount Value="43"/>
+ <Loaded Value="True"/>
</Unit11>
<Unit12>
+ <Filename Value="../units/randomunit.pas"/>
+ <EditorIndex Value="-1"/>
+ <UsageCount Value="4"/>
+ </Unit12>
+ <Unit13>
<Filename Value="../units/matheunit.pas"/>
- <EditorIndex Value="2"/>
+ <EditorIndex Value="-1"/>
<TopLine Value="185"/>
<CursorPos X="21" Y="188"/>
- <UsageCount Value="32"/>
- <Loaded Value="True"/>
- </Unit12>
- <Unit13>
+ <UsageCount Value="31"/>
+ </Unit13>
+ <Unit14>
<Filename Value="../units/systemunit.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="186"/>
<CursorPos Y="161"/>
- <UsageCount Value="17"/>
- </Unit13>
- <Unit14>
+ <UsageCount Value="16"/>
+ </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="8"/>
- </Unit14>
- <Unit15>
+ <UsageCount Value="7"/>
+ </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="6"/>
- </Unit15>
- <Unit16>
+ <UsageCount Value="5"/>
+ </Unit16>
+ <Unit17>
<Filename Value="/usr/lib/fpc/src/rtl/unix/baseunix.pp"/>
<UnitName Value="BaseUnix"/>
<EditorIndex Value="-1"/>
<TopLine Value="61"/>
- <UsageCount Value="6"/>
- </Unit16>
- <Unit17>
+ <UsageCount Value="5"/>
+ </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="6"/>
- </Unit17>
- <Unit18>
+ <UsageCount Value="5"/>
+ </Unit18>
+ <Unit19>
<Filename Value="/usr/lib/fpc/src/rtl/linux/bunxsysc.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="16"/>
- <UsageCount Value="6"/>
- </Unit18>
- <Unit19>
+ <UsageCount Value="5"/>
+ </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="6"/>
- </Unit19>
- <Unit20>
+ <UsageCount Value="5"/>
+ </Unit20>
+ <Unit21>
<Filename Value="/usr/lib/fpc/src/packages/fcl-image/src/fpimage.pp"/>
<UnitName Value="FPimage"/>
<EditorIndex Value="-1"/>
<TopLine Value="10"/>
<CursorPos X="3" Y="30"/>
- <UsageCount Value="6"/>
- </Unit20>
- <Unit21>
+ <UsageCount Value="5"/>
+ </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="9"/>
- </Unit21>
- <Unit22>
+ <UsageCount Value="8"/>
+ </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="9"/>
- </Unit22>
+ <UsageCount Value="8"/>
+ </Unit23>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="epostunit.pas"/>
- <Caret Line="89" Column="43" TopLine="69"/>
+ <Filename Value="gauszFit.inc"/>
+ <Caret Line="6" Column="19"/>
</Position1>
<Position2>
- <Filename Value="epostunit.pas"/>
- <Caret Line="1094" TopLine="1063"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1274" Column="71" TopLine="1254"/>
</Position2>
<Position3>
- <Filename Value="epostunit.pas"/>
- <Caret Line="1152" Column="46" TopLine="1120"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1349" Column="24" TopLine="1323"/>
</Position3>
<Position4>
- <Filename Value="epostunit.pas"/>
- <Caret Line="1156" Column="46" TopLine="1124"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1367" Column="44" TopLine="1347"/>
</Position4>
<Position5>
- <Filename Value="epostunit.pas"/>
- <Caret Line="1691" Column="26" TopLine="1683"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1389" Column="85" TopLine="1368"/>
</Position5>
<Position6>
<Filename Value="werteunit.pas"/>
- <Caret Line="45" Column="25" TopLine="27"/>
+ <Caret Line="1307" Column="25" TopLine="1281"/>
</Position6>
<Position7>
- <Filename Value="werteunit.pas"/>
- <Caret Line="631" Column="28" TopLine="382"/>
+ <Filename Value="epostunit.pas"/>
+ <Caret Line="5030" Column="13" TopLine="5015"/>
</Position7>
<Position8>
- <Filename Value="werteunit.pas"/>
- <Caret Line="645" TopLine="382"/>
+ <Filename Value="epostunit.pas"/>
+ <Caret Line="276" Column="18" TopLine="256"/>
</Position8>
<Position9>
<Filename Value="werteunit.pas"/>
- <Caret Line="641" Column="30" TopLine="602"/>
+ <Caret Line="1260" Column="36" TopLine="1252"/>
</Position9>
<Position10>
<Filename Value="werteunit.pas"/>
- <Caret Line="627" Column="71" TopLine="602"/>
+ <Caret Line="1310" Column="44" TopLine="1300"/>
</Position10>
<Position11>
- <Filename Value="werteunit.pas"/>
+ <Filename Value="epostunit.pas"/>
+ <Caret Line="2736" Column="37" TopLine="2656"/>
</Position11>
<Position12>
<Filename Value="epostunit.pas"/>
- <Caret Line="1691" Column="26" TopLine="1683"/>
+ <Caret Line="116" Column="23" TopLine="97"/>
</Position12>
<Position13>
<Filename Value="epostunit.pas"/>
- <Caret Line="2797" Column="53" TopLine="2785"/>
+ <Caret Line="1598" Column="31" TopLine="1593"/>
</Position13>
<Position14>
- <Filename Value="../units/matheunit.pas"/>
- <Caret Line="37" Column="21" TopLine="17"/>
+ <Filename Value="epostunit.pas"/>
+ <Caret Line="1597" TopLine="1576"/>
</Position14>
<Position15>
<Filename Value="epostunit.pas"/>
- <Caret Line="2804" Column="50" TopLine="2785"/>
+ <Caret Line="117" Column="67" TopLine="98"/>
</Position15>
<Position16>
<Filename Value="epostunit.pas"/>
- <Caret Line="6352" Column="22" TopLine="6331"/>
+ <Caret Line="147" Column="25" TopLine="115"/>
</Position16>
<Position17>
- <Filename Value="epostunit.pas"/>
- <Caret Line="364" Column="24" TopLine="344"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1258" Column="69" TopLine="1254"/>
</Position17>
<Position18>
<Filename Value="epostunit.pas"/>
- <Caret Line="6356" Column="13" TopLine="6343"/>
+ <Caret Line="5008" Column="83" TopLine="5003"/>
</Position18>
<Position19>
<Filename Value="epostunit.pas"/>
- <Caret Line="316" Column="16" TopLine="296"/>
+ <Caret Line="284" Column="84" TopLine="284"/>
</Position19>
<Position20>
<Filename Value="epostunit.pas"/>
- <Caret Line="371" Column="41" TopLine="338"/>
+ <Caret Line="2734" Column="59" TopLine="2655"/>
</Position20>
<Position21>
<Filename Value="epostunit.pas"/>
- <Caret Line="4058" Column="29" TopLine="4025"/>
+ <Caret Line="2729" TopLine="2676"/>
</Position21>
<Position22>
<Filename Value="epostunit.pas"/>
- <Caret Line="4059" Column="41" TopLine="4026"/>
+ <Caret Line="5042" Column="5" TopLine="5023"/>
</Position22>
<Position23>
- <Filename Value="epostunit.pas"/>
- <Caret Line="4060" Column="41" TopLine="4027"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="65" Column="23" TopLine="46"/>
</Position23>
<Position24>
- <Filename Value="epostunit.pas"/>
- <Caret Line="4061" Column="43" TopLine="4052"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1404" Column="83" TopLine="1379"/>
</Position24>
<Position25>
- <Filename Value="epostunit.pas"/>
- <Caret Line="4062" Column="46" TopLine="4052"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1403" Column="19" TopLine="1247"/>
</Position25>
<Position26>
- <Filename Value="epostunit.pas"/>
- <Caret Line="5618" Column="17" TopLine="5612"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="65" Column="78" TopLine="47"/>
</Position26>
<Position27>
<Filename Value="epostunit.pas"/>
- <Caret Line="5620" Column="26" TopLine="5627"/>
+ <Caret Line="277" Column="18" TopLine="258"/>
</Position27>
<Position28>
<Filename Value="epostunit.pas"/>
- <Caret Line="5724" Column="25" TopLine="5684"/>
+ <Caret Line="2769" Column="105" TopLine="2758"/>
</Position28>
<Position29>
- <Filename Value="epostunit.pas"/>
- <Caret Line="2640" Column="24" TopLine="2610"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1394" Column="17" TopLine="1372"/>
</Position29>
<Position30>
- <Filename Value="epostunit.pas"/>
- <Caret Line="2777" TopLine="2757"/>
+ <Filename Value="werteunit.pas"/>
+ <Caret Line="1408" Column="27" TopLine="1388"/>
</Position30>
</JumpHistory>
</ProjectSession>
diff --git a/epostunit.pas b/epostunit.pas
index dda146b..42c7151 100644
--- a/epostunit.pas
+++ b/epostunit.pas
@@ -142,6 +142,8 @@ type
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;
+ 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 berechneIntegral(st: boolean; f: tMyStringlist; threads: longint; quelle: tWerte): boolean;
@@ -278,6 +280,16 @@ type
destructor destroy; override;
procedure stExecute; override;
end;
+ tGauszFitThread = class(tLogThread)
+ qu: tWerte;
+ ampl,br,posi,ueberl,hint: pTLLWerteExtended;
+ vo,bi: longint;
+ senkr: boolean;
+ fenBr,maxBr,maxVersch: extended;
+ posiMitten: tExtendedArray;
+ constructor create(daten,amplituden,breiten,positionen,ueberlappe,hintergruende: tWerte; von,bis: longint; senkrecht: boolean; fensterBreite,maxBreite,maxVerschiebung: extended; positionsMitten: tExtendedArray);
+ procedure stExecute; override;
+ end;
tKorrelThread = class(tLogThread)
wl: tWavelet;
xMi,xMa: longint;
@@ -2049,11 +2061,11 @@ begin
(Transformationen as tAgglomeration).nullposition:=exprtofloat(st,s);
continue;
end;
- if s='horizontal' then begin
+ if s='waagerecht' then begin
(Transformationen as tAgglomeration).horizontal:=true;
continue;
end;
- if s='vertikal' then begin
+ if s='senkrecht' then begin
(Transformationen as tAgglomeration).horizontal:=true;
continue;
end;
@@ -2626,6 +2638,201 @@ begin
gibAus('Alle FFTThreads fertig!',1);
end;
+procedure tWerte.initFuerGauszFit(st: boolean; daten: tWerte; senkrecht: boolean; adLaenge: longint; adStart,adStop: extended);
+begin
+ Transformationen:=tFitTransformation.create(daten.Transformationen,senkrecht,adLaenge,adStart,adStop);
+ _xsteps:=Transformationen.xsteps;
+ _tsiz:=Transformationen.tsiz;
+ Genauigkeit:=gExtended;
+ if not st then
+ eWerte.holeRam(3);
+end;
+
+function tWerte.fitteGausze(st: boolean; f: tMyStringlist; threads: longint): boolean;
+var
+ Zeit: extended;
+ senkrecht,fertig: boolean;
+ s: string;
+ i,iterDim: longint;
+ ampl,br,posi,ueberl,hint: tWerte;
+ maxBreite,maxVerschiebung,fensterBreite: extended;
+ posiMitten: tExtendedArray;
+ gauszFitThreads: array of tGauszFitThread;
+begin
+ result:=false;
+ Zeit:=now;
+ if not st then
+ gibAus('Gauße fitten ...',3);
+ ampl:=nil;
+ br:=nil;
+ posi:=nil;
+ ueberl:=nil;
+ hint:=nil;
+ senkrecht:=true;
+ maxBreite:=-1;
+ maxVerschiebung:=-1;
+ fensterBreite:=-1;
+ setlength(posiMitten,0);
+ repeat
+ if not f.metaReadln(s,true) then begin
+ gibAus('Unerwartetes Dateiende!',3);
+ exit;
+ end;
+ if s='Ende' then break;
+ if s='senkrecht' then begin
+ senkrecht:=true;
+ continue;
+ end;
+ if s='waagerecht' then begin
+ senkrecht:=false;
+ continue;
+ end;
+ if startetMit('Amplituden:',s) then begin
+ i:=findeWerte(s,f,wertes,konturen,true);
+ if i<0 then
+ exit;
+ if assigned(ampl) then begin
+ gibAus('Habe bereits ein Ziel für die Amplituden beim Fitten eines Gaußes!',3);
+ exit;
+ end;
+ ampl:=wertes^[i];
+ continue;
+ end;
+ if startetMit('Breiten:',s) then begin
+ i:=findeWerte(s,f,wertes,konturen,true);
+ if i<0 then
+ exit;
+ if assigned(br) then begin
+ gibAus('Habe bereits ein Ziel für die Breiten beim Fitten eines Gaußes!',3);
+ exit;
+ end;
+ br:=wertes^[i];
+ continue;
+ end;
+ if startetMit('Positionen:',s) then begin
+ i:=findeWerte(s,f,wertes,konturen,true);
+ if i<0 then
+ exit;
+ if assigned(posi) then begin
+ gibAus('Habe bereits ein Ziel für die Positionen beim Fitten eines Gaußes!',3);
+ exit;
+ end;
+ posi:=wertes^[i];
+ continue;
+ end;
+ if startetMit('Überlapp:',s) then begin
+ i:=findeWerte(s,f,wertes,konturen,true);
+ if i<0 then
+ exit;
+ if assigned(ueberl) then begin
+ gibAus('Habe bereits ein Ziel für den Überlapp beim Fitten eines Gaußes!',3);
+ exit;
+ end;
+ ueberl:=wertes^[i];
+ continue;
+ end;
+ if startetMit('Hintergrund:',s) then begin
+ i:=findeWerte(s,f,wertes,konturen,true);
+ if i<0 then
+ exit;
+ if assigned(hint) then begin
+ gibAus('Habe bereits ein Ziel für den Hintergrund beim Fitten eines Gaußes!',3);
+ exit;
+ end;
+ hint:=wertes^[i];
+ continue;
+ end;
+ if startetMit('Maximalverschiebung:',s) then begin
+ maxVerschiebung:=kont2diskFak(senkrecht,exprtofloat(st,s));
+ continue;
+ end;
+ if startetMit('Maximalbreite:',s) then begin
+ maxBreite:=kont2diskFak(senkrecht,exprtofloat(st,s));
+ continue;
+ end;
+ if startetMit('Fensterbreite:',s) then begin
+ fensterBreite:=kont2diskFak(senkrecht,exprtofloat(st,s));
+ continue;
+ end;
+ if startetMit('Positionsbereichsmitten:',s) then begin
+ while s<>'' do
+ fuegeSortiertHinzu(kont2disk(senkrecht,exprToFloat(st,erstesArgument(s))),posiMitten);
+ continue;
+ end;
+ gibAus('Verstehe Option '''+s+''' nicht beim Fitten eines Gaußes!',3);
+ exit;
+ until false;
+
+ if (2*maxVerschiebung>fensterBreite) or ((maxVerschiebung<0) and (fensterBreite>0)) then
+ maxVerschiebung:=fensterBreite/2;
+
+ if length(posiMitten)=0 then begin
+ gibAus('Es sind keine Gauße zu fitten! Was soll das?',3);
+ exit;
+ end;
+
+ if not (assigned(ampl) or assigned(br) or assigned(posi) or assigned(ueberl) or assigned(hint)) then begin
+ gibAus('Es sind keine Parameter des Gaußes zu speichern! Was soll das?',3);
+ exit;
+ end;
+
+ if assigned(ampl) then
+ ampl.initFuerGauszFit(st,self,senkrecht,length(posiMitten),posiMitten[0],posiMitten[length(posiMitten)-1]);
+ if assigned(br) then
+ br.initFuerGauszFit(st,self,senkrecht,length(posiMitten),posiMitten[0],posiMitten[length(posiMitten)-1]);
+ if assigned(posi) then
+ posi.initFuerGauszFit(st,self,senkrecht,length(posiMitten),posiMitten[0],posiMitten[length(posiMitten)-1]);
+ if assigned(ueberl) then
+ ueberl.initFuerGauszFit(st,self,senkrecht,length(posiMitten),posiMitten[0],posiMitten[length(posiMitten)-1]);
+ if assigned(hint) then
+ hint.initFuerGauszFit(st,self,senkrecht,length(posiMitten),posiMitten[0],posiMitten[length(posiMitten)-1]);
+
+ if senkrecht then
+ iterDim:=_xsteps
+ else
+ iterDim:=_tsiz;
+
+ if threads > iterDim then
+ threads:=iterDim;
+
+ if st then begin
+ result:=true;
+ exit;
+ end;
+
+ setlength(gauszFitThreads,threads);
+ for i:=0 to threads-1 do
+ gauszFitThreads[i]:=
+ tGauszFitThread.create(
+ self,
+ ampl,
+ br,
+ posi,
+ ueberl,
+ hint,
+ round(i*iterDim/threads),
+ round((i+1)*iterDim/threads)-1,
+ senkrecht,
+ fensterBreite,
+ maxBreite,
+ maxVerschiebung,
+ posiMitten
+ );
+
+ repeat
+ sleep(10);
+ fertig:=true;
+ for i:=0 to threads-1 do
+ fertig:=fertig and gauszFitThreads[i].fertig;
+ until fertig;
+
+ for i:=0 to threads-1 do
+ gauszFitThreads[i].free;
+
+ gibAus('... fertig '+timetostr(now-Zeit),3);
+ result:=true;
+end;
+
function tWerte.berechneZeitfrequenzanalyse(st: boolean; f: tMyStringlist; threads: longint; quelle: tWerte; Warn: tWarnstufe): boolean;
var
i,tmin,tmax,qlen: longint;
@@ -3003,7 +3210,7 @@ begin
continue;
end;
if startetMit('Richtung:',s) then begin
- if s='horizontal' then begin
+ if s='waagerecht' then begin
rtg:=irHorizontal;
continue;
end;
@@ -3792,15 +3999,15 @@ begin
params:=trim(params);
if startetMit('integriere ',params) then begin
- if startetMit('horizontal',params) then b1:=true
- else if startetMit('vertikal',params) then b1:=false
+ if startetMit('waagerecht',params) then b1:=true
+ else if startetMit('senkrecht',params) then b1:=false
else exit;
if st then begin
result:=true;
exit;
end;
- if b1 then s:='horizontal'
- else s:='vertikal';
+ if b1 then s:='waagerecht'
+ else s:='senkrecht';
gibAus('... schreibe in '''+params+''', integriere '+s,3);
if pos(' ',params)>0 then begin
@@ -4855,6 +5062,57 @@ begin
fertig:=true;
end;
+// tGauszFitThread *************************************************************
+
+constructor tGauszFitThread.create(daten,amplituden,breiten,positionen,ueberlappe,hintergruende: tWerte; von,bis: longint; senkrecht: boolean; fensterBreite,maxBreite,maxVerschiebung: extended; positionsMitten: tExtendedArray);
+begin
+ inherited create;
+ qu:=daten;
+ if assigned(amplituden) then
+ ampl:=@amplituden.eWerte
+ else
+ ampl:=nil;
+ if assigned(breiten) then
+ br:=@breiten.eWerte
+ else
+ br:=nil;
+ if assigned(positionen) then
+ posi:=@positionen.eWerte
+ else
+ posi:=nil;
+ if assigned(ueberlappe) then
+ ueberl:=@ueberlappe.eWerte
+ else
+ ueberl:=nil;
+ if assigned(hintergruende) then
+ hint:=@hintergruende.eWerte
+ else
+ hint:=nil;
+ vo:=von;
+ bi:=bis;
+ senkr:=senkrecht;
+ fenBr:=fensterBreite;
+ maxBr:=maxBreite;
+ maxVersch:=maxVerschiebung;
+ posiMitten:=positionsMitten;
+ gibAus('GaußFitThread kreiert: '+inttostr(von)+'-'+inttostr(bis),1);
+ suspended:=false;
+end;
+
+procedure tGauszFitThread.stExecute;
+begin
+ gibAus('GaußFitThread gestartet ...',1);
+ case qu.Genauigkeit of
+ gSingle:
+ qu.sWerte.gauszFit(ampl,br,posi,ueberl,hint,vo,bi,senkr,fenBr,maxBr,maxVersch,posiMitten);
+ gDouble:
+ qu.dWerte.gauszFit(ampl,br,posi,ueberl,hint,vo,bi,senkr,fenBr,maxBr,maxVersch,posiMitten);
+ gExtended:
+ qu.eWerte.gauszFit(ampl,br,posi,ueberl,hint,vo,bi,senkr,fenBr,maxBr,maxVersch,posiMitten);
+ end{of case};
+ gibAus('... und fertig',1);
+end;
+
// tKorrelThread ***************************************************************
constructor tKorrelThread.create(quelle,ziel: tWerte; xMin,xMax: longint; wavelet: tWavelet);
diff --git a/gauszFit.inc b/gauszFit.inc
new file mode 100644
index 0000000..e90392f
--- /dev/null
+++ b/gauszFit.inc
@@ -0,0 +1,17 @@
+{$IFDEF gauszFitBerechneWerte}
+ fehlers[nParams]:=0;
+ for ii:=0 to length(parameter[nParams,true])-1 do
+ parameter[nParams,true,ii]:=0;
+
+ for ii:=wiMin to wiMax do begin
+ t0:=ii-parameter[nParams,false,0];
+ t1:=exp( - sqr(t0 * parameter[nParams,false,1]) );
+ t2:=parameter[nParams,false,2] * t1;
+ t3:=werte[offset+qpSchritt*ii] - t2 - parameter[nParams,false,3];
+ fehlers[nParams]:=fehlers[nParams] + sqr(t3);
+ parameter[nParams,true,0]:=parameter[nParams,true,0] - t3 * t2 * 2 * t0 * sqr(parameter[nParams,false,1]);
+ parameter[nParams,true,1]:=parameter[nParams,true,1] + t3 * t2 * 2 * sqr(t0) * parameter[nParams,false,1];
+ parameter[nParams,true,2]:=parameter[nParams,true,2] - t3 * t1;
+ parameter[nParams,true,3]:=parameter[nParams,true,3] - t3;
+ end;
+{$ENDIF}
diff --git a/typenunit.pas b/typenunit.pas
index 5814925..6d24d16 100644
--- a/typenunit.pas
+++ b/typenunit.pas
@@ -397,6 +397,19 @@ type
// keine Änderung der Werte(skalierung)
function dumpParams: string; override;
end;
+ tFitTransformation = class(tKoordinatenTransformation)
+ private
+ _senkrecht: boolean;
+ _adLaenge: longint;
+ _adStao: tExtPoint;
+ public
+ constructor create(daten: tTransformation; senkrecht: boolean; adLaenge: longint; adStart,adStop: extended);
+ procedure aktualisiereXsTs; override;
+ procedure aktualisiereAchsen; override;
+ // keine Änderung der Werte(skalierung)
+ function wertZuPositionAufAchse(const l: tLage; x: extended): extended; override;
+ function dumpParams: string; override;
+ end;
tAgglomeration = class (tKoordinatenTransformation)
private
_nullposition: extended;
@@ -2059,6 +2072,59 @@ begin
result:='Koordinatenausschnitt: '+inttostr(gr['x','x'])+'..'+inttostr(gr['x','y'])+' x '+inttostr(gr['y','x'])+'..'+inttostr(gr['y','y']);
end;
+// tFitTransformation **********************************************************
+
+constructor tFitTransformation.create(daten: tTransformation; senkrecht: boolean; adLaenge: longint; adStart,adStop: extended);
+begin
+ inherited create;
+ wmiaExplizit:=true; // nicht sinnvoll berechenbar
+ _senkrecht:=senkrecht; // die Richtung, in der gefittet wurde ("andere Dimension") - also senkrecht zur übernommenen Ausdehnung
+ _adLaenge:=adLaenge; // Größe in der "anderen Dimension"
+ _adStao['x']:=adStart; // Start und
+ _adStao['y']:=adStop; // Stopp in der "anderen Dimension"
+ if (_adLaenge=1) xor (_adStao['x']=_adStao['y']) then
+ fehler('Die gefitteten Daten müssen genau dann eindimensional sein, wenn Start = Stopp ist. ('+inttostr(_adLaenge)+'-d vs. '+floattostr(_adStao['x'])+'..'+floattostr(_adStao['y'])+')');
+ fuegeVorgaengerHinzu(daten);
+end;
+
+procedure tFitTransformation.aktualisiereXsTs;
+var
+ c: char;
+begin
+ for c:='x' to 'y' do
+ out_xs_ts[c]:=_adLaenge+(in_xs_ts[c]-_adLaenge)*byte(_senkrecht xor (c='y'));
+end;
+
+procedure tFitTransformation.aktualisiereAchsen;
+var
+ c: char;
+begin
+ for c:='x' to 'y' do begin
+ out_achsen[char(ord('x')+byte(_senkrecht)),c]:=
+ in_achsen[char(ord('x')+byte(_senkrecht)),c];
+ out_achsen[char(ord('y')-byte(_senkrecht)),c]:=
+ _adStao[c];
+ end;
+end;
+
+function tFitTransformation.wertZuPositionAufAchse(const l: tLage; x: extended): extended;
+begin
+ if (l in [lOben,lUnten]) xor _senkrecht then
+ result:=0 // keine Ausdehnung in dieser Richtung!
+ else
+ result:=vorgaenger[0].wertZuPositionAufAchse(l,x);
+end;
+
+function tFitTransformation.dumpParams: string;
+begin
+ result:='FitTransformation: ';
+ if _senkrecht then
+ result:=result+'vertik'
+ else
+ result:=result+'horizont';
+ result:=result+'al';
+end;
+
// tAgglomeration **************************************************************
constructor tAgglomeration.create;
diff --git a/werteunit.pas b/werteunit.pas
index e35b54a..a643a7b 100644
--- a/werteunit.pas
+++ b/werteunit.pas
@@ -62,6 +62,7 @@ type
procedure integriereSingle(qu: pTLLWerteSingle; xmi,xma,tmi,tma,xof,tof: longint; richtung: tIntegrationsRichtung);
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);
end;
tLLWerteSingle = specialize tLLWerte<single>;
tLLWerteDouble = specialize tLLWerte<double>;
@@ -1254,6 +1255,184 @@ begin
end{of case};
end;
+procedure tLLWerte.gauszFit(amplituden,breiten,positionen,ueberlappe,hintergruende: pTLLWerteExtended; von,bis: longint; senkrecht: boolean; fensterBreite,maxBreite,maxVerschiebung: extended; positionsMitten: tExtendedArray);
+var
+ i,j,ii,zaehl, // Zähler
+ qpSchritt,qsSchritt, // Schrittlängen in der Quelle
+ zpSchritt,zdSchritt, // Schrittlängen im Ziel
+ pLen,offset, // Datenlänge und Offset in der Quelle
+ wiMin,wiMax, // momentane Fensterränder (für den Zählindex) in der Quelle
+ verbesserung, // <0: schlechter, 1: besser, 2: viel besser
+ aParams,nParams: longint; // Index der alten und neuen Parameter
+ parameter: array[0..1,boolean,0..3] of extended;
+ // dim0 nummeriert Parametersätze
+ // dim1: Ableitung (true) oder Werte (false)
+ // dim2: position, 1/breite, amplitude, hintergrund
+ fehlers: array[0..1] of extended;
+ t0,t1,t2,t3, // Zwischenergebnisse
+ qdrSumm, // Quadratesumme im betrachteten Fenster
+ pMi,pMa, // Achsenenden in Datenrichtung
+ schrittFaktor: extended;
+ ignBr,ignVersch: boolean; // Breite/Verschiebung am Anschlag!
+begin
+ if senkrecht then begin
+ qpSchritt:=params.xsteps; // Schritt in der Quelle parallel zur Fit-Richtung
+ qsSchritt:=1; // Schritt in der Quelle senkrecht zur Fit-Richtung
+ zpSchritt:=params.xsteps; // Schritt im Ziel in positionsMitten-Richtung
+ zdSchritt:=1; // Schritt im Ziel in Daten-Richtung (= senkrecht zur Fit-Richtung)
+ pMi:=params.tstart;
+ pMa:=params.tstop;
+ pLen:=params.tsiz;
+ end
+ else begin
+ qsSchritt:=params.xsteps;
+ qpSchritt:=1;
+ zdSchritt:=length(positionsMitten);
+ zpSchritt:=1;
+ pMi:=params.xstart;
+ pMa:=params.xstop;
+ pLen:=params.xsteps;
+ end;
+ maxBreite:=1/maxBreite;
+
+ for i:=von to bis do
+ for j:=0 to length(positionsMitten)-1 do begin
+ offset:=i*qsSchritt;
+ aParams:=0;
+
+ wiMin:=0;
+ wiMax:=pLen-1;
+ if fensterBreite>0 then begin
+ wiMin:=max(wiMin,round(positionsMitten[j] - fensterBreite / 2));
+ wiMax:=min(wiMax,round(positionsMitten[j] + fensterBreite / 2));
+ end;
+
+ qdrSumm:=0;
+ t0:=0;
+ t1:=0;
+ t2:=0;
+ schrittFaktor:=0;
+ for ii:=wiMin to wiMax do begin
+ t3:=werte[offset+qpSchritt*ii];
+ t3:=abs(t3);
+ qdrSumm:=qdrSumm + sqr(t3);
+ t0:=t0 + t3;
+ t1:=t1 + ii*t3;
+ t2:=t2 + sqr(ii)*t3;
+ if t3>schrittFaktor then schrittFaktor:=t3;
+ end;
+
+ t1:=t1/t0;
+ t2:=t2/t0;
+
+ parameter[aParams,false,0]:=t1; // Erwartungswert
+ parameter[aParams,false,2]:=schrittFaktor; // Maximalwert
+ parameter[aParams,false,1]:=parameter[aParams,false,2]/t0*sqrt(pi);
+// parameter[aParams,false,1]:=1/sqrt(2*(t2-sqr(t1))); // beinhalted Standardabweichung <-- schlechter!!
+ parameter[aParams,false,3]:=0;
+
+ if (maxBreite>=0) and (parameter[aParams,false,1]<2*maxBreite) then
+ parameter[aParams,false,1]:=maxBreite*2;
+
+ nParams:=aParams;
+ {$DEFINE gauszFitBerechneWerte}
+ {$I gauszFit.inc} // Werte + Gradienten berechnen
+ {$UNDEF}
+
+ schrittFaktor:=1;
+ if maxVerschiebung>=0 then
+ schrittFaktor:=min(schrittFaktor,maxVerschiebung/max(abs(parameter[nParams,true,0]),1e-50));
+ if maxBreite>=0 then
+ schrittFaktor:=min(schrittFaktor,abs(parameter[nParams,false,2]-maxBreite)/max(abs(parameter[nParams,true,1]),1e-50));
+
+ zaehl:=0;
+ repeat
+ nParams:=(aParams+1) mod length(parameter);
+ for ii:=0 to length(parameter[aParams,false])-1 do
+ parameter[nParams,false,ii]:=
+ parameter[aParams,false,ii] - schrittFaktor * parameter[aParams,true,ii]; // * byte(ii<3);
+
+ ignVersch:=false;
+ if maxVerschiebung>0 then begin
+ if parameter[nParams,false,0]-positionsMitten[j] > maxVerschiebung then begin
+ parameter[nParams,false,0]:=positionsMitten[j] + maxVerschiebung;
+ ignVersch:=true;
+ end;
+ if positionsMitten[j]-parameter[nParams,false,0] > maxVerschiebung then begin
+ parameter[nParams,false,0]:=positionsMitten[j] - maxVerschiebung;
+ ignVersch:=true;
+ end;
+ end;
+
+ ignBr:=false;
+ if maxBreite>0 then
+ if parameter[nParams,false,1] < maxBreite then begin
+ parameter[nParams,false,1]:=maxBreite;
+ ignBr:=true;
+ end;
+
+ {$DEFINE gauszFitBerechneWerte}
+ {$I gauszFit.inc} // Werte + Gradienten berechnen
+ {$UNDEF}
+
+ if fehlers[aParams]>2*fehlers[nParams] then begin
+ verbesserung:=2;
+ schrittFaktor:=schrittFaktor * 2;
+ aParams:=nParams;
+ end
+ else if fehlers[aParams]>fehlers[nParams] then begin
+ verbesserung:=1;
+ schrittFaktor:=schrittFaktor * 1.3;
+ aParams:=nParams;
+ end
+ else begin
+ if verbesserung>0 then
+ verbesserung:=-1
+ else
+ dec(verbesserung);
+ schrittFaktor:=schrittFaktor * 0.5;
+ end;
+
+ if schrittFaktor<1e-50 then
+ fehler('Sehr kleiner Schrittfaktor ('+floattostr(schrittFaktor)+') beim Fitten!');
+
+ inc(zaehl);
+ {$IFDEF gauszFitStatus}
+ if (zaehl mod 10000)=0 then
+ gibAus(
+ floattostr(fehlers[aParams])+' '+
+ floattostr(qdrSumm)+' '+
+ inttostr(byte((verbesserung<-10) or (fehlers[aParams]*100<qdrSumm)))+' '+
+ inttostr(byte(ignVersch or (abs(schrittFaktor*parameter[aParams,true,0])<1)))+' '+
+ inttostr(byte(ignBr or (abs(schrittFaktor*parameter[aParams,true,1]/parameter[aParams,false,1])<0.01)))+' '+
+ inttostr(byte(abs(schrittFaktor*parameter[aParams,true,2]/parameter[aParams,false,2])<0.01))+' '+
+ inttostr(byte(abs(schrittFaktor*parameter[aParams,true,3]/max(abs(parameter[aParams,false,3]),1e-10))<0.01))+' '+
+ inttostr(verbesserung),
+ 3);
+ {$ENDIF}
+
+ until ((zaehl>=100000) or (verbesserung<-10) or (fehlers[aParams]*10<qdrSumm)) and
+ (ignVersch or (abs(schrittFaktor*parameter[aParams,true,0])<1)) and
+ (ignBr or (abs(schrittFaktor*parameter[aParams,true,1]/parameter[aParams,false,1])<0.01)) and
+ (abs(schrittFaktor*parameter[aParams,true,2]/parameter[aParams,false,2])<0.01) and
+ (abs(schrittFaktor*parameter[aParams,true,3]/max(abs(parameter[aParams,false,3]),1e-10))<0.01);
+ {$IFDEF gauszFitStatus}
+ gibAus('',3);
+ {$ENDIF}
+
+ if assigned(positionen) then
+ positionen^.werte[j*zpSchritt + i*zdSchritt]:=pMi+(pMa-pMi)/(pLen-1)*parameter[aParams,false,0];
+ if assigned(breiten) then
+ breiten^.werte[j*zpSchritt + i*zdSchritt]:=(pMa-pMi)/(pLen-1)/parameter[aParams,false,1];
+ if assigned(amplituden) then
+ amplituden^.werte[j*zpSchritt + i*zdSchritt]:=parameter[aParams,false,2];
+ if assigned(hintergruende) then
+ hintergruende^.werte[j*zpSchritt + i*zdSchritt]:=parameter[aParams,false,3];
+ if assigned(ueberlappe) then
+ ueberlappe^.werte[j*zpSchritt + i*zdSchritt]:=fehlers[aParams]/qdrSumm;
+ end;
+end;
+
// tWavelet ********************************************************************
function tWavelet.setzeTyp(s: string): boolean;