/*
 * CSE 333/374 Function parameter demo - version 2
 * Integration with function parameters and some syntactic sugar:
 * Use a typedef for the function parameter type, and take advantage
 * of implicit funtion<->pointer conversions in parameters and calls.
 * 12/07-3/16, HP
 */

#include <stdio.h>
#include <math.h>

#define PI 3.1415926535

/* return 2.0 for all values of x */
double two(double x) {
  return 2.0;
}

/* Define fdd as type of pointer to double->double function */
typedef double (*fdd)(double);

/* return integral of f(x) from lo to hi in steps of delta */
/* note: no error checking, not the most numerically robust, etc., */
/* intended only to demonstrate functional parameters, distributed as-is, */
/* not to be used to launch spaceships or in any other critical application */
double integrate(fdd f, double lo, double hi, double delta) {
  int i;
  double ans = 0.0;
  double x;
  int n = (int)(0.5+(hi-lo)/delta);
  for (i = 0; i <= n; i++) {
    x = lo + i*delta;
    ans += f(x) * ((hi-lo) / (n+1));
  }
  printf("n = %d, final x = %e\n", n, x);
  return ans;
}

int main() {
  printf("\\int two(x) from 0 to 2 step 1.0  = %e\n", 
	 integrate(two, 0.0, 2.0, 1.0));
  printf("\\int two(x) from 0 to 4 step 0.01 = %e\n", 
	 integrate(two, 0.0, 4.0, 0.01));
  printf("\\int sin(x) from 0 to pi/2 step 0.01 = %e\n", 
	 integrate(sin, 0.0, PI/2.0, 0.01));
  printf("\\int sin(x) from 0 to pi/2 step 0.000001 = %e\n", 
	 integrate(sin, 0.0, PI/2.0, 0.000001));
  return 0;
}