This source file includes following definitions.
- inverse_factorial
- main
#include "Halide.h"
#include <stdio.h>
using namespace Halide;
float inverse_factorial(int x) {
double y = 1;
for (int i = 2; i <= x; i++) {
y /= i;
}
return (float)y;
}
int main(int argc, char **argv) {
Func f;
Var x;
Expr xf = x/256.0f;
{
Expr y1 = 0.0f;
for (int k = 0; k < 20; k++) {
y1 += Halide::pow(-1, k) * pow(xf, 1+2*k) * inverse_factorial(1 + 2 * k);
}
Func approx_sin_1;
approx_sin_1(x) = y1;
Expr y2 = 1.0f;
for (int k = 20; k > 0; k--) {
y2 = 1 - (y2 * pow(xf, 2)) / (2*k * (2*k + 1));
}
y2 *= xf;
Func approx_sin_2;
approx_sin_2(x) = y2;
Func exact_sin;
exact_sin(x) = sin(xf);
Buffer<float> approx_result_1 = approx_sin_1.realize(256*5);
Buffer<float> approx_result_2 = approx_sin_2.realize(256*5);
Buffer<float> exact_result = exact_sin.realize(256*5);
Func rms_1, rms_2;
RDom r(exact_result);
rms_1() = sqrt(sum(pow(approx_result_1(r) - exact_result(r), 2), "rms_1_sum"));
rms_2() = sqrt(sum(pow(approx_result_2(r) - exact_result(r), 2), "rms_2_sum"));
Buffer<float> error_1 = rms_1.realize();
Buffer<float> error_2 = rms_2.realize();
if (error_1(0) > 0.0001 || error_2(0) > 0.0001) {
printf("Approximate sin errors too large: %1.20f %1.20f\n", error_1(0), error_2(0));
return -1;
}
}
{
xf = xf + 1;
Func approx_exp_1;
Expr y1 = 0.0f;
for (int k = 0; k < 20; k++) {
y1 += pow(xf, -k) * inverse_factorial(k);
}
approx_exp_1(x) = y1;
Func approx_exp_2;
Expr y2 = 0.0f;
for (int k = 20; k > 0; k--) {
y2 = 1 + y2 / (k * xf);
}
approx_exp_2(x) = y2;
Func exact_exp;
exact_exp(x) = exp(1.0f/xf);
Buffer<float> approx_result_1 = approx_exp_1.realize(256*5);
Buffer<float> approx_result_2 = approx_exp_2.realize(256*5);
Buffer<float> exact_result = exact_exp.realize(256*5);
Func rms_1, rms_2;
RDom r(exact_result);
rms_1() = sqrt(sum(pow(approx_result_1(r) - exact_result(r), 2), "rms_1_neg_sum"));
rms_2() = sqrt(sum(pow(approx_result_2(r) - exact_result(r), 2), "rms_2_neg_sum"));
Buffer<float> error_1 = rms_1.realize();
Buffer<float> error_2 = rms_2.realize();
if (error_1(0) > 0.0001 || error_2(0) > 0.0001) {
printf("Approximate exp errors too large: %1.20f %1.20f\n", error_1(0), error_2(0));
return -1;
}
}
printf("Success!\n");
return 0;
}