Tuesday, June 10, 2014

Control Observer

import java.util.*;

/**
 * Description   : ControlCommand, interface for processing commands
 * @author dbauman
 * @since   Jun 11, 2004
 *      Jun 11, 2004    (DBauman) Original Release
 */

public interface ControlCommand {
    public boolean processCommand(ControlProcessing controlProcessing);
}


import java.util.*;

/**
 * Description   : ControlCommandAbstract, holds the parameters, implements ControlCommand
 * @author dbauman
 * @since   Jun 11, 2004
 *      Jun 11, 2004    (DBauman) Original Release
 */

public abstract class ControlCommandAbstract implements ControlCommand {

    protected boolean debug = true;
    
    private ControlParameters controlParameters;
    public ControlParameters getControlParameters() {return controlParameters;}
    public ControlCommandAbstract(ControlParameters controlParameters) {
        this.controlParameters = controlParameters;
    }

}



import java.util.*;

/**
 * Description   : ControlCommandExit, exit command
 * @author dbauman
 * @since   Jun 11, 2004
 *   Jun 11, 2004    (DBauman) Original Release
 */

public class ControlCommandExit extends ControlCommandAbstract {
    public ControlCommandExit(ControlParameters controlParameters) {
        super(controlParameters);
    }
    public boolean processCommand(ControlProcessing controlProcessing) {
        ControlParameters controlParameters = getControlParameters();
        if (debug) System.out.println("Exit");
        System.exit(0);
        return true;
    }
}




import java.util.*;

/**
 * Description   : ControlCommandGetItem, get item command
 * @author dbauman
 * @since   Jun 11, 2004
 *      Jun 11, 2004    (DBauman) Original Release
 */

public class ControlCommandGetItem extends ControlCommandAbstract {
    public ControlCommandGetItem(ControlParameters controlParameters) {
        super(controlParameters);
    }
    public boolean processCommand(ControlProcessing controlProcessing) {
        ControlParameters controlParameters = getControlParameters();
        if (!controlParameters.hasNext()) return false;
        String map = (controlParameters.nextToken()).trim();
        if (!controlParameters.hasNext()) return false;
        String section = (controlParameters.nextToken()).trim();
        if (!controlParameters.hasNext()) return false;
        String item = (controlParameters.nextToken()).trim();
        if (debug) System.out.println("getitem: "+map+", "+section+", "+item);
        String val = "itemValue";
        // DO THE WORK HERE!!!
        // val = helper.getAppMapItem(map, section, item);

        // we can cast because we know that we are of this 'interface' type
        ((ControlProcessingUI1)controlProcessing).setAppMapItem(val);
        return true;
    }
}




import java.util.*;

/**
 * Description   : ControlCommandOpenMap, open map command
 * @author dbauman
 * @since   Jun 11, 2004
 *      Jun 11, 2004    (DBauman) Original Release
 */

public class ControlCommandOpenMap extends ControlCommandAbstract {
    public ControlCommandOpenMap(ControlParameters controlParameters) {
        super(controlParameters);
    }
    public boolean processCommand(ControlProcessing controlProcessing) {
        ControlParameters controlParameters = getControlParameters();
        if (!controlParameters.hasNext()) return false;
        String map = (controlParameters.nextToken()).trim();
        if (debug) System.out.println("Openmap: "+map);
        String statusCode = "OK";
        // DO THE WORK HERE!!!
        // statusCode = helper.openMap(map);
        try { // simulate that the commands takes real time
            Thread.sleep(3000);
        } catch (InterruptedException ie) {}
        //
        // we can cast because we know that we are of this 'interface' type
        ((ControlProcessingUI1)controlProcessing).setStatusCode(statusCode);
        return true;
    }
}




import java.util.*;

/**
 * Description   : ControlObservable, extends Observable, implements Runnable.
 * This is the 'other thread' which sends data to the Control portion.
 * Implement Runnable so that our 'run' method can be the result of
 * starting another Thread so that the controler/Observer can receive the notification
 * messages without blocking.
 * This class does all of the thread stuff, including the 'synchronizing'
 * @author dbauman
 * @since   DEC 17, 2003
 *      DEC 17, 2003    (DBauman) Original Release
 *      DEC 17, 2003    (DBauman) we also
 *   implement ControlProcessing so that we can tell the GUI when we are done processing.
 */

public class ControlObservable extends Observable implements Runnable {

  private ControlProcessing controlProcessing;

  /** constructor, starts our thread **/
  ControlObservable (ControlProcessing controlProcessing) {
    this.controlProcessing = controlProcessing;
    // start the processing thread
    new Thread(this).start();
  }

  /** a queue of commands to notify the observer with.
   ** The observer is on another thread, so we use this to
   ** pass the commands from one thread to another.
   **/
  private ArrayList cmds = new ArrayList();

  public boolean isEmpty () {
    return cmds.isEmpty(); // no need to be sychronized
  }

  public void addCommand (Object cmd) {
    synchronized(cmds) {
      cmds.add(cmd);
    }
  }


  /** Purpose: run method of another thread. Used
   ** solely by the notifyOurObserver method via the 'cmds'.  It is best to keep
   ** the observer (controller) in a separate thread from the GUI (view) because
   ** if the user presses a button twice during a test then nothing will happen.
   * Side Effects: 'cmds', a command is grabbed from this queue
   * State Read:   'cmds'
   * Assumptions:  We sleep for 100 ms between commands inside an infinite loop.
   **/
  public void run () {
    for(;;) {
      Object next = null;
      if (!cmds.isEmpty()) { // do this twice for efficiency
        synchronized(cmds) {
          if (!cmds.isEmpty()) { // have to do here inside the 'synchronized' at the very least
            next = cmds.get(0);
          }
        }
      }
      if (next != null) {
        setChanged();
        notifyObservers(next);
        clearChanged();
      }
      boolean empty = false;
      synchronized(cmds) {
        if (!cmds.isEmpty()) {
          cmds.remove(0); // finally remove the element
        }
        empty = cmds.isEmpty();
      }
      // processing complete, based on 'empty' flag
      // make sure not to do this inside the 'sychronized' block because it could be slow
      controlProcessing.processingComplete(empty);

      try {
        Thread.sleep(100);
      } catch (InterruptedException ie) {}
    }
  }
}



