I made a program that contains a root-finding algorithm for polynomials as a function and contains 3 test polynomials. The algorithm is [Brent's method][1] and is based entirely off the pseudocode from Wikipedia. Is there anything I should change to make the code faster/easier to understand/etc?

The code does run and prints correct results for all test cases I've tried.

I'm mostly interested in writing optimized code with the priority being faster runtime, less memory usage, and fewer redundant function calls respectively, but I'm also interested in picking up better coding practices.

    /*******************************************************************************
    *
    * Grant Williams
    *
    * Version 1.0.0
    * August 27, 2015
    *
    * Test Program for Brent's Method Function.
    *
    * Brent's method makes use of the bisection method, the secant method, and inverse quadratic interpolation in one algorithm.
    *
    * To Compile Please use icc -std=c++11 if using intel or g++ -std=c++11 if using GCC.
    *
    ********************************************************************************/
    
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #include <functional>
    #include <ctime>
    //#include "brent_fun.h"
    
    void brents_fun(std::function<double (double)> f, double lower_bound, double upper_bound, double TOL, double MAX_ITER);
    
    int main()
    {
    	//clock stuff
    	std::clock_t start;
    	double duration;
    	start = std::clock();
    	//stop clock stuff 
    
    	double a;				// lower bound
    	double b;				// upper bound
    	double TOL = 0.0001;	// tolerance
    	double MAX_ITER = 1000;	// maximum number of iterations
    
    	int function;			// set polynomial to find roots of & boundary conditions for that polynomial
    
    	std::cout << std::endl;
    
    	for (function = 1; function <= 3; function++)
    	{
    		if (function == 1)
    		{
    			a = -1.5;
    			b = 0;
    			auto f = [](double x){ return (x+1) * (x+2) * (x+3); };
    			brents_fun(f,a,b,TOL,MAX_ITER);
    		}
    		else if (function == 2)
    		{
    			a = -10;
    			b = 10;
    			auto f = [](double x){ return (x*x*x -4*x - 9); };
    			brents_fun(f,a,b,TOL,MAX_ITER);
    		}
    		else if (function == 3)
    		{
    			a = -4;
    			b = 3;
    			auto f = [](double x){ return (x+3)*(x-1)*(x-1); };
    			brents_fun(f,a,b,TOL,MAX_ITER);
    		}
    	}
    
    	
    
    	
    	//clock stuff again
    	duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
    	std::cout << "Elapsed time: " << duration << " seconds" << std::endl;
    	//finish clock stuff
    
    	std::cout << std::endl;
    
    	return 0;
    }
    
    void brents_fun(std::function<double (double)> f, double lower_bound, double upper_bound, double TOL, double MAX_ITER)
    {
    	double a = lower_bound;
    	double b = upper_bound;
    	double fa = f(a);	// calculated now to save function calls
    	double fb = f(b);	// calculated now to save function calls
    	double fs = 0;		// initialize 
    
    	if (!(fa * fb < 0))
    	{
    		std::cout << "Signs of f(lower_bound) and f(upper_bound) must be opposites" << std::endl; // throws exception if root isn't bracketed
    		return;
    	}
    
    	if (std::abs(fa) < std::abs(b))	// if magnitude of f(lower_bound) is less than magnitude of f(upper_bound)
    	{
    		std::swap(a,b);
    		std::swap(fa,fb);
    	}
    
    	double c = a;			// c now equals the largest magnitude of the lower and upper bounds
    	double fc = fa;			// precompute function evalutation for point c by assigning it the same value as fa
    	bool mflag = true;		// boolean flag used to evaluate if statement later on
    	double s = 0;			// Our Root that will be returned
    	double d = 0;			// Only used if mflag is unset (mflag == false)
    
    	for (unsigned int iter = 1; iter < MAX_ITER; ++iter)
    	{
    		// stop if converged on root or error is less than tolerance
    		if (std::abs(b-a) < TOL)
    		{
    			std::cout << "After " << iter << " iterations the root is: " << s << std::endl;
    			return;
    		} // end if
    		
    		if (fa != fc && fb != fc)
    		{
    			// use inverse quadratic interopolation
    			s =	  ( a * fb * fc / ((fa - fb) * (fa - fc)) )
    				+ ( b * fa * fc / ((fb - fa) * (fb - fc)) )
    				+ ( c * fa * fb / ((fc - fa) * (fc - fb)) );
    		}
    		else
    		{
    			// secant method
    			s = b - fb * (b - a) / (fb - fa);
    		}
    
    		/*
    			Crazy condition statement!:
    			-------------------------------------------------------
    			(condition 1) s is not between  (3a+b)/4  and b or
    			(condition 2) (mflag is true and |s−b| ≥ |b−c|/2) or
    			(condition 3) (mflag is false and |s−b| ≥ |c−d|/2) or
    			(condition 4) (mflag is set and |b−c| < |TOL|) or
    			(condition 5) (mflag is false and |c−d| < |TOL|)
    		*/
    		if (	( (s < (3 * a + b) * 0.25) || (s > b) ) ||
    				( mflag && (std::abs(s-b) >= (std::abs(b-c) * 0.5)) ) ||
    				( !mflag && (std::abs(s-b) >= (std::abs(c-d) * 0.5)) ) ||
    				( mflag && (std::abs(b-c) < TOL) ) ||
    				( !mflag && (std::abs(c-d) < TOL))	)
    		{
    			// bisection method
    			s = (a+b)*0.5;
    
    			mflag = true;
    		}
    		else
    		{
    			mflag = false;
    		}
    
    		fs = f(s);	// calculate fs
    		d = c;		// first time d is being used (wasnt used on first iteration because mflag was set)
    		c = b;		// set c equal to upper bound
    		fc = fb;	// set f(c) = f(b)
    
    		if ( fa * fs < 0)	// fa and fs have opposite signs
    		{
    			b = s;
    			fb = fs;	// set f(b) = f(s)
    		}
    		else
    		{
    			a = s;
    			fa = fs;	// set f(a) = f(s)
    		}
    
    		if (std::abs(fa) < std::abs(fb)) // if magnitude of fa is less than magnitude of fb
    		{
    			std::swap(a,b);		// swap a and b
    			std::swap(fa,fb);	// make sure f(a) and f(b) are correct after swap
    		}
    
    	} // end for
    
    	std::cout<< "The solution does not converge or iterations are not sufficient" << std::endl;
    
    } // end brent_fun


  [1]: https://en.wikipedia.org/wiki/Brent%27s_method