View on GitHub

computational-mathematics

Contains basic implementations of a number of standard procedures in scientific computing and computational mathematics.

Routine Name: functionalIteration

Author: Christopher Johnson

Language: C++. Tested with g++ compiler.

Declared in “functionalIteration.h”

Description/Purpose: This routine will approximate the a solution to the root finding problem f(x)=0, guaranteed within a user input tolerance. The given function f(x) must be a continuous function on one variable.

Input: Double a give an initial guess at the solution. Function f(x) gives a real-valued, continuous function on a single variable. Double tol is an optional parameter giving the required precision. Defaults to 10^-8 if not otherwise specified.

Output: Returns a double, giving the appoximated solution of f(x)=0. If the function fails to converge within 1000000 iterations, it will throw a notConvergentException.

Usage/Example:

In order to call the function functionalIteration, a target function f(x) must first be defined. Example usage code follows:

#include <iostream>
#include <cmath>
#include "functionalIteration.h"

double f(double x)
{
    return 3.0*sin(10*x);
}

double g(double x)
{
    return x*exp(-x);
}

int main(void)
{
    double froot,groot;
    try{
        froot = functionalIteration(-0.00000001,f);
        std::cout << "Root of f(x) at x=" << froot << std::endl;
    }
    catch(notConvergentException& e){
        std::cout << "Root of f(x) could not be calculated, as series did not converge.\n";
    }

    froot = functionalIteration(0,f);
    std::cout << "Root of f(x) at x=" << froot << std::endl;

    groot = functionalIteration(1.05,g);
    std::cout << "Root of g(x) at x=" << groot << std::endl;

    return 0;
}

Output from the lines above:

Root of f(x) could not be calculated, as series did not converge.
Root of f(x) at x=0
Root of g(x) at x=-2.13696e-20

Function f() is poorly conditioned for this algorithm, as it has a root a zero, but a value very close to zero failed to converge to the solution. If one was determined to utilize functional iteration to find a root of f(x), it would be necessary to find a different function to iterate on. The function g(x) has exactly one root, which is at x=0. Through testing, it was determined that any value in the range (-.6931,1.0603) would converge to the root, while any value outside of this range would never converge. As has been observed, the boiler-plate solution of iterating “x_{k+1} = f(x_k) - x_k” does not produce stable convergence in a wide range for either function examined. If functional iteration is to be used to solve for a root of a function, it is highly recommended that a custom iteration function be determined and utilized.

Implementation/Code: The following is the code for functionalIteration(a,f,tol)

//Finds an approximation of a root f(x)=0
//Input: a = starting estimate, f = function, tol = maximum accceptable error
//Output: double, approximation of some root of f(x)
double functionalIteration(double a, double (*f)(double), double tol=pow(10,-8))
{
    int maxIter = 1000000;
    double error = 10*tol; //force loop to execute at least once
    double x=a;
    int count=0;
    while (error>tol && ++count<maxIter)
    {
        //iterate on function x = f(x)-x
        double xprime = f(x)-x;
        error = std::abs(x-xprime);
        x = xprime;
    }
    if (count == maxIter)
        throw notConvergent;
    else
        return x;
}

Last Modified: September/2017