#include #include "biglagrange.h" #define EXTRA 5 #define SAMPLE 3 // G(t) = (1-cos(t))*(1-z*cos(t))^(-3/2), where z = 1 - e^^-y and y is context BigFloat G(const BigFloat& t, void* context) { BigFloat z(*(BigFloat*)context); z.Negate().Exp().Negate().Add(1); BigFloat b(t); b.Cos(); BigFloat numerator(1); // The next line makes the numerator 1-cos, comment out the next line and the numerator is just 1. // numerator.Sub(b); b.Mult(z).Negate().Add(1); BigFloat denominator(b); denominator.Mult(b).Mult(b).Sqrt(); numerator.Div(denominator); return numerator; } // F(x) = f(y), where x = -ln(1-y) and f(y) = integral t=0..2pi of (1/2pi)*(1-cos(t))*(1-y*cos(t))^(-3/2) dt BigFloat F(const BigFloat& x, void* context) { BigFloat start(0); BigFloat finish(BigFloat::Pi()); s8 nTerms = 30; const int minLogPieces = 5; const int maxLogPieces = 63; int logPieces = minLogPieces; BigFloat range(finish); range.Sub(start).Div(1< 0 && logPieces > minLogPieces) { BigFloat newSubFinish(subFinish); newSubFinish.Add(range); if (newSubFinish.Compare(finish) <= 0) { logPieces--; subFinish.Copy(newSubFinish); range.Mult(2); continue; } } else if (biggestFirst.CompareAbsolute(biggestLast) < 0 && logPieces < maxLogPieces) { logPieces++; range.Div(2); subFinish.Copy(subStart); subFinish.Add(range); continue; } else if (t.Compare(finish) > 0) { lastPiece = true; range.Copy(finish); range.Sub(subStart); subFinish.Copy(finish); continue; } break; } // integrate this piece for (int j=c.Length(); j-- > 0;) { BigFloat x(c.At(j)); x.Mult(range).Div(2).Div(j+1); c.SetAt(j+1, x); } c.SetAt(0, BigFloat(0)); // divide by 2pi c.Mult(BigFloat(2).Mult(BigFloat::Pi()).Invert()); BigFloat coef(c.Eval(BigFloat(-1))); coef.Negate(); BigFloat coef2(c.Eval(BigFloat(1))); startCoef.Add(coef); startCoef.Add(coef2); subStart.Copy(subFinish); } // evaluate the integral at 2pi (it will be twice its value at pi) BigFloat r(startCoef); // result r.Mult(2); return r; } int main(int argc, char** argv) { const char* name = "Th1"; static const int f = 40; // finish static const int maxTerms = 20; BigFloat start(0); BigFloat finish(f); s8 nPieces[f]; // number of pieces for each power of e nPieces[0] = 16; nPieces[1] = 8; nPieces[2] = 4; nPieces[3] = 4; for (int i=4; i\n"); printf("static double **coef%s[%d];\n", name, f); printf("static double allCoef%s[] = {\n", name); for (int iInt=0; iInt= finish%s)\n", name); printf(" return nan(\"\");\n"); printf(" int iInt = static_cast(x);\n"); printf(" x -= iInt;\n\n"); printf(" // The 0.5 adjusts the range to [-0.5,0.5) instead of [0,1), so c[0] is the middle value.\n"); printf(" // The number of pieces per int was adjusted manually.\n"); printf(" x *= nPieces%s[iInt];\n", name); printf(" int iPiece = static_cast(x);\n"); printf(" x = x - iPiece - 0.5;\n\n"); printf(" // start with the tiny terms and build up, to avoid rounding errors\n"); printf(" double *c = coef%s[iInt][iPiece];\n", name); printf(" int iTerm = nTerms%s[iInt][iPiece]-1;\n", name); printf(" double y = c[iTerm];\n"); printf(" while (iTerm--)\n"); printf(" y = y * x + c[iTerm];\n"); printf(" return y;\n"); printf("}\n"); printf("\n"); printf("#ifdef TESTFUNC\n"); printf("#include \n"); printf("#include \"bigFloat.h\"\n"); printf("int main(int argc, char** argv)\n"); printf("{\n"); printf(" double iterations = 137;\n"); printf(" for (int i=0; i %%.18g\\n\", x, z);\n"); printf(" }\n"); printf("}\n"); printf("#endif /* TESTFUNC */\n"); return 0; }