D
.filmor schrieb:
Sicher, dass das so genauer ist? Wurzeln werden im Rechner ja auch nur mit Newton- bzw. Heronverfahren gelöst, oder irre ich mich?
Dann wäre ein direktes Newtonverfahren doch vermutlich besser weil keine Hintereinanderschaltung…
So, ich hab mal einen Test programmiert:
//Das ist mit Näherungsverfahren
//1 Mio mal berechnen!
int Count=1000000;
int ImgW,ImgH;
double RMax,D,ROrgMax,R,RO,RU,ROrg,V;
double B=0.2;
D=1.0 - B;
//vorhandenes Kissen entzerren
ImgW=2288;
ImgH=1712;
while (Count>0)
{
RMax=double(max(ImgW,ImgH)) / double(min(ImgW,ImgH));
RO=RMax;
RU=0;
R=RO;
ROrg=(B * R * R + D) * R;
while (fabs(ROrg - RMax)>0.0001)
// while (fabs(ROrg - RMax)>0.0000000000001)
{ if (ROrg>RMax)
{ RO=R;
R=(R + RU) / 2.0;
}
else
{ RU=R;
R=(R + RO) / 2.0;
}
ROrg=(B * R * R + D) * R;
}
V=R / RMax;
Count--;
}
//Das ist mit "direkter" Berechnung
//1 Mio mal berechnen!
int Count=1000000;
int ImgW,ImgH;
double RMax,D,ROrgMax,R,RO,RU,ROrg,V;
double Det,SqrtDet,Det1,Det2;
double B=0.2;
D=1.0 - B;
//vorhandenes Kissen entzerren
ImgW=2288;
ImgH=1712;
while (Count>0)
{
RMax=double(max(ImgW,ImgH)) / double(min(ImgW,ImgH));
Det=(RMax * RMax) / (4 * B * B) + (D * D * D) / (27 * B * B * B);
if (Det>0)
{
SqrtDet=sqrt(Det);
Det1=RMax / (2 * B) + SqrtDet;
Det2=RMax / (2 * B) - SqrtDet;
if (Det1>0)
{ Det1=pow(Det1,(1.0 / 3.0));
}
else
{ Det1=-pow(-Det1,(1.0 / 3.0));
}
if (Det2>0)
{ Det2=pow(Det2,(1.0 / 3.0));
}
else
{ Det2=-pow(-Det2,(1.0 / 3.0));
}
R=Det1 + Det2;
V=R / RMax;
}
else
{ break;
}
Count--;
}
Ergebnis:
1. Genauigkeit kann (fast) gleich sein.
(wird Tolleranzschwelle bei "Suche" minimal gemacht, ist Ergebnis
bis auf 15.te Stelle gleich)
2. "Annäherung" ist bei maximaler Genauigkeit halb so schnell
3. "Annäherung" ist bei Genauigkeit ca. 5 Stelle doppelt so schnell
Fazit:
- Für hochgenaue Berechnungen ist direkter Weg besser (schneller)
- Für begrenzte Genauigkeit ist Annäherung besser (schneller aber "ungenau")
Hinweis:
- getestet auf Borland BCB
- Datentypen alle double !!!
beide Teile können sicher noch optimiert werden!
Gruss und Dank
Frank