import java.io.*;
import java.util.*;
import java.lang.reflect.*;

/**
 * Description   : ControlObserver, used to control something, and acts as an observer
 * @author dbauman
 * @since   DEC 15, 2003
 *   DEC 15, 2003    (DBauman) Original Release
 * a controller : it uses Class.forName to load the 'instanceName' class which is the Observable
 * to our Observer.  Our 'update' method gets the commands from
 * that GUI and executes them.
 */

public class ControlObserver extends ControlObserverUpdate {
  /** the instance name of the GUI **/
  public static String instanceName = "ControlObservableUI";


  /** Purpose: main method
   * @param                     args, String[],
   * 
args[0]: can be: *
instanceName **/ public static void main (String[] args) { ControlObserver control = new ControlObserver(); if (args.length>0) { control.instanceName = args[0]; } System.out.println("instanceName (for GUI class): "+instanceName); control.debug = true; control.instanceGui(instanceName); control.start(); } }

import java.io.*;
import java.util.*;
import java.lang.reflect.*;

/**
 * Description   : ControlObserver, used to control something, and acts as an observer, abstract method to be extended
 * @author dbauman
 * @since   DEC 15, 2003
 *      DEC 15, 2003    (DBauman) Original Release
 *      Jun 11, 2004    (DBauman) was moved to this class
 * abstract reusable part of our controller : it uses Class.forName to load the 'instanceName' class which is the Observable
 * to our Observer.  Our 'update' method gets the commands from
 * that GUI and executes them.
 *
 */

public abstract class ControlObserverUpdate implements Observer {
  protected boolean debug=false;
  protected ControlProcessing instance = null;

  public void start() {
      instance.start();
  }
  /** Tries to instance a Gui
   * @param                     instanceName, String
   * @return instance
   **/
  public ControlProcessing instanceGui (String instanceName) {
    String methodName = "ControlObserver.instanceGui: ";
    try { // next try using Class.forName...
      if (debug) System.out.println(methodName+"trying :"+instanceName);
      Class guiClass = Class.forName(instanceName);
      if (debug) System.out.println(methodName+"guiClass: "+guiClass.getName());
      instance = (ControlProcessing) guiClass.newInstance();
      instance.addObserver(this);
      return instance;
    } catch (NoClassDefFoundError nc) {
      System.err.println(methodName+"no class definition found: "+instanceName);
    } catch (ClassCastException cc) {
      System.err.println(methodName+"can't Cast class: "+instanceName);
    } catch (InstantiationException ie) {
      System.err.println(methodName+"can't instantiate class: "+instanceName);
    } catch (ClassNotFoundException ex) {
      System.err.println(methodName+"can't find class: "+instanceName);
    } catch (IllegalAccessException iae) {
      System.err.println(methodName+iae.toString());
    }
    return null;
  }

  /** 
Purpose: this class is called when a GUI sends us data * @param obs, Observable * @param arg, Object **/ public void update(Observable obs, Object arg) { ControlParameters st = (ControlParameters) arg; ControlCommand command = st.getCommand(); if (debug) System.out.println("NEXT: "+command); boolean result = command.processCommand(instance); if (debug) System.out.println("RESULT: "+result); } }


import java.util.*;

/**
 * Description   : ControlParameters, contains objects passed to the control
 * @author dbauman
 * @since   DEC 17, 2003
 *
 *     DEC 17, 2003    (DBauman) Original Release
 */

public class ControlParameters {
  private ControlCommand command;
  public ControlCommand getCommand() {iterator=params.iterator(); return command;}
  public void setCommand(ControlCommand command) {this.command=command;}
  private Collection params = new LinkedList();
  private Iterator iterator;
  public void addParam(Object param) {params.add(param);}
  public boolean hasNext () {return iterator.hasNext();}
  public Object next() {return iterator.next();}
  public String nextToken() {return (String)next();}
}






import java.util.*;

/**
 * Description   : ControlProcessing interface, can indicate when processing is complete
 * @author dbauman
 * @since   DEC 17, 2003
 *      DEC 17, 2003    (DBauman) Original Release
 */

public interface ControlProcessing {

  public void processingComplete (boolean pc);
  /** pass along to 'controlObservable'
   ** with a line like this: 
   ** controlObservable.addObserver(observer); 
**/ public void addObserver(Observer observer); public void start(); }



public interface ControlProcessingUI1 extends ControlProcessing {
  /** set the text of the 'statusCode' text field **/
  public void setStatusCode(String status);
  /** set the text of the 'appMapItem' text field **/
  public void setAppMapItem(String val);
}






import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

/**
 * Description   : ControlObservableUI, used to control an engine by sending step commands.
 * This is the GUI, we contain an Observable (instance of ControlObservable).
 * When our buttons are pressed, we send commands to the Observer (Controller)
 * Implement ActionListener so that our actionPerformed method can
 * react to the buttons.
 * Implement Runnable so that our 'run' method can be the result of
 * starting another Thread so that the controler/Observer can receive the notification
 * messages without blocking our GUI thread.
 * @author dbauman
 * @since   DEC 15, 2003
 *      DEC 15, 2003    (DBauman) Original Release
 *      DEC 17, 2003    (DBauman) changed to contain an ControlObservable.
 */

public class ControlObservableUI implements ActionListener, ControlProcessingUI1 {

  /** set the text of the 'statusCode' text field **/
  public void setStatusCode(String status) {this.statusCode.setText(status);}
  /** set the text of the 'appMapItem' text field **/
  public void setAppMapItem(String val) {this.appMapItem.setText(val);}

  /** startup the observable thread **/
  private ControlObservable controlObservable = new ControlObservable(this);

