text: /****************************************************************************
   *
   * Copyright 2016 Samsung Electronics All Rights Reserved.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an
   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
   * either express or implied. See the License for the specific
   * language governing permissions and limitations under the License.
   *
   ****************************************************************************/
  /************************************************************************
   * libc/math/lib_logf.c
   *
   * This file is a part of NuttX:
   *
   *   Copyright (C) 2012 Gregory Nutt. All rights reserved.
   *   Ported by: Darcy Gong
   *
   * It derives from the Rhombs OS math library by Nick Johnson which has
   * a compatibile, MIT-style license:
   *
   * Copyright (C) 2009, 2010 Nick Johnson <nickbjohnson4224 at gmail.com>
   *
   * Permission to use, copy, modify, and distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
   * copyright notice and this permission notice appear in all copies.
   *
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   *
   ************************************************************************/
  
  /************************************************************************
   * Included Files
   ************************************************************************/
  
  #include <math.h>
  #include <float.h>
  
  /************************************************************************
   * Pre-processor Definitions
   ************************************************************************/
  
  #define FLT_MAX_EXP_X         88.0F
  
  /* To avoid looping forever in particular corner cases, every LOGF_MAX_ITER
   * the error criteria is relaxed by a factor LOGF_RELAX_MULTIPLIER.
   * todo: might need to adjust the double floating point version too.
   */
  
  #define LOGF_MAX_ITER         10
  #define LOGF_RELAX_MULTIPLIER 2
  
  /************************************************************************
   * Public Functions
   ************************************************************************/
  
  float logf(float x)
  {
  	float y;
  	float y_old;
  	float ey;
  	float epsilon;
  	int relax_factor;
  	int iter;
  
  	y = 0.0;
  	y_old = 1.0;
  	epsilon = FLT_EPSILON;
  
  	iter = 0;
  	relax_factor = 1;
  
  	if (isnan(x) || x < 0.0) {
  		return NAN;
  	}
  
  	if (x == 0.0) {
  		return -INFINITY;
  	}
  
  	while (y > y_old + epsilon || y < y_old - epsilon) {
  		y_old = y;
  		ey = expf(y);
  		y -= (ey - x) / ey;
  
  		if (y > FLT_MAX_EXP_X) {
  			y = FLT_MAX_EXP_X;
  		}
  
  		if (y < -FLT_MAX_EXP_X) {
  			y = -FLT_MAX_EXP_X;
  		}
  		epsilon = (fabsf(y) > 1.0) ? fabsf(y) * FLT_EPSILON : FLT_EPSILON;
  
  		if (++iter >= LOGF_MAX_ITER) {
  			relax_factor *= LOGF_RELAX_MULTIPLIER;
  			iter = 0;
  		}
  
  		if (relax_factor > 1) {
  			epsilon *= relax_factor;
  		}
  	}
  
  	if (y == FLT_MAX_EXP_X) {
  		return INFINITY;
  	}
  
  	if (y == -FLT_MAX_EXP_X) {
  		return INFINITY;
  	}
  
  	return y;
  }
  