numerical approximation of gauss error function https://en.wikipedia.org/wiki/Error_function#Polynomial original book: Numerical Recipes in Fortran 77: The Art of Scientific Computing
| 70 | // original book: |
| 71 | // Numerical Recipes in Fortran 77: The Art of Scientific Computing |
| 72 | mlir::Value erf_approx(ValueBuilderHelper& helper, mlir::Value x) { |
| 73 | auto zero = helper.const_f32(0); |
| 74 | auto one = helper.const_f32(1); |
| 75 | auto half = helper.const_f32(0.5); |
| 76 | |
| 77 | auto t = helper.div(one, helper.add(one, helper.mul(half, helper.abs(x)))); |
| 78 | |
| 79 | std::vector<mlir::Value> coeff = { |
| 80 | helper.const_f32(0.17087277), helper.const_f32(-0.82215223), |
| 81 | helper.const_f32(1.48851587), helper.const_f32(-1.13520398), |
| 82 | helper.const_f32(0.27886807), helper.const_f32(-0.18628806), |
| 83 | helper.const_f32(0.09678418), helper.const_f32(0.37409196), |
| 84 | helper.const_f32(1.00002368), helper.const_f32(-1.26551223)}; |
| 85 | auto p = polynomial(helper, t, coeff); |
| 86 | |
| 87 | auto r = helper.mul(t, helper.exp(helper.sub(p, helper.mul(x, x)))); |
| 88 | return helper.select(helper.ge(x, zero), helper.sub(one, r), helper.sub(r, one)); |
| 89 | } |
| 90 | |
| 91 | // numerical approximation of the inverse of normal distribution function |
| 92 | // original algorithm: |