  /** all of the GUI elements **/
  private JFrame frame;
  private JPanel top;
  private JLabel lab7;
  private JTextField map;
  private JTextField section;
  private JTextField item;
  private JTextField appMapItem;
  private JTextField statusCode;
  public static final String CENTER = "Center";
  private String BUSY = "Please wait until the last command is finished.";
  private static final String BLANKSPACE = "                    ";
  private String lab7text = "Processing Command";
  private String lab7tail= "..."+BLANKSPACE;
  /**Construct the Panel*/
  public ControlObservableUI() {
    top = new JPanel();
    Dimension dim = new Dimension(588, 160);
    top.setSize(dim);
    top.setPreferredSize(dim);
    JPanel panC = new JPanel();
    panC.setBorder(BorderFactory.createTitledBorder("Application Map"));
    JPanel pan8 = new JPanel();
    JPanel pan9 = new JPanel();
    JPanel pan10 = new JPanel();
    JPanel pan11 = new JPanel();
    JPanel pan12 = new JPanel();
    JPanel pan13 = new JPanel();
    lab7 = new JLabel(BLANKSPACE);
    JLabel lab5 = new JLabel("Application Map"+": ");
    JLabel lab10 = new JLabel("Status Code"+": ");
    JLabel lab11 = new JLabel("Section"+": ");
    JLabel lab12 = new JLabel("Item"+": ");
    JLabel lab13 = new JLabel("Item Value"+": ");
    map = new JTextField();
    section = new JTextField();
    item = new JTextField();
    appMapItem = new JTextField();
    statusCode = new JTextField();
    map.setColumns(28);
    section.setColumns(28);
    item.setColumns(28);
    appMapItem.setColumns(28);
    statusCode.setColumns(28);
    JButton b2 = new JButton("OpenMap");
    JButton b3 = new JButton("Clear");
    JButton b4 = new JButton("Exit");
    JButton b6 = new JButton("Get Item");
    JButton b6b = new JButton("Get Item Now");
    b2.setActionCommand("OpenMap");
    b2.addActionListener(this);
    b3.setActionCommand("Clear");
    b3.addActionListener(this);
    b4.setActionCommand("Exit");
    b4.addActionListener(this);
    b6.setActionCommand("GetItem");
    b6.addActionListener(this);
    b6b.setActionCommand("GetItemNow");
    b6b.addActionListener(this);
    panC.setLayout(new BoxLayout(panC, BoxLayout.Y_AXIS));
    pan8.setLayout(new BoxLayout(pan8, BoxLayout.X_AXIS));
    pan9.setLayout(new BoxLayout(pan9, BoxLayout.X_AXIS));
    pan10.setLayout(new BoxLayout(pan10, BoxLayout.X_AXIS));
    pan11.setLayout(new BoxLayout(pan11, BoxLayout.X_AXIS));
    pan12.setLayout(new BoxLayout(pan12, BoxLayout.X_AXIS));
    pan13.setLayout(new BoxLayout(pan13, BoxLayout.X_AXIS));
    pan8.add(lab5, CENTER);
    pan8.add(map, CENTER);
    pan9.add(lab11, CENTER);
    pan9.add(section, CENTER);
    pan10.add(lab12, CENTER);
    pan10.add(item, CENTER);
    pan11.add(lab13, CENTER);
    pan11.add(appMapItem, CENTER);
    pan12.add(lab10, CENTER);
    pan12.add(statusCode, CENTER);
    pan13.add(lab7, CENTER);
    pan13.add(b2, CENTER);
    pan13.add(b3, CENTER);
    pan13.add(b4, CENTER);
    pan13.add(b6, CENTER);
    pan13.add(b6b, CENTER);
    top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS));
    top.add(panC);
    panC.add(pan8);
    panC.add(pan9);
    panC.add(pan10);
    panC.add(pan11);
    panC.add(pan12);
    panC.add(pan13);
  }

  /** starts up the frame and adds the 'top' component to it;
   ** also starts up the observable thread (ControlObservable)
   **/
  public void start () {
    System.out.println("start");
    frame = new JFrame("ControlObservableUI");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          //notifyOurObserver("Exit");
          System.exit(1); // for the impatient user, otherwise would have to wait for cmd
        }
      });
    frame.getContentPane().add(top, CENTER);
    frame.pack();
    frame.setVisible(true);
  }

  /** pass along to 'controlObservable'**/
  public void addObserver(Observer observer) {
    System.out.println("adding: "+observer);
    controlObservable.addObserver(observer);
    System.out.println("done adding: "+observer);
  }

  /** show an information popup dialog using JOptionPane
   ** @param msg, String
   **/
  public void popupMessage (String msg) {
    JOptionPane.showMessageDialog(frame, msg,
                                  msg, JOptionPane.INFORMATION_MESSAGE);
  }

  /** processing complete will be called by ControlObservable class run thread **/
  public void processingComplete (boolean pc) {
    if (lab7 != null) {
      if (pc) {
        lab7.setText(BLANKSPACE);
      } else {
        lab7.setText(lab7text + lab7tail);
      }
    }
  }

  /** notify the observers by placing 'cmd' on the 'cmds' queue
   ** @param cmd, String
   **/
  private void notifyOurObserver (Object cmd) {
    lab7.setText(lab7text + lab7tail);
    controlObservable.addCommand(cmd);
  }
  /** notify the observers of the event.getActionCommand()
   ** with the params
   **/
  public void actionPerformed(ActionEvent event) {
    ControlParameters buf = new ControlParameters();
    if (event.getActionCommand().equalsIgnoreCase("OpenMap")) {
      if (!controlObservable.isEmpty()) {popupMessage(BUSY); return;}
      buf.setCommand(new ControlCommandOpenMap(buf));
      buf.addParam(map.getText());
    } else if (event.getActionCommand().equalsIgnoreCase("GetItem")) {
      if (!controlObservable.isEmpty()) {popupMessage(BUSY); return;}
      buf.setCommand(new ControlCommandGetItem(buf));
      buf.addParam(map.getText());
      buf.addParam(section.getText());
      buf.addParam(item.getText());
    } else if (event.getActionCommand().equalsIgnoreCase("GetItemNow")) {
        //if (!controlObservable.isEmpty()) {popupMessage(BUSY); return;}
      buf.setCommand(new ControlCommandGetItem(buf));
      buf.addParam(map.getText());
      buf.addParam(section.getText());
      buf.addParam(item.getText());
    } else if (event.getActionCommand().equalsIgnoreCase("Clear")) {
      map.setText("");
      section.setText("");
      item.setText("");
      statusCode.setText("");
      appMapItem.setText("");
      return; // because we don't need to 'notify'
    } else if (event.getActionCommand().equalsIgnoreCase("Exit")) {
      if (!controlObservable.isEmpty()) {popupMessage(BUSY); return;}
      buf.setCommand(new ControlCommandExit(buf));
    } 
    notifyOurObserver(buf);
  }

}

