polynomial approximation of arctangent atan(t) = t + c3 * t^3 + c5 * t^5 + ... + c17 * t^17 original paper: https://arxiv.org/pdf/1508.03211.pdf
| 25 | // original paper: |
| 26 | // https://arxiv.org/pdf/1508.03211.pdf |
| 27 | mlir::Value atan2_approx(ValueBuilderHelper& helper, mlir::Value y, mlir::Value x) { |
| 28 | auto atan_poly = [&](mlir::Value t) { |
| 29 | std::vector<mlir::Value> coeff = { |
| 30 | helper.const_f32(2.90188402868807315826416015625E-3), |
| 31 | helper.const_f32(-1.62907354533672332763671875E-2), |
| 32 | helper.const_f32(4.3082617223262786865234375E-2), |
| 33 | helper.const_f32(-7.5408883392810821533203125E-2), |
| 34 | helper.const_f32(0.1066047251224517822265625), |
| 35 | helper.const_f32(-0.14209578931331634521484375), |
| 36 | helper.const_f32(0.19993579387664794921875), |
| 37 | helper.const_f32(-0.3333314359188079833984375)}; |
| 38 | auto t2 = helper.mul(t, t); |
| 39 | auto p = polynomial(helper, t2, coeff); |
| 40 | return helper.add(helper.mul(helper.mul(p, t2), t), t); |
| 41 | }; |
| 42 | |
| 43 | // constants |
| 44 | auto zero = helper.const_f32(0); |
| 45 | auto pi = helper.const_f32(3.141592653589793); |
| 46 | auto pi_over_2 = helper.const_f32(1.570796326794897); |
| 47 | |
| 48 | // transform the angle into interval [0, pi/4] |
| 49 | auto ax = helper.abs(x); |
| 50 | auto ay = helper.abs(y); |
| 51 | auto q = helper.div(helper.min(ax, ay), helper.max(ax, ay)); |
| 52 | |
| 53 | // get approximation for interval [0, pi/4] |
| 54 | auto r = atan_poly(q); |
| 55 | |
| 56 | // [0, pi/4] => [0, pi/2] |
| 57 | r = helper.select(helper.le(ax, ay), helper.sub(pi_over_2, r), r); |
| 58 | |
| 59 | // [0, pi/2] => [0, pi] |
| 60 | r = helper.select(helper.le(x, zero), helper.sub(pi, r), r); |
| 61 | |
| 62 | // [0, pi] => [-pi, pi] |
| 63 | r = helper.select(helper.le(y, zero), helper.sub(zero, r), r); |
| 64 | |
| 65 | return r; |
| 66 | } |
| 67 | |
| 68 | // numerical approximation of gauss error function |
| 69 | // https://en.wikipedia.org/wiki/Error_function#Polynomial |