function [ x, fx, it ] = nonlin_fixed_point ( f_string, g_string, x0, it )

%*****************************************************************************80
%
%% nonlin_fixed_point is an interactive fixed point method program.
%
%  Discussion:
%
%    This function manages an interactive computation which uses the fixed
%    point method to seek a zero of a function f(x), given a fixed
%    point function g(x), a starting value, and a number of iterations.
%
%    The user enters formulas for f(x) and g(x), the starting value x0,
%    and the number of iterations it.
%
%    The program can be invoked by a function call, in which case the
%    string specifying f(x) must be quoted:
%      [ x, fx, it ] = nonlin_fixed_point ( 'x^2-5', '(x+5/x)/2', 1, 10 )
%    or as an interactive command with arguments:
%      [ x, fx, it ] = nonlin_fixed_point  x^2-5  (x+5/x)/2  1  10
%    If called with no arguments, these are requested:
%      [ x, fx, it ] = nonlin_fixed_point ( );
%      Enter function formula, like x^2: x^2-5
%      Enter fixed point formula, like 2*x: (x+5/x)/2
%      Enter starting point, x0: 1
%      Enter number of iterations, it: 10
%
%    The function is specified as a string which is either:
%    * a MATLAB expression using the argument 'x', 
%    * the name of an M-file followed by the argument '(x)'.
%
%    The string should not contain any spaces between symbols, except
%    when it is passed as a function argument in quotes.
%
%    It is not necessary to use the "dot" notation for expressions involving
%    '*', '/', or '^', but it doesn't hurt either.
%
%    Examples of function specifications:
%
%      x^2
%      x.^2
%      3/(x^4+5*x-6)
%      sin(7*x)*sqrt(x)/8
%      wiggle(x)     <-- where "wiggle.m" is a user-provided M file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 July 2019
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    string f_string: the function whose zero is desired.
%
%    string g_string: the fixed point function.
%
%    real x0: the starting point.
%
%    integer it: the number of iterations to take.
%
%  Output:
%
%    real x(it+1): the sequence of solution estimates;
%
%    real fx(it+1): the function values.
%

%
%  Get f, g, x0, it
%
  if ( nargin < 1 )
    f_string = input ( 'Enter function formula, like x^2: ', 's' );
  end
  f_element = vector_to_element ( f_string );
  f = str2func ( [ '@(x)', f_element ] );

  if ( nargin < 2 )
    g_string = input ( 'Enter fixed point formula, like 2*x: ', 's' );
  end
  g_element = vector_to_element ( g_string );
  g = str2func ( [ '@(x)', g_element ] );

  if ( nargin < 3 )
    x0 = input ( 'Enter starting point x0: ' );
  elseif ( ischar ( x0 ) )
    x0 = str2num ( x0 );
  end

  if ( nargin < 4 )
    it = input ( 'Enter number of iterations: ' );
  elseif ( ischar ( it ) )
    it = str2num ( it );
  end
%
%  Carry out the fixed point calculation.
%
  x = zeros ( it + 1, 1 );
  fx = zeros ( it + 1, 1 );

  x(1) = x0;
  fx(1) = f ( x(1) );

  for i = 2 : it + 1
    x(i) = g( x(i-1) );
    fx(i) = f( x(i) );
  end

  return
end
function [ a, it, status ] = newton ( a, tol, f, fp )

%*****************************************************************************80
%
%% newton carries out the newton method.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 July 2019
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, the starting point.
%
%    Input, real TOL, a tolerance. 
%
%    Input, function handle F, FP, pointers to a function and its derivative.  
%    These can be anonymous functions or the names of a MATLAB M-file function.
%
%    Output, real A, the last iterate.
%
%    Output, integer IT, the number of steps.
%
%    Output, string STATUS, a message indicating why the procedure stopped.
%
  fa = f(a);
  fpa = fp ( a );
  big = 100.0 * abs ( fa );
  small = 1.0E-08;
  it = 0;

  while ( true )

    if ( 50 <= it )
      status = 'Failure: too many steps!';
      return
    end

    if ( abs ( fpa ) <= small )
      status = 'Divergence: derivative value too small!';
      return
    end

    b = a - fa / fpa;
    fb = f(b);
    it = it + 1;
    a = b;
    fa = fb;
    fpa = fp ( a );

    if ( big <= abs ( fa ) )
      status = 'Divergence: function value grew too large!';
      return
    end

    if ( abs ( fa ) <= tol )
      status = 'Convergence: very small function value!';
      return
    end

  end

  return
end
function f_element = vector_to_element ( f_vector )

%*****************************************************************************80
%
%% vector_to_element rewrites a MATLAB vector function elementwise.
%
%  Discussion:
%
%    In MATLAB, by default, the operators '*', '/', and '^' are interpreted
%    as linear algebraic operations.  In many cases, a user simply desired
%    the elementwise operation instead, which MATLAB indicates using a 
%    dotted notation: '.*', './', and '.^'.
%
%    This function converts a string to a form that uses dotted operators.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 June 2019
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    string f_vector, a string presumably representing a MATLAB expression.
%
%  Output:
%
%    string f_element, a copy of f_vector in which all operators have been
%    replaced by their dotted (elementwise) form.
%
  n_vector = length ( f_vector );
  f_element = [''];

  c_prev = '';
  for iv = 1 : n_vector
    c = f_vector(iv);
    if ( ( c == '*' || c == '/' || c == '^' ) && ( c_prev ~= '.' ) )
      f_element = [ f_element, ' .', c, ' ' ];
    else
      f_element = [ f_element, c ];
    end
    c_prev = c;
  end

  return
end