Friday, June 6, 2014

Updated for 2014: Pi to any precision ported to Dart





It used to take 7 to 10 seconds to do 1000 digits of Pi on my machine with the original version of Dart, which is was based on javascript.

The new version of dart (c. 2014) now calcuates 3500 digits of Pi in 1.88 seconds. My Java version is only slightly faster, 3500 digits of PI in 1.39 seconds.

Douglas Bauman
/** Pi
 * I found an old C program which 
 * prints out lots of digits of pi.
 * I ported it to java (and now to dart)
 *  © 2011 - © 2014 Douglas A. Bauman
 * Here it is in case you are interested.
 * -Doug
 */

class Pi {
 
    static final int MAXPRC = 20000;
    StringBuffer bufDigits;
    StringBuffer buf;
    StringBuffer bufTime;
    List<int> p; // = new List<int>(MAXPRC); // byte[]
    List<int> t; // = new List<int>(MAXPRC); // byte[]
    int q;

    Pi(){
    }

    setQ(int q) {
        this.q = q;
        bufDigits = new StringBuffer();
        bufDigits.write("digits: "+q.toString());
        buf = new StringBuffer();
        bufTime = new StringBuffer();
    }

    arctan(int s) {
        int n;
        t[0] = 1;
        div6(s);   /* t[] = 1/s */
        add5();
        n = 1;
        do {
            mul7(n);
            div6(s * s);
            div6(n += 2);
            if (((n-1) / 2) % 2 == 0) {
                add5();
            } else {
                sub8();
            }
        } while (!tiszero());
    }
 
    add5() {
        int j;
        for (j = q; j >= 0; j--) {
            if (t[j] + p[j] > 9) {
                p[j] += t[j] - 10;
                if (j>=0) p[j-1] += 1;
            } else {
                p[j] += t[j];
            }
        }
    }
 
    sub8() {
        int j;
        for (j = q; j >= 0; j--) {
            if (p[j] < t[j]) {
                p[j] -= t[j] - 10;
                if (j>=0) p[j-1] -= 1;
            } else {
                p[j] -= t[j];
            }
        }
    }
 
    mul7(int multiplier) {
        int b;
        int i;
        num carry=0;
        int digit = 0;
        for (i = q; i >= 0; i--) {
            b = (t[i] * multiplier + carry);
            digit = b % 10;
            carry = (b / 10).floor();
            t[i] = digit; //(byte)
        }
    }
    
    /* t[] /= l */
    div6(int divisor) {
        int i, b;
        num quotient, remainder = 0;
        for (i = 0; i <= q; i++) {
            b = (10 * remainder + t[i]);
            quotient = (b / divisor).floor();
            remainder = b % divisor;
            t[i] = quotient; // (byte)
        }
    }
    
    div4() {
        int i=0, d = 0;
        num c=0;
        for (; i <= q; i++) {
            c = ((10 * d + p[i]) / 4).floor();
            d = (10 * d + p[i]) % 4;
            p[i] = c; // (byte)
        }
    }
    
    mul4() {
        int i;
        num d=0;
        num c=0;
        for (i = q; i >= 0; i--) {
            d = (p[i] * 4 + c) % 10;
            c = (p[i] * 4 + c) / 10;
            p[i] = d.floor(); // (byte)
        }
    }
    
    bool tiszero() {
        int k;
        for (k = 0; k <= q; k++)
            if (t[k] != 0)
                return(false);
        return(true);
    }

    compute() {
        int i;
        print(getAppletInfo());
        print("..compute..");
        if (q > MAXPRC) {
            buf.write("Precision too large: "+q.toString()+", >MAX: "+MAXPRC.toString());
            return;
        }
 
        /* compute pi */
        p = new List<int>(MAXPRC+1);
        t = new List<int>(MAXPRC+1);
        for(int ii=0; ii<=q; ii++) {p[ii]=0; t[ii]=0;}

        DateTime startime = new DateTime.now();
        print("..arctan(2)..");
        arctan(2);
        print("..arctan(3)..");
        arctan(3);
        print("..mul..");
        mul4();

        DateTime endtime = new DateTime.now();
        Duration diff = endtime.difference(startime);
 
        /* print pi */
        bufTime.write(""+diff.toString()+
          " seconds to compute "+q.toString()+" digits of pi");
        print(bufDigits.toString());

        print("pi = ");
        i = 0;
        int km = 79;
        int f = 1;
        do {
          for (int k=0; i <= q && k < km; i++, k++) {
            buf.write(""+(p[i]==null?"?":p[i].toString()));
            if (i==0) buf.write(".");
          }
          print(buf.toString());
          buf = new StringBuffer();
          km+= f;
          f=0;
        } while (i <= q);

        print(buf.toString());
        print(bufTime.toString());
    }
    
    String getAppletInfo() {
        return "Pi by Douglas A. Bauman";
    }
}
main() {
    int q = 3500;
    print("calculating Pi for " + q.toString() + " digits...");
    Pi pi = new Pi();
    pi.setQ(q);
    pi.compute();

}

