summaryrefslogtreecommitdiff
path: root/epostunit.pas
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2017-08-07 10:31:23 +0200
committerErich Eckner <git@eckner.net>2017-08-07 10:31:23 +0200
commit097ae86b2bce4c189bb9f38c3738e8572aaa429b (patch)
tree58a2d479d23958aaef5afb2df5392d787631f9e0 /epostunit.pas
parent2960a3b69a1ea80e32690a26a4e5655d588d1136 (diff)
downloadepost-097ae86b2bce4c189bb9f38c3738e8572aaa429b.tar.xz
macheKomplex und istKomplex neu
Diffstat (limited to 'epostunit.pas')
-rw-r--r--epostunit.pas203
1 files changed, 164 insertions, 39 deletions
diff --git a/epostunit.pas b/epostunit.pas
index ed65ab1..c393734 100644
--- a/epostunit.pas
+++ b/epostunit.pas
@@ -5,7 +5,8 @@ unit epostunit;
interface
uses
- classes, sysutils, mystringlistunit, werteunit, typenunit, process, lowlevelunit, matheunit, fftunit;
+ classes, sysutils, mystringlistunit, werteunit, typenunit, process, lowlevelunit,
+ matheunit, fftunit, randomunit;
type
tBmpHeader = packed record
@@ -117,6 +118,7 @@ type
procedure wMinW(miW: extended);
function rMaxW: extended;
procedure wMaxW(maW: extended);
+ function istKomplex: boolean;
function xScale: extended;
function tScale: extended;
function dichtenParameterErkannt(sT: boolean; s: string; var bekannteBefehle: tMyStringList; threads,xMin,xMax,tMin,tMax: longint): boolean;
@@ -159,6 +161,7 @@ type
function entferneArtefakte(sT: boolean; f: tMyStringList; threads: longint): boolean;
function extrahiereEinhuellende(sT: boolean; f: tMyStringList; threads: longint; Warn: tWarnstufe): boolean;
function extrahierePhase(sT: boolean; f: tMyStringList; threads: longint; Warn: tWarnstufe): boolean;
+ function macheKomplex(sT: boolean; f: tMyStringList; threads: longint): 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;
@@ -169,7 +172,7 @@ type
procedure spiegle(threads: longint); overload;
procedure spiegle(threads,tMin,tMax: longint); overload;
procedure fuelleMitDummys(sT: boolean);
- procedure verschiebe(threads: longint; richtung: tIntPoint; komplex: boolean);
+ procedure verschiebe(threads: longint; richtung: tIntPoint);
procedure ermittlePhasenWinkel(threads: longint);
procedure fft2dNachbearbeitung(threads: longint; nB: tFFTDatenordnung);
procedure schreibeWert(var f: textfile; x,y: longint);
@@ -245,16 +248,17 @@ type
nummer,mT,breite,wBreite,hoehe,
wHoehe,gesBreite,lOf,oOf,rOf,uOf: longint;
ws: tWerteArray;
- xMi,xMa,tMi,tMa,xPMi,xPMa,komplex: longint;
+ xMi,xMa,tMi,tMa,xPMi,xPMa: longint;
xZ,yZ: extended;
nbs: tTransformationArray;
farben: tRGBArray;
+ istKomplex: array of boolean;
wertes: array of tExtendedArray;
anzahlens: array of tLongintArray;
pals: array of tPalette;
rahmen: boolean;
beschr: pTBeschriftungen;
- constructor create(i,maxThreads,iBreite,iHoehe,lO,oO,rO,uO: longint; const wes: tWerteArray; xMin,xMax,tMin,tMax,kmpl: longint; xZoom,yZoom: extended; nachbearbeitungen: tTransformationArray; paletten: tPalettenArray; beschri: pTBeschriftungen; rm: boolean);
+ constructor create(i,maxThreads,iBreite,iHoehe,lO,oO,rO,uO: longint; const wes: tWerteArray; xMin,xMax,tMin,tMax: longint; xZoom,yZoom: extended; nachbearbeitungen: tTransformationArray; paletten: tPalettenArray; beschri: pTBeschriftungen; rm: boolean);
destructor destroy; override;
procedure stExecute; override;
procedure initAnzahlensFuerKontur;
@@ -389,8 +393,7 @@ type
we: tWerte;
xMi,xMa,tMi,tMa: longint;
rtg: tIntPoint;
- kmpl: boolean;
- constructor create(werte: tWerte; xMin,xMax,tMin,tMax: longint; richtung: tIntPoint; komplex: boolean);
+ constructor create(werte: tWerte; xMin,xMax,tMin,tMax: longint; richtung: tIntPoint);
procedure stExecute; override;
end;
tPhasenWinkelThread = class(tLogThread)
@@ -399,6 +402,14 @@ type
constructor create(werte: tWerte; xMin,xMax: longint);
procedure stExecute; override;
end;
+ tKomplexMachThread = class(tLogThread)
+ we: tWerte;
+ xMi,xMa: longint;
+ kmm: tKomplexMachModus;
+ mT: tMersenneTwister;
+ constructor create(werte: tWerte; xMin,xMax: longint; komplexMachModus: tKomplexMachModus; randomSeed: longword);
+ procedure stExecute; override;
+ end;
function neuePalette(f: tMyStringList): boolean;
function initBmpHeader(w,h: longint): tBmpHeader;
@@ -933,6 +944,18 @@ begin
end{of case};
end;
+function tWerte.istKomplex: boolean;
+begin
+ case genauigkeit of
+ gSingle:
+ result:=sWerte.params.istKomplex;
+ gDouble:
+ result:=dWerte.params.istKomplex;
+ gExtended:
+ result:=eWerte.params.istKomplex;
+ end{of case};
+end;
+
function tWerte.findeAlleDateien(nam: string; var dat: tGenerischeInputDateiInfoArray; vorlage: tGenerischeInputDateiInfo): boolean;
var
err: longint;
@@ -3921,7 +3944,7 @@ begin
betraege.free;
gibAus('zentrieren '+tIntPointToStr(maxPos),3);
- verschiebe(threads,maxPos,true);
+ verschiebe(threads,maxPos);
gibAus('berechne inverse x-FFT ...',3);
if not fft(threads,false,true,doAlleResIms,doAlleResIms,nil,0,pvFehler,wsLasch) then begin
@@ -3943,6 +3966,80 @@ begin
result:=true;
end;
+function tWerte.macheKomplex(sT: boolean; f: tMyStringList; threads: longint): boolean;
+var
+ bekannteBefehle: tMyStringList;
+ komplexMachModus: tKomplexMachModus;
+ kmThreads: array of tKomplexMachThread;
+ s: string;
+ i: longint;
+ fertig: boolean;
+begin
+ result:=false;
+ if istKomplex then begin
+ gibAus('Werte '''+bezeichner+''' sind bereits komplex!',3);
+ exit;
+ end;
+
+ komplexMachModus:=kmmImNull;
+
+ bekannteBefehle:=tMyStringList.create;
+ repeat
+ if not f.metaReadln(s,true) then begin
+ gibAus('Unerwartetes Dateiende!',3);
+ exit;
+ end;
+ bekannteBefehle.clear;
+ if istDasBefehl('Ende',s,bekannteBefehle,false) then break;
+ if istDasBefehl('rein reell',s,bekannteBefehle,false) then begin
+ komplexMachModus:=kmmImNull;
+ continue;
+ end;
+ if istDasBefehl('rein imaginär',s,bekannteBefehle,false) then begin
+ komplexMachModus:=kmmReNull;
+ continue;
+ end;
+ if istDasBefehl('zufällige Phase',s,bekannteBefehle,false) then begin
+ komplexMachModus:=kmmPhZuf;
+ continue;
+ end;
+ bekannteBefehle.sort;
+ gibAus('Verstehe Option '''+s+''' nicht beim Komplexmachen!'#10'Ich kenne:'#10+bekannteBefehle.text,3);
+ bekannteBefehle.free;
+ exit;
+ until false;
+
+ _tSiz:=_tSiz*2;
+ if sT then begin
+ result:=true;
+ exit;
+ end;
+
+ holeRAM(3);
+
+ setLength(kmThreads,threads);
+ for i:=0 to length(kmThreads)-1 do
+ kmThreads[i]:=tKomplexMachThread.create(
+ self,
+ round(i/threads*(_tSiz div 2)),
+ round((i+1)/threads*(_tSiz div 2))-1,
+ komplexMachModus,
+ random(high(longword))
+ );
+
+ repeat
+ fertig:=true;
+ for i:=0 to length(kmThreads)-1 do
+ fertig:=fertig and kmThreads[i].fertig;
+ if not fertig then sleep(10);
+ until fertig;
+
+ for i:=0 to length(kmThreads)-1 do
+ kmThreads[i].free;
+
+ result:=true;
+end;
+
function tWerte.berechneIntegral(sT: boolean; f: tMyStringList; threads: longint; quelle: tWerte): boolean;
var
i,tMin,tMax,xMin,xMax: longint;
@@ -4238,7 +4335,7 @@ var
nachbearbeitungen: tTransformationArray;
Ausschnitt: tTransformation;
bilderThreads: array of tBilderThread;
- fertig,rahmen,komplex: boolean;
+ fertig,rahmen: boolean;
img: file;
achsen: array of tAchse;
fontRenderer: tFontRenderer;
@@ -4302,7 +4399,6 @@ begin
Ausschnitt:=nil;
rahmen:=false;
fontRenderer:=nil;
- komplex:=false;
bekannteBefehle:=tMyStringList.create;
repeat
if not f.metaReadln(s,true) then begin
@@ -4369,10 +4465,6 @@ begin
rahmen:=true;
continue;
end;
- if istDasBefehl('komplex',s,bekannteBefehle,false) then begin
- komplex:=true;
- continue;
- end;
if istDasBefehl('Nachbearbeitung:',s,bekannteBefehle,true) then begin
if s[1] in ['0'..'9'] then
i:=strtoint(erstesArgument(s))
@@ -4393,7 +4485,7 @@ begin
continue;
end;
if istDasBefehl('Legende:',s,bekannteBefehle,true) then begin
- if komplex then begin
+ if istKomplex then begin
gibAus('Ich kann keine Legende zu komplexen Werten erstellen!',3);
aufraeumen;
exit;
@@ -4519,7 +4611,7 @@ begin
xMin:=max(xMin,0);
xMax:=min(xMax,_xSteps-1);
tMin:=max(tMin,0);
- tMax:=min(tMax,_tSiz div (1+byte(komplex))-1);
+ tMax:=min(tMax,_tSiz div (1+byte(istKomplex))-1);
gibAus('('+intToStr(xMin)+'-'+intToStr(xMax)+'x'+intToStr(tMin)+'-'+intToStr(tMax)+')',3);
gibAus(' ('+floatToStr(transformationen.xStart)+'-'+floatToStr(transformationen.xStop)+' x '+floatToStr(transformationen.tStart)+'-'+floatToStr(transformationen.tStop)+')',3);
breite:=round((xMax-xMin+1)*xZoom);
@@ -4595,7 +4687,7 @@ begin
setLength(bilderThreads,maxThreads);
for i:=0 to length(bilderThreads)-1 do
- bilderThreads[i]:=tBilderThread.create(i,length(bilderThreads),breite,hoehe,lOf,oOf,rOf,uOf,quellen,xMin,xMax,tMin,tMax,byte(komplex)*_tSiz div 2,xZoom,yZoom,nachbearbeitungen,paletten,@beschriftungen,rahmen);
+ bilderThreads[i]:=tBilderThread.create(i,length(bilderThreads),breite,hoehe,lOf,oOf,rOf,uOf,quellen,xMin,xMax,tMin,tMax,xZoom,yZoom,nachbearbeitungen,paletten,@beschriftungen,rahmen);
for i:=0 to length(bilderThreads)-1 do begin
gibAus('starte Thread '+intToStr(i)+' ...',1);
bilderThreads[i].suspended:=false;
@@ -5014,7 +5106,7 @@ begin
end;
end;
-procedure tWerte.verschiebe(threads: longint; richtung: tIntPoint; komplex: boolean);
+procedure tWerte.verschiebe(threads: longint; richtung: tIntPoint);
var
einheitsZelle: tIntPoint;
teilRichtung: char;
@@ -5022,7 +5114,7 @@ var
i: longint;
fertig: boolean;
begin
- einheitsZelle:=berechneEinheitsZelle(richtung,intPoint(_xSteps,_tSiz div (1+byte(komplex))));
+ einheitsZelle:=berechneEinheitsZelle(richtung,intPoint(_xSteps,_tSiz div (1+byte(istKomplex))));
teilRichtung:=char(ord('x')+byte(einheitsZelle['y']>einheitsZelle['x']));
if einheitsZelle[teilRichtung]<threads then
@@ -5038,8 +5130,7 @@ begin
round((i+1)/threads*einheitsZelle['x']-1),
0,
einheitsZelle['y']-1,
- richtung,
- komplex
+ richtung
)
else
verschiebeThreads[i]:=
@@ -5049,8 +5140,7 @@ begin
einheitsZelle['x']-1,
round(i/threads*einheitsZelle['y']),
round((i+1)/threads*einheitsZelle['y']-1),
- richtung,
- komplex
+ richtung
);
repeat
sleep(10);
@@ -5681,9 +5771,9 @@ end;
// tBilderThread ***************************************************************
-constructor tBilderThread.create(i,maxThreads,iBreite,iHoehe,lO,oO,rO,uO: longint; const wes: tWerteArray; xMin,xMax,tMin,tMax,kmpl: longint; xZoom,yZoom: extended; nachbearbeitungen: tTransformationArray; paletten: tPalettenArray; beschri: pTBeschriftungen; rm: boolean);
+constructor tBilderThread.create(i,maxThreads,iBreite,iHoehe,lO,oO,rO,uO: longint; const wes: tWerteArray; xMin,xMax,tMin,tMax: longint; xZoom,yZoom: extended; nachbearbeitungen: tTransformationArray; paletten: tPalettenArray; beschri: pTBeschriftungen; rm: boolean);
var
- ii: longint;
+ ii,anzKompl: longint;
begin
inherited create;
beschr:=beschri;
@@ -5707,7 +5797,6 @@ begin
for ii:=0 to length(pals)-1 do
pals[ii]:=paletten[ii];
rahmen:=rm;
- komplex:=kmpl;
xPMi:=nummer*((gesBreite+lOf+rOf) div mT)-lOf;
if nummer=mT-1 then xPMa:=gesBreite+rOf-1 // der letzte Thread bekommt den Rest
else xPMa:=(nummer+1)*((gesBreite+lOf+rOf) div mT)-lOf-1;
@@ -5717,14 +5806,19 @@ begin
// breite:=wBreite+lOf*byte(nummer=0)+rOf*byte(nummer=mT-1);
hoehe:=oOf+wHoehe+uOf;
gibAus('Werte: '+intToStr(xMi)+'-'+intToStr(xMa)+'x'+intToStr(tMi)+'-'+intToStr(tMa)+' ('+intToStr(wBreite)+'), Pixel: '+intToStr(xPMi)+'-'+intToStr(xPMa)+' ('+intToStr(breite)+')',1);
+ anzKompl:=0;
+ for ii:=0 to length(wes)-1 do
+ anzKompl:=anzKompl+1+byte(wes[ii].istKomplex);
gibAus('Thread '+intToStr(nummer)+': hole '
- +intToStr(round(((sizeOf(extended)+sizeOf(longint))*length(wes)*(1+byte(komplex))*wHoehe*wBreite+
+ +intToStr(round(((sizeOf(extended)+sizeOf(longint))*anzKompl*wHoehe*wBreite+
sizeOf(tRGB)*hoehe*breite)/1024/1024))+'MB RAM ...',1);
+ setLength(istKomplex,length(wes));
setLength(wertes,length(wes));
setLength(anzahlens,length(wes));
for ii:=0 to length(wertes)-1 do begin
+ istKomplex[ii]:=wes[ii].istKomplex;
setLength(anzahlens[ii],wHoehe*wBreite);
- setLength(wertes[ii],(1+byte(komplex>0))*length(anzahlens[ii]));
+ setLength(wertes[ii],(1+byte(wes[ii].istKomplex))*length(anzahlens[ii]));
end;
setLength(farben,hoehe*breite);
gibAus('Thread '+intToStr(nummer)+' hat jetzt seinen Speicher.',1);
@@ -5747,6 +5841,7 @@ end;
procedure tBilderThread.stExecute;
var
i,j,k: longint;
+ hLen: int64;
wert: extended;
b: boolean;
frb: tRGB;
@@ -5754,9 +5849,9 @@ begin
gibAus('Thread '+intToStr(nummer)+' gestartet!',1);
for i:=0 to length(ws)-1 do
case ws[i].genauigkeit of
- gSingle: if not ws[i].sWerte.zuPixelWerten(wHoehe,wBreite,xPMi,xMi,tMi,komplex,xZ,yZ,@wertes[i],@anzahlens[i]) then exit;
- gDouble: if not ws[i].dWerte.zuPixelWerten(wHoehe,wBreite,xPMi,xMi,tMi,komplex,xZ,yZ,@wertes[i],@anzahlens[i]) then exit;
- gExtended: if not ws[i].eWerte.zuPixelWerten(wHoehe,wBreite,xPMi,xMi,tMi,komplex,xZ,yZ,@wertes[i],@anzahlens[i]) then exit;
+ gSingle: if not ws[i].sWerte.zuPixelWerten(wHoehe,wBreite,xPMi,xMi,tMi,xZ,yZ,@wertes[i],@anzahlens[i]) then exit;
+ gDouble: if not ws[i].dWerte.zuPixelWerten(wHoehe,wBreite,xPMi,xMi,tMi,xZ,yZ,@wertes[i],@anzahlens[i]) then exit;
+ gExtended: if not ws[i].eWerte.zuPixelWerten(wHoehe,wBreite,xPMi,xMi,tMi,xZ,yZ,@wertes[i],@anzahlens[i]) then exit;
end{of case};
for i:=0 to length(wertes)-1 do
for j:=0 to length(anzahlens[i])-1 do
@@ -5771,9 +5866,10 @@ begin
farben[i-xPMi+(j+oOf)*breite].rgbRed:=0;
farben[i-xPMi+(j+oOf)*breite].rgbGreen:=0;
farben[i-xPMi+(j+oOf)*breite].rgbBlue:=0;
- for k:=0 to length(wertes)-1 do
- for b:=false to komplex>0 do begin
- wert:=(wertes[k,i-max(0,xPMi)+(j+byte(b)*komplex)*wBreite]/anzahlens[k,i-max(0,xPMi)+j*wBreite]-ws[k]._minW)/(ws[k]._maxW-ws[k]._minW);
+ for k:=0 to length(wertes)-1 do begin
+ hLen:=length(wertes[k]) div 2;
+ for b:=false to istKomplex[k] do begin
+ wert:=(wertes[k,i-max(0,xPMi)+(j+byte(b and istKomplex[k])*hLen)*wBreite]/anzahlens[k,i-max(0,xPMi)+j*wBreite]-ws[k]._minW)/(ws[k]._maxW-ws[k]._minW);
wert:=max(0,min(wert,1));
wert:=nbs[k].transformiereWert(wert);
frb:=pals[k].wertZuFarbe(wert,b);
@@ -5783,6 +5879,7 @@ begin
rgbBlue:= rgbBlue + frb.rgbBlue;
end;
end;
+ end;
end
else begin
farben[i-xPMi+(j+oOf)*breite].rgbRed:=
@@ -7147,7 +7244,7 @@ end;
// tVerschiebeThread ***********************************************************
-constructor tVerschiebeThread.create(werte: tWerte; xMin,xMax,tMin,tMax: longint; richtung: tIntPoint; komplex: boolean);
+constructor tVerschiebeThread.create(werte: tWerte; xMin,xMax,tMin,tMax: longint; richtung: tIntPoint);
begin
inherited create;
we:=werte;
@@ -7156,8 +7253,7 @@ begin
tMi:=tMin;
tMa:=tMax;
rtg:=richtung;
- kmpl:=komplex;
- gibAus('VerschiebeThread erzeugt: '+intToStr(xMin)+'-'+intToStr(xMax)+' '+intToStr(tMin)+'-'+intToStr(tMax)+' '+tIntPointToStr(richtung)+' '+intToStr(byte(komplex)),1);
+ gibAus('VerschiebeThread erzeugt: '+intToStr(xMin)+'-'+intToStr(xMax)+' '+intToStr(tMin)+'-'+intToStr(tMax)+' '+tIntPointToStr(richtung)+' '+intToStr(byte(we.istKomplex)),1);
suspended:=false;
end;
@@ -7166,11 +7262,11 @@ begin
gibAus('VerschiebeThread gestartet',1);
case we.genauigkeit of
gSingle:
- we.sWerte.verschiebe(rtg,xMi,xMa,tMi,tMa,kmpl);
+ we.sWerte.verschiebe(rtg,xMi,xMa,tMi,tMa);
gDouble:
- we.dWerte.verschiebe(rtg,xMi,xMa,tMi,tMa,kmpl);
+ we.dWerte.verschiebe(rtg,xMi,xMa,tMi,tMa);
gExtended:
- we.eWerte.verschiebe(rtg,xMi,xMa,tMi,tMa,kmpl);
+ we.eWerte.verschiebe(rtg,xMi,xMa,tMi,tMa);
end{of case};
gibAus('VerschiebeThread beendet',1);
end;
@@ -7201,6 +7297,35 @@ begin
gibAus('PhasenWinkelThread beendet',1);
end;
+// tKomplexMachThread **********************************************************
+
+constructor tKomplexMachThread.create(werte: tWerte; xMin,xMax: longint; komplexMachModus: tKomplexMachModus; randomSeed: longword);
+begin
+ inherited create;
+ we:=werte;
+ xMi:=xMin;
+ xMa:=xMax;
+ kmm:=komplexMachModus;
+ mT:=tMersenneTwister.create;
+ mT.init(randomSeed);
+ gibAus('KomplexMachThread erzeugt: '+intToStr(xMin)+'-'+intToStr(xMax),1);
+ suspended:=false;
+end;
+
+procedure tKomplexMachThread.stExecute;
+begin
+ gibAus('KomplexMachThread gestartet',1);
+ case we.genauigkeit of
+ gSingle:
+ we.sWerte.macheKomplex(xMi,xMa,kmm,mT);
+ gDouble:
+ we.dWerte.macheKomplex(xMi,xMa,kmm,mT);
+ gExtended:
+ we.eWerte.macheKomplex(xMi,xMa,kmm,mT);
+ end{of case};
+ gibAus('KomplexMachThread beendet',1);
+end;
+
// sonstiges *******************************************************************
function findePalette(out palette: tPalette; name: string): boolean;