
import java.applet.*;
import java.awt.*;

public class EMSF
  extends Applet
{
  private static double EULER_GAMMA=0.5772156649015328606065120900;
                                    /* Obtained from GP-PARI */
  private Panel pUI;
  private Panel pNum;
  private Label lNum;
  private TextField tfNum;
  private Button bConv;
  private Panel pResult;
  private TextArea tfResult;

  public EMSF()
  {
    pNum = new Panel();
    pNum.setLayout( new FlowLayout( FlowLayout.LEFT ) );
    lNum = new Label( "Number of terms to use:" );
    tfNum = new TextField( "10", 20 );
    pNum.add( lNum );
    pNum.add( tfNum );
    bConv = new Button( "Find Sum" );
    pNum.add( bConv );

    pResult = new Panel();
    pResult.setLayout( new FlowLayout( FlowLayout.LEFT ) );
    tfResult = new TextArea( 18, 64 );
    pResult.add( tfResult );

    pUI = new Panel();
    pUI.setLayout( new BorderLayout() );
    pUI.add( "North", pNum );
    pUI.add( "Center", pResult );

    setLayout( new BorderLayout() );
    add( "North", pUI );
    add( "Center", new Panel() );
  }

  public double g_direct( int n )
  {
    int k;
    double sum = 0.0;

    for( k = n; k > 0; k-- )
      sum += 1.0 / k;
    sum -= Math.log( 1.0 * n );
    return sum;
  }

  public double g_trapez( int n )
  {
    return g_direct(n)-0.5/n;
  }

  double g_eul_macl( int n )
  {
    int nn;
    nn = n*n;
    return g_trapez(n) + 1/(nn*12.0) -1/(nn*nn*120.0) +1/(nn*nn*nn*252.0);
  }

  public void showResult()
  {
    double gd, gt, ge;

    String txtNum = tfNum.getText();
    int n = Integer.parseInt( txtNum );
    if( n < 1 )
      n = 1;
    tfResult.setText(
      "ESTIMATING EULER'S CONSTANT BY VARIOUS METHODS:\n" );

    tfResult.appendText(
      "\nDefinition: lim(1+1/2+1/3+...+1/n -log(n))\n" );
    tfResult.appendText( "            n->infinity\n" );
    tfResult.appendText(
      "\nAccurate value obtained from GP-PARI: " + EULER_GAMMA );

    tfResult.appendText( "\n\nSummation Using "+ n + " terms\n" );

    gd = g_direct( n );
    gt = g_trapez( n );
    ge = g_eul_macl( n );
    tfResult.appendText( "\nDIRECT:\n" );
    tfResult.appendText(
      "Sum: " + gd + "      Error= " +  ( gd - EULER_GAMMA ) + "\n" );
    tfResult.appendText( "\nWITH TRAPEZOIDAL CORRECTION:\n" );
    tfResult.appendText(
      "Sum: " + gt + "       Error= " +  ( gt - EULER_GAMMA ) + "\n" );

    tfResult.appendText( "\nEULER-MACLAURIN (WITH 3 EXTRA TERMS):\n" );
    tfResult.appendText(
      "Sum: " + ge + "       Error= " +  ( ge - EULER_GAMMA ) + "\n" );
  }

  public boolean handleEvent( Event evt )
  {
    if( evt.id == Event.ACTION_EVENT ) {
      if( ( evt.target == bConv ) || ( evt.target == tfNum ) ) {
        try {
          showResult();
        } catch( NumberFormatException nfex ) {
          tfResult.setText( "Number Format Wrong!!!" );
        }
      }
    }
    return super.handleEvent( evt );
  }

  public void init() {
    showResult();
  }
}
