- /* MATH1155 C programming assignment */
- /* file: intersect.c */
- /* created by: Ian Grundy 01/04/12 */
- /* modified by: */
- # include <stdio.h>
- # include <stdlib.h>
- # include <math.h>
- # define PI 3.1415926535897932385
- /* Function prototypes */
- double f(double x);
- double dfdx(double x);
- double si(double x);
- double diffsi(double x);
- double myrandom();
- double heuristic(double left, double right, int maxiter);
- double bisection(double left, double right, double epsilon);
- double secant(double left, double right, double epsilon, int maxiter);
- double newton(double initial, double epsilon, int maxiter);
- int main(void)
- {
- double eps = 1.0e-12;
- int maxiter;
- double b, n, s, h;
- maxiter = 5000;
- h = heuristic(0, 3.0, maxiter);
- maxiter = 500;
- b = bisection(0, 3.0, eps);
- s = secant(0, 3.0, eps, maxiter);
- n = newton(1.5, eps, maxiter);
- printf (" heuristic bisection secant newton\n");
- printf ("%15.10f %15.10f %15.10f %15.10f %f\n", h, b, s, n, si(1.5));
- return 0;
- }
- /* Function Definitions */
- double factorial(int n)
- {
- int i;
- double product = 1;
- for ( i=2; i <= n; i=i+1) product = product * i;
- return product;
- }
- double si(double x)
- {
- int i;
- double z;
- double sum=0;
- for(i=1;;i++)
- {
- z = ((pow((-1),i))*(pow(x,(2*i+1))))/((2*i+1)*(factorial(2*i+1)));
- if (fabs(z) < exp(-12))
- {
- break;
- }
- else
- {
- sum = sum + z;
- }
- }
- return sum;
- }
- double diffsi(double x)
- {
- double sum = 1;
- int i;
- double z;
- for(i=0;;i++)
- {
- z = ((pow((-1),i))*(pow(x,(2*i+2))))/(factorial(2*i+1));
- if (fabs(z) < exp(-12))
- {
- break;
- }
- else
- {
- sum = sum + z;
- }
- }
- return sum;
- }
- double f(double x)
- {
- return si(x)-PI/2.0;
- }
- double dfdx(double x)
- {
- return diffsi(x);
- }
- double myrandom()
- {
- return (double) rand() / (double) RAND_MAX;
- }
- double heuristic(double left, double right, int maxiter)
- {
- /* simulated annealing function minimiser */
- double rad = (right - left)/100.0;
- double r = 0.99;
- double T = 100;
- double prob;
- int iter = 0;
- double bestx, currentx, newx;
- double besty, currenty, newy;
- currentx = (left + right)/2.0;
- currenty = fabs(f(currentx));
- bestx = currentx;
- besty = currenty;
- for (iter = 1; iter < maxiter+1; iter++)
- {
- newx = currentx + (2*myrandom()-1)*rad;
- newy = fabs(f(newx));
- if ( newy < currenty )
- {
- /* accept if better */
- currentx = newx;
- currenty = newy;
- }
- else
- {
- /* possibly accept if worse */
- prob = exp(-(newy-currenty)/T);
- if ( myrandom() < prob)
- {
- currentx = newx;
- currenty = newy;
- }
- }
- if ( currenty < besty )
- {
- /* store absolute best found */
- bestx = currentx;
- besty = currenty;
- }
- T = r*T;
- }
- return bestx;
- }
- double bisection(double left, double right, double epsilon)
- {
- double midpoint, fmid, fleft, fright;
- fleft = f(left);
- fright = f(right);
- if (fleft*fright > 0) return -99;
- while (fabs(right - left) > 2*epsilon)
- {
- midpoint = (left + right)/2.0;
- fmid = f(midpoint);
- if (fmid*fleft >= 0) left = midpoint;
- if (fmid*fright > 0) right = midpoint;
- }
- return (left + right)/2.0;
- }
- double secant(double left, double right, double epsilon, int maxiter)
- {
- return (left + right)/2.0;
- }
- double newton(double initial, double epsilon, int maxiter)
- {
- return initial;
- }