|
7 | 7 | namespace ErrorFunctionApproximation { |
8 | 8 | class Program { |
9 | 9 | static void Main(string[] args) { |
10 | | - MultiPrecision<Pow2.N32>[] xs = new MultiPrecision<Pow2.N32>[]{ |
11 | | - 1, 2, 4, 8, 16, 32 |
12 | | - }; |
| 10 | + MultiPrecision<Pow2.N32> dx = 1d / 1024; |
13 | 11 |
|
14 | | - static MultiPrecision<Pow2.N32> f32(MultiPrecision<Pow2.N32> x) { |
15 | | - return MultiPrecision<Pow2.N32>.InverseErfc(MultiPrecision<Pow2.N32>.Pow2(-x * x)); |
16 | | - }; |
| 12 | + using StreamWriter sw = new("../../../../results/series_inverf_e20.txt"); |
| 13 | + sw.WriteLine("pade approximant f(x^2) f(x):=inverf(x)/x"); |
17 | 14 |
|
18 | | - static MultiPrecision<Pow2.N64> f64(MultiPrecision<Pow2.N64> x) { |
19 | | - return MultiPrecision<Pow2.N64>.InverseErfc(MultiPrecision<Pow2.N64>.Pow2(-x * x)); |
20 | | - }; |
| 15 | + MultiPrecision<Pow2.N32> x0 = 0, x1 = 0.5; |
21 | 16 |
|
22 | | - using StreamWriter sw = new("../../../../results/pade_inverfc_e16.txt"); |
23 | | - sw.WriteLine("pade approximant inverse_erfc(2^(-x^2))"); |
| 17 | + sw.WriteLine($"\nrange x in [{x0}, {x1}]"); |
24 | 18 |
|
25 | | - for (int j = 0; j < xs.Length - 1; j++) { |
26 | | - MultiPrecision<Pow2.N32> x0 = xs[j], x1 = xs[j + 1]; |
27 | | - MultiPrecision<Pow2.N32> dx = (x1 - x0) / 2048; |
| 19 | + MultiPrecision<Pow2.N32> c = MultiPrecision<Pow2.N32>.Sqrt(MultiPrecision<Pow2.N32>.PI) / 2; |
28 | 20 |
|
29 | | - sw.WriteLine($"\nrange x in [{x0}, {x1}]"); |
30 | | - |
31 | | - //sw.WriteLine("expected"); |
32 | | - List<MultiPrecision<Pow2.N32>> expecteds = new(); |
33 | | - for (MultiPrecision<Pow2.N32> x = x0; x <= x1; x += dx) { |
34 | | - MultiPrecision<Pow2.N32> y = f32(x); |
| 21 | + sw.WriteLine("expected"); |
| 22 | + List<MultiPrecision<Pow2.N32>> expecteds = new(); |
| 23 | + for (MultiPrecision<Pow2.N32> x = x0; x <= x1; x += dx) { |
| 24 | + MultiPrecision<Pow2.N32> y = (x > 0) ? MultiPrecision<Pow2.N32>.InverseErf(x) / x : c; |
35 | 25 |
|
36 | | - expecteds.Add(y); |
37 | | - |
38 | | - if ((x % 0.125) == 0) { |
39 | | - Console.Write("."); |
40 | | - } |
| 26 | + expecteds.Add(y); |
41 | 27 |
|
42 | | - //sw.WriteLine($"{x},{y:e40}"); |
43 | | - } |
44 | | - |
45 | | - Console.Write("\n"); |
| 28 | + //sw.WriteLine($"{x},{y:e40}"); |
| 29 | + } |
46 | 30 |
|
47 | | - sw.WriteLine($"diffs x = {x0}"); |
48 | | - MultiPrecision<Pow2.N64>[] diffs = FiniteDifference<Pow2.N64>.Diff(x0.Convert<Pow2.N64>(), f64, Math.ScaleB(1, -20)); |
49 | | - for (int i = 0; i < diffs.Length; i++) { |
50 | | - sw.WriteLine($"{i},{diffs[i]:e40}"); |
51 | | - } |
52 | | - sw.Flush(); |
53 | | - |
54 | | - MultiPrecision<Pow2.N32>[] cs = new MultiPrecision<Pow2.N32>[diffs.Length + 1]; |
55 | | - cs[0] = f32(x0); |
56 | | - for (int i = 0; i < diffs.Length; i++) { |
57 | | - cs[i + 1] = diffs[i].Convert<Pow2.N32>() * MultiPrecision<Pow2.N32>.TaylorSequence[i + 1]; |
58 | | - } |
59 | | - |
60 | | - sw.WriteLine("pade results"); |
61 | | - bool is_finished = false; |
62 | | - |
63 | | - for (int m = 4; m < diffs.Length && !is_finished; m++) { |
64 | | - for (int n = m - 1; n <= m + 1 && m + n < diffs.Length; n++) { |
65 | | - (MultiPrecision<Pow2.N32>[] ms, MultiPrecision<Pow2.N32>[] ns) = |
66 | | - PadeSolver<Pow2.N32>.Solve(cs.Take(m + n + 1).ToArray(), m, n); |
67 | | - |
68 | | - MultiPrecision<Pow2.N32> err = 0; |
69 | | - for ((int i, MultiPrecision<Pow2.N32> x) = (0, x0); i < expecteds.Count; i++, x += dx) { |
70 | | - MultiPrecision<Pow2.N32> expected = expecteds[i]; |
71 | | - MultiPrecision<Pow2.N32> actual = PadeSolver<Pow2.N32>.Approx(x - x0, ms, ns); |
72 | | - |
73 | | - err = MultiPrecision<Pow2.N32>.Max(err, MultiPrecision<Pow2.N32>.Abs(expected / actual - 1)); |
74 | | - } |
75 | | - |
76 | | - Console.WriteLine($"m={m},n={n}"); |
77 | | - Console.WriteLine($"{err:e20}"); |
78 | | - |
79 | | - if (err < 1e-16) { |
80 | | - sw.WriteLine($"m={m},n={n}"); |
81 | | - sw.WriteLine("ms"); |
82 | | - for (int i = 0; i < ms.Length; i++) { |
83 | | - sw.WriteLine($"{ms[i]:e20}"); |
84 | | - } |
85 | | - sw.WriteLine("ns"); |
86 | | - for (int i = 0; i < ns.Length; i++) { |
87 | | - sw.WriteLine($"{ns[i]:e20}"); |
88 | | - } |
89 | | - sw.WriteLine("relative err"); |
90 | | - sw.WriteLine($"{err:e20}"); |
91 | | - sw.Flush(); |
92 | | - |
93 | | - if (ms.All((v) => v > 0) && ns.All((v) => v > 0)) { |
94 | | - is_finished = true; |
95 | | - } |
96 | | - } |
97 | | - } |
98 | | - } |
99 | | - |
100 | | - if (!is_finished) { |
101 | | - Console.WriteLine("not convergence"); |
102 | | - } |
| 31 | + sw.WriteLine($"series x = {x0}"); |
| 32 | + List<MultiPrecision<Pow2.N32>> diffs = new(); |
| 33 | + for (int d = 0; d <= 64; d++) { |
| 34 | + MultiPrecision<Pow2.N32> dy = InvErfTaylorSeries.Coef<Pow2.N32>(d); |
| 35 | + diffs.Add(dy); |
| 36 | + |
| 37 | + sw.WriteLine($"{d},{dy:e20}"); |
103 | 38 | } |
104 | | - |
| 39 | + sw.Flush(); |
| 40 | + |
| 41 | + //sw.WriteLine("pade results"); |
| 42 | + //bool is_finished = false; |
| 43 | + // |
| 44 | + //for (int m = 4; m <= 64 && !is_finished; m++) { |
| 45 | + // for (int n = m - 1; n <= m + 1 && m + n < 128; n++) { |
| 46 | + // (MultiPrecision<Pow2.N32>[] ms, MultiPrecision<Pow2.N32>[] ns) = |
| 47 | + // PadeSolver<Pow2.N32>.Solve(diffs.Take(m + n + 1).ToArray(), m, n); |
| 48 | + // |
| 49 | + // MultiPrecision<Pow2.N32> err = 0; |
| 50 | + // for ((int i, MultiPrecision<Pow2.N32> x) = (0, x0); i < expecteds.Count; i++, x += dx) { |
| 51 | + // MultiPrecision<Pow2.N32> expected = expecteds[i]; |
| 52 | + // MultiPrecision<Pow2.N32> actual = PadeSolver<Pow2.N32>.Approx(MultiPrecision<Pow2.N32>.Square(x - x0), ms, ns); |
| 53 | + // |
| 54 | + // err = MultiPrecision<Pow2.N32>.Max(err, MultiPrecision<Pow2.N32>.Abs(expected / actual - 1)); |
| 55 | + // } |
| 56 | + // |
| 57 | + // Console.WriteLine($"m={m},n={n}"); |
| 58 | + // Console.WriteLine($"{err:e20}"); |
| 59 | + // |
| 60 | + // if (err < 1e-32) { |
| 61 | + // sw.WriteLine($"m={m},n={n}"); |
| 62 | + // sw.WriteLine("ms"); |
| 63 | + // for (int i = 0; i < ms.Length; i++) { |
| 64 | + // sw.WriteLine($"{(ms[i] * c):e40}"); |
| 65 | + // } |
| 66 | + // sw.WriteLine("ns"); |
| 67 | + // for (int i = 0; i < ns.Length; i++) { |
| 68 | + // sw.WriteLine($"{ns[i]:e40}"); |
| 69 | + // } |
| 70 | + // sw.WriteLine("relative err"); |
| 71 | + // sw.WriteLine($"{err:e20}"); |
| 72 | + // sw.Flush(); |
| 73 | + // |
| 74 | + // is_finished = true; |
| 75 | + // } |
| 76 | + // } |
| 77 | + //} |
105 | 78 |
|
106 | 79 | Console.WriteLine("END"); |
107 | 80 | Console.Read(); |
|
0 commit comments