output:
calculating Pi for 3500 digits...
Pi by Douglas A. Bauman
..compute..
..arctan(2)..
..arctan(3)..
..mul..
digits: 3500
pi = 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208
99862803482534211706798214808651328230664709384460955058223172535940812848111745
02841027019385211055596446229489549303819644288109756659334461284756482337867831
65271201909145648566923460348610454326648213393607260249141273724587006606315588
17488152092096282925409171536436789259036001133053054882046652138414695194151160
94330572703657595919530921861173819326117931051185480744623799627495673518857527
24891227938183011949129833673362440656643086021394946395224737190702179860943702
77053921717629317675238467481846766940513200056812714526356082778577134275778960
91736371787214684409012249534301465495853710507922796892589235420199561121290219
60864034418159813629774771309960518707211349999998372978049951059731732816096318
59502445945534690830264252230825334468503526193118817101000313783875288658753320
83814206171776691473035982534904287554687311595628638823537875937519577818577805
32171226806613001927876611195909216420198938095257201065485863278865936153381827
96823030195203530185296899577362259941389124972177528347913151557485724245415069
59508295331168617278558890750983817546374649393192550604009277016711390098488240
12858361603563707660104710181942955596198946767837449448255379774726847104047534
64620804668425906949129331367702898915210475216205696602405803815019351125338243
00355876402474964732639141992726042699227967823547816360093417216412199245863150
30286182974555706749838505494588586926995690927210797509302955321165344987202755
96023648066549911988183479775356636980742654252786255181841757467289097777279380
00816470600161452491921732172147723501414419735685481613611573525521334757418494
68438523323907394143334547762416862518983569485562099219222184272550254256887671
79049460165346680498862723279178608578438382796797668145410095388378636095068006
42251252051173929848960841284886269456042419652850222106611863067442786220391949
45047123713786960956364371917287467764657573962413890865832645995813390478027590
09946576407895126946839835259570982582262052248940772671947826848260147699090264
01363944374553050682034962524517493996514314298091906592509372216964615157098583
87410597885959772975498930161753928468138268683868942774155991855925245953959431
04997252468084598727364469584865383673622262609912460805124388439045124413654976
27807977156914359977001296160894416948685558484063534220722258284886481584560285
06016842739452267467678895252138522549954666727823986456596116354886230577456498
03559363456817432411251507606947945109659609402522887971089314566913686722874894
05601015033086179286809208747609178249385890097149096759852613655497818931297848
21682998948722658804857564014270477555132379641451523746234364542858444795265867
82105114135473573952311342716610213596953623144295248493718711014576540359027993
44037420073105785390621983874478084784896833214457138687519435064302184531910484
81005370614680674919278191197939952061419663428754440643745123718192179998391015
91956181467514269123974894090718649423196156794520809514655022523160388193014209
37621378559566389377870830390697920773467221825625996615014215030680384477345492
02605414665925201497442850732518666002132434088190710486331734649651453905796268
56100550810665879699816357473638405257145910289706414011097120628043903975951567
71577004203378699360072305587631763594218731251471205329281918261861258673215791
98414848829164470609575270695722091756711672291098169091528017350671274858322287
18352093539657251210835791513698820914442100675103346711031336

0:00:01.846000 seconds to compute 3500 digits of pi

Tuesday, November 27, 2012

Douglas A. Bauman - Resume


Douglas A. Bauman





QUALIFICATIONS
Worked as a project team member, mentor and team lead/designer on a wide variety of projects including e-business/enterprise applications, Swing based applications, high-level artificial intelligence (AI) applications and distributed multiprocessor applications. Currently I’m working in a production group as development point contact responsible for maintaining a large suite of successful Enterprise applications as well as for the design and development of new features for the ever growing product line. Other qualifications include work as a lead Java developer at a company which provides ‘Heatmaps’, a web and desktop software analysis tool for the trading desk visualization market (stock market). Another development effort concerned the use of JavaBeans as an interface to Active-X clients as it is applied to business process automation. Also designed and worked with a team to develop a real-time blackboard architecture with advanced control of knowledge sources and their application to total plant diagnostics, incremental rule base development and deployment, inter-process and socket communications, and portable graphical user interfaces. My most recent interests are with respect to Java/SQL for business analysis, visualization and communication, in e-business, enterprise, client server, or desktop application environments.

I have experience in the following programming languages, environments and hardware:

Lang. Java PL/SQL C# C++ C VB Lisp OPS5 Pascal PL/M
Years 17 10 2 16 22 7 6 4 5 5
Tech. UML/
Rose
Design Patterns J2EE EJB JNDI JMS/
Java-mail
JDBC-
SQL
JSP Custom Tags Struts
Years 3 12 10 10 3 2 14 4 3 2
Tech. Swing Java Beans XML RMI JNI HTML/ Javascript Threads VAJ/
WSAD
Motif X-Wind
Years 15 10 4 3 4 12 4 3 8 10
Oper.
System
UNIX Oracle Solaris Win
95/98/ME
NT/2000
/XP
OS/2 DOS VMS Micro-
Proc.
Network/
Sockets
Years 15 6 6 8 8 2 10 8 5 10


