/** Approximator fuer den natuerlichen Logarithmus
 * @author Jan Johannsen 
 */
public class LogApproximator
{

    private final double EPSILON = 1E-14 ;
    private final double DELTA = 0.05 ; 

    private double argument;
    private int anzahl ; 
    private int faktor ; 
    private double alteNaeherung ;
    private double neueNaeherung ;
    private int vorzeichen ;  
    private double potenz ; 

    /** erzeugt einen Approximator 
     * @param eingabe Zahl deren Logarithmus berechnet wird 
     * Vorbedingung: eingabe > 0 
     */
    public LogApproximator(double eingabe) 
    {
	argument = eingabe ;
	anzahl = 1  ; 

	for ( faktor = 0 ; argument <= DELTA ; faktor-- )
	    argument *= Math.E ; 
	for ( faktor = 0 ; argument >= 2-DELTA ; faktor++ )
	    argument /= Math.E ; 

	alteNaeherung = 0 ;
	neueNaeherung = argument-1 ;

	vorzeichen = 1 ;  
	potenz = argument-1 ; 
    }

    /** 
     * @return das Argument der Approximation 
     */
    public double getArgument() 
    { 
	return argument ; 
    }

    /** 
     * @return den Skalierungsfaktor 
     */
    public double getFaktor() 
    { 
	return faktor ; 
    }

    /** berechnet einen besseren Naeherungswert.
     * @return den neuen Naeherungswert 
     */ 
    public double naechsteNaeherung()
    {
	alteNaeherung = neueNaeherung ; 
	vorzeichen *= -1 ; 
	potenz *= ( argument - 1 ) ;
	anzahl++ ; 
	neueNaeherung = alteNaeherung + vorzeichen * potenz / anzahl ; 
	return neueNaeherung ; 
    }

    /** Abbruchkriterium
     * @return ob der Naeherungswert noch unganau ist 
     */
    public boolean nochUngenau() 
    {
	return Math.abs( neueNaeherung - alteNaeherung ) > EPSILON ;
    }

    /** berechnet den Logarithmus durch iteriertes Verbessern
     * der Naeherung 
     * @return der berechnete Naeherungswert
     */  
    public double getLog() 
    {	
	while ( nochUngenau() ) 
	    naechsteNaeherung() ; 
	return neueNaeherung + faktor ; 
    }

}