WORK HISTORY

  • May, 2003-Present, Management Science Associates (M.S.A)
    • Senior engineer and team lead designing, developing and maintaining the Deal Management, Commercial Instructions and whole suite of Gabriel media applications; developed in Java, PL/SQL(Oracle) and other languages like Visual Basic, C++ and C#.
      • Functional specifications and design/architecture for the applications
      • J2EE development using Weblogic and WebSphere connected with an Oracle backend
      • Code testing using JUnit Suites for unit and integration testing.
      • Integration testing with the functional team including QA and Docs
      • Oracle 10 DB development of PL/SQL and performance tuning of  SQL.
      • Mentor junior programmers in all aspects of software development process
    • Architect/engineer designing, developing and maintaining an automation testing framework using the Rational testing suite (developed with Java).
    • Aug, 2001-April, 2003 Ciber, Inc (consultant for Transtar, Inc), Technical lead designing and developing web-based applications in the Java language using a number of the technologies specified in the Java 2 Enterprise Edition. Advanced e-business enterprise system for car and train control, car order, revenue, scheduling, inventory, security, personnel, customers and all aspects for Transtar Inc. Responsibilities include:
      • Lead developer and mentor for core team of developers.
      • Design and development of J2EE MVC2 infrastructure/architecture including EJB design patterns.
      • Development of functional requirements/specification documentation.
      • Designing business related enterprise applications.
      • Developing using Java in IBM's WebSphere Studio (WSAD), and deployed to WebSphere.
      • Analysis and design reviews for fulfillment of requirements, techniques, patterns, algorithms and correctness.
      • Pier code reviews for other developers, including aspects of style, correctness and documentation.
      • Business logic developed using session and entity EJBs, and data access objects using JDBC and SQL for DB2 and Oracle.
      • Code testing using JUnit Suites for unit and integration testing.
      • Worked with the Q/A personnel to bring product life cycle requirements to fulfillment; use of Webrunner and Rational test tools.
      • Presentation tier developed using JSP and Custom Tags using MVC2 servlet/processor view/controller architecture designed and developed at the start of the project.
    • Feb, 2000-Jul, 2001 NeoVision Hypersystems, Involved with the design and development of Java-Swing based Visualization and analytic tool for the trading desk visualization market. The Heatmap tool is designed to cut through the information using simple and effective financial visualization technology. The graphical interfaces give traders, analysts, money managers and risk managers the ability to act on key financial information quickly and effectively. The tool is almost entirely implemented in the latest Java platform, and can be deployed either to the desktop, an enterprise or as a web application. It communicates via the Internet to multiple existing financial data sources for the real-time market information as well as Oracle and other databases.
    • Jan, 1998- Feb, 2000 Signature Solutions (now called Alventive, Inc.), working on advanced business information technology solutions for manufacturing visualization, business process automation, and configuration of product lines. Worked on the development of a Power Switching Center knowledge base and object oriented framework. This Sales Force Automation product configuration module is used by the Siemens Energy and Automation division Sales Force to configure a Power Switching Center either standalone or as part of a Unit Substation in conjunction with a Switchboard configuration development and verification effort. Began work on the application of EJB as the middleware for a Sales Force Automation initiative over the internet and the use of Java Swing components on the client using the web

    • 1980-Jan, 1998 Senior Engineer, Westinghouse Science and Technology Center. Designed and led a team of developers including myself with the software architecture for the Temelin Monitoring and Diagnostic System. This multiple processor real time system provides plant maintenance, engineering and operations personnel with expert information on plant equipment and systems and guidance with respect to phenomenon such as stress, chemistry and vibration analysis. It is based on a centralized blackboard architecture supported by knowledge sources and a control mechanism. I also led a team of engineers with the development of the expert system rule bases and scheduling criteria built on this extensible architecture.

    • Spent several months investigating the Java Development Kit in order to determine its feasibility with respect to extending and porting the above architecture. Actually implemented a distributed client server version of the Diagnostic and Monitoring System based on Java RMI/Sockets.
    • Developed several Visual C++ GUI programs for Windows NT/95, also ported part of the UNIX based blackboard architecture to NT to facilitate its distributed and extensible nature.
    • Developed a portable object oriented Motif based graphical user interface library for UNIX workstations and applied it to several user interface requirements for a Mitsubishi steel plant expert system application. The library was used by other members of the development team.
    • Worked on two diagnostics and monitoring systems including a neutron noise vibration monitoring system for nuclear cores employing digital signal processing (DSP) techniques.
    • Developed an intelligent PC-based training program for power system harmonics.
    • Developed a generic interactive menu graphical user interface based on script files.
    • Worked on a switchboard/panelboard automatic configuration program using OPS-5 and C. This project evolved into additional customer order engineering applications.
    • Developed an expert system shell called MAESTRO and have worked extensively on various expert systems, including a Transportation people-mover rule base, a metal-impact detection system for a nuclear application, and a Gen-Aid, Turbine-Aid expert system for the Power Generation Division.
    • Developed a microprocessor based elevator simulator used to verify elevator controllers.
    • Worked on a microprocessor controlled voice synthesis and voice recognition system for use with elevator and robotics applications

    EDUCATION
    B. S., Electrical Engineering and Mathematics, Carnegie Mellon University, 1980
    M. S., Electronic and Computer Engineering, Carnegie Mellon University, 1984
    Three month AI Internship, Carnegie Mellon University Robotics Institute and Intelligent Systems Laboratory, 1984



    AWARDS RECEIVED
    · Westinghouse Signature Award of Excellence, 1996
    · Westinghouse Inventor Recognition Award, 1995



    PATENTS AWARDED
    · Artificial intelligence software shell for plant operation simulation, 1995, #5412756
    · Case-based knowledge source for artificial intelligence software shell, 1995, #5402524
    · Interruptibility / priority control scheme for artificial intelligence, 1995, #5402526
    · Control process for artificial intelligence software shell, 1995, #5398304
    · Plant maintenance with predictive diagnostics, 1993, #5311562
    · Method and apparatus for auto-calibration of signal conditioning electronics, #4642636
    · Method and apparatus for preventing inadvertent criticality in a nuclear fueled electric powering generating unit #4582672
    · Elevator system with speech synthesizer for audible information, #4400786


    EXTERNAL PUBLICATIONS
    · "Integrating Equipment Condition Monitoring and Diagnostics Systems with Advanced Plant Information Systems," 1995 IEEE Nuclear Science Symposium and Medical Imaging Conference.
    · "Advanced Plant Information Systems using Intelligent Monitoring and Diagnostics and the ALLY Plant Monitoring and Diagnostics System," 1993 SMirt Conference, Konstanz, Germany.

    Tuesday, February 14, 2012

    Binary Tree Iterator


    import java.util.*;

    /** Binary Tree (not balanced) by Douglas A. Bauman
    ** also includes Iterator operation on the tree (inorder)
    **/
    public class NodeT<T> implements Iterable<T>
    {
    Integer data;
    NodeT left;
    NodeT right;
    NodeT parent;
    /* iterator and iterable contracts */
    public Iterator<T> iterator() {
    NodeTIterator result = new NodeTIterator(this);
    return result;
    }
    private class NodeTIterator implements Iterator<T> {
    NodeT cur;
    public NodeTIterator(NodeT n) {
    this.cur = n.getLeftMost();
    }
    /* Returns true if the iteration has more elements. */
    public boolean hasNext() {
    return cur != null;
    }
    /* Returns the next element in the iteration.*/
    public T next() {
    T r = null;
    if (cur != null) {
    r = (T)cur;
    cur = ((NodeT)cur).getNext();
    }
    return r;
    }
    /* Removes from the underlying collection the last element returned by the iterator (optional operation). */
    public void remove() {throw new UnsupportedOperationException("remove not implemented for NodeTIterator");}
    }
    /* constructor */
    public NodeT(Integer data, NodeT parent) {
    this.data = data;
    this.parent = parent;
    }
    public NodeT getLeftMost() {
    NodeT n = this;
    while (n.left != null) {
    n = n.left;
    }
    return n;
    }
    public NodeT getNext() {
    if (right != null) {
    return right.getLeftMost();
    } else {
    NodeT n = this;
    while (n.parent != null && n == n.parent.right) {
    n = n.parent;
    }
    return n.parent;
    }
    }
    /* recursively insert the data as a new node at the appropriate place using inorder placement */
    public NodeT insert(NodeT n, Integer data, int level, NodeT parent) {
    if (n == null) {
    // create new node
    n = (NodeT) new NodeT(data, parent);
    } else if (((Integer)data).intValue() > ((Integer)n.data).intValue()) {
    n.right = insert(n.right, data, level+1, n);
    } else {
    n.left = insert(n.left, data, level+1, n);
    }
    return n;
    }

    /** inorder find data in the tree by iterating, will be O(N) because iteration is in sort order, so not a good algorithm */
    public NodeT find(Integer data) {
    NodeT cur = getLeftMost();
    while (cur != null) {
    System.out.println("searching :"+cur.data);
    if (cur.data.intValue() == data.intValue()) return cur;
    cur = cur.getNext();
    }
    return null;
    }

    /* recursively find the data: should be O(logN) if this were a balanced tree (but it's not), but if it were, then this would be the better search */
    public NodeT findrec(Integer data, int level) {
    System.out.println("finding...:"+data+", this.data:"+this.data+" level:"+level);
    if (right!=null && data.intValue() > this.data.intValue()) {
    System.out.println("searching right:"+right.data);
    return right.findrec(data, level+1);
    } else if (data.intValue() == this.data.intValue()) {
    System.out.println("eq");
    return this;
    } else if (left!=null && data.intValue() < this.data.intValue()) {
    System.out.println("searching left:"+left.data);
    return left.findrec(data, level+1);
    }
    return null;
    }

    public void dumpnode(String tag, int level) {
    System.out.println("data: "+data+
    " "+tag+", parent: "+(parent==null?"null":""+parent.data)+
    ", left: "+(left==null?"null":""+left.data)+
    ", right: "+(right==null?"null":""+right.data)
    //", level:" +level
    );
    }

    /** inorder dump of the tree, so the values come out sorted **/
    public void dumptree(String tag, int level) {
    NodeT cur = getLeftMost();
    while (cur != null) {
    System.out.print(" " + cur.data);
    cur = cur.getNext();
    }
    System.out.println("");
    }

    /** inorder recursive dump of the tree, so the values come out sorted **/
    public void dumptreerec(String tag, int level) {
    if (left != null) left.dumptreerec("left", level+1);
    dumpnode(tag, level);
    if (right != null) right.dumptreerec("right", level+1);
    }

    public void dump(String tag) {
    System.out.println("In-Order Dump ("+tag+")");
    dumptree("root", 1);
    }

    public static void main(String[] args) {
    int array[] = { 3, 9, 1, 4, 8, 2, 5, 7, 0, 6 };
    // this array will generate: __3__
    //data: 0 (left) / \
    //data: 1 (left) 1 9
    //data: 2 (right) /\ /
    //data: 3 (root) 0 2 4
    //data: 4 (left) \
    //data: 5 (left) 8
    //data: 6 (left) /
    //data: 7 (right) 5
    //data: 8 (right) \
    //data: 9 (right) 7
    // /
    // 6
    int i;

    NodeT base = new NodeT(array[0], null);
    String buffer = "after added node " + array[0];
    base.dump(buffer);
    for (i = 1; i < array.length; i++) {
    buffer = "after added node " + array[i];
    base = base.insert(base, array[i], 1, null);
    base.dump(buffer);
    }

    System.out.println("\nrecursive dump:");
    base.dumptreerec("root", 1);

    System.out.println("\nrecursively find 9:");
    NodeT n = base.findrec(9, 1);
    if (n==null) System.out.println("...can't find 9");
    else n.dumpnode("found", 1);

    System.out.println("\n iteratively find 9:");
    n = base.find(9);
    if (n==null) System.out.println("...can't find 9");
    else n.dumpnode("found", 1);

    System.out.println("\niterate.....");
    for(Object k : base) {
    System.out.println("next k:"+((NodeT)k).data);
    }
    }

    //output will look like this:
    // In-Order Dump (after added node 3)
    // 3
    // In-Order Dump (after added node 9)
    // 3 9
    // In-Order Dump (after added node 1)
    // 1 3 9
    // In-Order Dump (after added node 4)
    // 1 3 4 9
    // In-Order Dump (after added node 8)
    // 1 3 4 8 9
    // In-Order Dump (after added node 2)
    // 1 2 3 4 8 9
    // In-Order Dump (after added node 5)
    // 1 2 3 4 5 8 9
    // In-Order Dump (after added node 7)
    // 1 2 3 4 5 7 8 9
    // In-Order Dump (after added node 0)
    // 0 1 2 3 4 5 7 8 9
    // In-Order Dump (after added node 6)
    // 0 1 2 3 4 5 6 7 8 9
    //
    // recursive dump:
    // data: 0 left, parent: 1, left: null, right: null
    // data: 1 left, parent: 3, left: 0, right: 2
    // data: 2 right, parent: 1, left: null, right: null
    // data: 3 root, parent: null, left: 1, right: 9
    // data: 4 left, parent: 9, left: null, right: 8
    // data: 5 left, parent: 8, left: null, right: 7
    // data: 6 left, parent: 7, left: null, right: null
    // data: 7 right, parent: 5, left: 6, right: null
    // data: 8 right, parent: 4, left: 5, right: null
    // data: 9 right, parent: 3, left: 4, right: null
    //
    // recursively find 9:
    // finding...:9, this.data:3 level:1
    // searching right:9
    // finding...:9, this.data:9 level:2
    // eq
    // data: 9 found, parent: 3, left: 4, right: null
    //
    // iteratively find 9:
    // searching :0
    // searching :1
    // searching :2
    // searching :3
    // searching :4
    // searching :5
    // searching :6
    // searching :7
    // searching :8
    // searching :9
    // data: 9 found, parent: 3, left: 4, right: null
    //
    // iterate.....
    // next k:0
    // next k:1
    // next k:2
    // next k:3
    // next k:4
    // next k:5
    // next k:6
    // next k:7
    // next k:8
    // next k:9
    }

    Friday, December 2, 2011

    Pi to any precision ported to Dart


    try.dartlang.org/s/q2Ui

    Click the link, then click the button in the upper left part of the pane.

    It works in Chrome and Firefox, I'm not sure if they have it working in IE yet.

    It takes 7 to 10 seconds to do 1000 digits of Pi on my machine with Dart, which is based on javascript.
    With Java, it only takes 0.09 seconds, so java is way faster (so far).

    Doug

    /** Pi
    * I found an old C program which
    * prints out lots of digits of pi.
    * I ported it to java (and now to dart)
    * © 2011 Douglas A. Bauman
    * Here it is in case you are interested.
    * -Doug
    */

    class Pi {

    static final int MAXPRC = 20000;
    StringBuffer bufDigits;
    StringBuffer buf;
    StringBuffer bufTime;
    List<int> p; // = new List<int>(MAXPRC); // byte[]
    List<int> t; // = new List<int>(MAXPRC); // byte[]
    int q;

    Pi(){
    }

    setQ(int q) {
    this.q = q;
    bufDigits = new StringBuffer();
    bufDigits.add("digits: "+q);
    buf = new StringBuffer();
    bufTime = new StringBuffer();
    }

    arctan(int s) {
    int n;
    t[0] = 1;
    div6(s); /* t[] = 1/s */
    add5();
    n = 1;
    do {
    mul7(n);
    div6(s * s);
    div6(n += 2);
    if (((n-1) / 2) % 2 == 0) {
    add5();
    } else {
    sub8();
    }
    } while (!tiszero());
    }

    add5() {
    int j;
    for (j = q; j >= 0; j--) {
    if (t[j] + p[j] > 9) {
    p[j] += t[j] - 10;
    if (j>=0) p[j-1] += 1;
    } else {
    p[j] += t[j];
    }
    }
    }

    sub8() {
    int j;
    for (j = q; j >= 0; j--) {
    if (p[j] < t[j]) {
    p[j] -= t[j] - 10;
    if (j>=0) p[j-1] -= 1;
    } else {
    p[j] -= t[j];
    }
    }
    }

    mul7(int multiplier) {
    int b;
    int i;
    num carry=0;
    int digit = 0;
    for (i = q; i >= 0; i--) {
    b = (t[i] * multiplier + carry);
    digit = b % 10;
    carry = (b / 10).floor();
    t[i] = digit; //(byte)
    }
    }

    /* t[] /= l */
    div6(int divisor) {
    int i, b;
    num quotient, remainder = 0;
    for (i = 0; i <= q; i++) {
    b = (10 * remainder + t[i]);
    quotient = (b / divisor).floor();
    remainder = b % divisor;
    t[i] = quotient; // (byte)
    }
    }

    div4() {
    int i=0, d = 0;
    num c=0;
    for (; i <= q; i++) {
    c = ((10 * d + p[i]) / 4).floor();
    d = (10 * d + p[i]) % 4;
    p[i] = c; // (byte)
    }
    }

    mul4() {
    int i;
    num d=0;
    num c=0;
    for (i = q; i >= 0; i--) {
    d = (p[i] * 4 + c) % 10;
    c = (p[i] * 4 + c) / 10;
    p[i] = d.floor(); // (byte)
    }
    }

    bool tiszero() {
    int k;
    for (k = 0; k <= q; k++)
    if (t[k] != 0)
    return(false);
    return(true);
    }

    compute() {
    int i;
    print(getAppletInfo());
    print("..compute..");
    if (q > MAXPRC) {
    buf.add("Precision too large: "+q+", >MAX: "+MAXPRC);
    return;
    }

    /* compute pi */
    p = new List<int>(MAXPRC+1);
    t = new List<int>(MAXPRC+1);
    for(int ii=0; ii<=q; ii++) {p[ii]=0; t[ii]=0;}

    Date startime = new Date.now();
    print("..arctan(2)..");
    arctan(2);
    print("..arctan(3)..");
    arctan(3);
    print("..mul..");
    mul4();

    Date endtime = new Date.now();
    Duration diff = endtime.difference(startime);

    /* print pi */
    bufTime.add(""+diff.toString()+
    " seconds to compute "+q+" digits of pi");
    print(bufDigits.toString());

    print("pi = ");
    i = 0;
    int km = 79;
    int f = 1;
    do {
    for (int k=0; i <= q && k < km; i++, k++) {
    buf.add(""+(p[i]==null?'?':p[i]));
    if (i==0) buf.add(".");
    }
    print(buf.toString());
    buf = new StringBuffer();
    km+= f;
    f=0;
    } while (i <= q);

    print(buf.toString());
    print(bufTime.toString());
    }

    String getAppletInfo() {
    return "Pi by Douglas A. Bauman";
    }
    }
    main() {
    int q = 1000;
    print("calculating Pi for " + q + " digits...");
    Pi pi = new Pi();
    pi.setQ(q);
    pi.compute();

    }