Tuesday, June 30, 2009

Writing NSF Proposals

In preparing NSF proposals at The Cromwell Workshop, I think this is an excellent source for guidelines by Gisele Muller-Parker with "How to get NSF funding: a view from the 'inside'" at http://www.wwu.edu/depts/rsp/insideview.pdf . Some other examples include a budget proposal worksheet at http://www.stat.purdue.edu/resources/business_office/Sample_Budgetworksheet.pdf and a NSF proposal template at http://74.125.93.132/search?q=cache:3gpLNshV6zkJ:teesresearch.tamu.edu/documents/NSF/template/NSF_PROPOSAL_TEMPLATE.doc+NSF+proposal+document&cd=3&hl=en&ct=clnk&gl=us
that can be used to get started. In preparing the proposal, the author considers:

• Review NSF Award Abstracts (Fastlane)
• Talk to your NSF Program Director
• Talk to your colleagues; have experienced colleagues review a draft and comment
• Recruit and describe university infrastructure support for your proposed project
• Address the merit review criteria
• Compliance checks (GPG)

In addition, make sure that you have the following in mind before you begin:
  • Original ideas
  • Succinct, focused project plan
  • Cost effective
  • Knowledge and experience in the discipline
  • Experience in essential methodology
  • Realistic amount of work
  • Sufficient detail
  • Strong rationale or evidence of potential effectiveness

As far as the general NSF review, the author poses five questions each in two categories:

  1. What is the intellectual merit of the proposed activity?
  2. What are the broader impacts of the proposed activity?

For each of these, I would recommend answering the following questions in the construction of the first draft of the proposal.

The intellectual Merit:


1. How important is the proposed activity to advancing knowledge and understanding within its own field or across different fields?

2. How well qualified is the proposer to conduct the project?

3. To what extent does the proposed activity explore creative and original concepts?

4. How well conceived and organized is the proposed activity?

5. Is there sufficient access to necessary resources?

The Broader impact activities:


1. How well does the activity advance discovery and understanding while promoting teaching,
training and learning?

2. How well does the proposed activity broaden the participation of underrepresented groups?

3. To what extent will it enhance the infrastructure for research and education, such as
facilities,instrumentation, networks and partnerships?

4. Will the results be disseminated broadly to enhance scientific and technological understanding?

5. What may be the benefits of the proposed activity to society?

Finally, I like the author's 9 tips for writing the proposal. These are:

  1. Discuss size and scope of intellectual payoff
  2. Use plain, simple English
  3. Let no question fester
  4. Do not include extra stuff
  5. Put specifics in the Methods section
  6. Use tables, figures, and flow charts to save words
  7. Make it visually appealing (i.e. do not make reviewers curse you for making their job harder)
  8. Include sufficient budget justification
  9. Think of your proposal as the 40th in a stack

Using these guidelines in writing the proposal, more often than not you will receive high ratings for your proposal and increase the opportunity of getting funded.

Tuesday, April 14, 2009

Visualization of Direct Acyclic Graph Models

Graphviz at http://www.graphviz.org/About.php is visualization software that can be used to model direct acyclic graphs. For example, the code:

digraph G{
subgraph leftBrain{
node [style=filled, color=lightgrey];
A -> C [ label = "0.0" ];
C -> E [ label = "0.0" ];
}
subgraph middleBrain{
node [shape=circle, style=filled, color=white];
W -> K [ label = "0.0" ];
K -> V [ label = "0.0" ];
}
subgraph rightBrain{
node[style=filled, color=lightgrey];
B -> D [ label = "0.0" ];
D -> F [ label = "0.0" ];
}
start -> A [ label = "0.0" ];
start -> B [ label = "0.0" ];
start -> W [ label = "0.0" ];
A -> W [ label = "0.0" ];
B -> W [ label = "0.0" ];
D -> K [ label = "0.0" ];
C -> K [ label = "0.0" ];
E -> K [ label = "0.0" ];
F -> K [ label = "0.0" ];
F -> V [ label = "0.0" ];
E -> V [ label = "0.0" ];
E -> F [ label = "0.0" ];
A -> B [ label = "0.0" ];
D -> C [ label = "0.0" ];
V -> end [ label = "0.0" ];

start [shape=Mdiamond];
end [shape=Msquare];
}



generates the image in Figure 1.

Figure 1. Visual Representation




What I like about this application is that I can write the C# or Java code to read and write the above probability maps, i.e. the numerical quantities on the edges are the probabilities, into my software. As above the code illustrates, you can connect subgraphs together and assemble different types of networks for reasoning. This visualization tool then can help with insight into how intelligent agents are solving problems and provide the necessary illustrations for the publication process.

Wednesday, April 1, 2009

SimMetrics

Recently, I have been working on measuring the semantic distance between concepts in ontologies. One such tool is SimMetrics at http://www.dcs.shef.ac.uk/~sam/stringmetrics.html which is an open source extensible library in Java. The following string metrics are included in the package and can be found here at http://www.dcs.shef.ac.uk/~sam/stringmetrics.html with a corresponding description. These similarity measures can be found in statisics, DNA analysis, artificial intelligence, and information retrieval.

For example, the cosine similarity is a vector space measure:


/**
* SimMetrics - SimMetrics is a java library of Similarity or Distance
* Metrics, e.g. Levenshtein Distance, that provide float based similarity
* measures between String Data. All metrics return consistant measures
* rather than unbounded similarity scores.
*
* Copyright (C) 2005 Sam Chapman - Open Source Release v1.1
*
* Please Feel free to contact me about this library, I would appreciate
* knowing quickly what you wish to use it for and any criticisms/comments
* upon the SimMetric library.
*
* email: s.chapman@dcs.shef.ac.uk
* www: http://www.dcs.shef.ac.uk/~sam/
* www: http://www.dcs.shef.ac.uk/~sam/stringmetrics.html
*
* address: Sam Chapman,
* Department of Computer Science,
* University of Sheffield,
* Sheffield,
* S. Yorks,
* S1 4DP
* United Kingdom,
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package uk.ac.shef.wit.simmetrics.similaritymetrics;
import uk.ac.shef.wit.simmetrics.tokenisers.InterfaceTokeniser;
import uk.ac.shef.wit.simmetrics.tokenisers.TokeniserWhitespace;
import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
import java.io.Serializable;
/**
* Package: uk.ac.shef.wit.simmetrics.similaritymetrics.cosinesimilarity
* Description: uk.ac.shef.wit.simmetrics.similaritymetrics.cosinesimilarity implements a
* Date: 05-Apr-2004
* Time: 10:52:58
* @author Sam Chapman Website, Email.
* @version 1.1
*/
public final class CosineSimilarity extends AbstractStringMetric implements Serializable {
/**
* a constant for calculating the estimated timing cost.
*/
private final float ESTIMATEDTIMINGCONST = 0.00000038337142857142857142857142857142f;
/**
* private tokeniser for tokenisation of the query strings.
*/
private final InterfaceTokeniser tokeniser;
/**
* constructor - default (empty).
*/
public CosineSimilarity() {
tokeniser = new TokeniserWhitespace();
}
/**
* constructor.
*
* @param tokeniserToUse - the tokeniser to use should a different tokeniser be required
*/
public CosineSimilarity(final InterfaceTokeniser tokeniserToUse) {
tokeniser = tokeniserToUse;
}
/**
* returns the string identifier for the metric.
*
* @return the string identifier for the metric
*/
public String getShortDescriptionString() {
return "CosineSimilarity";
}
/**
* returns the long string identifier for the metric.
*
* @return the long string identifier for the metric
*/
public String getLongDescriptionString() {
return "Implements the Cosine Similarity algorithm providing a similarity measure between two strings from the angular divergence within term based vector space";
}
/**
* gets a div class xhtml similarity explaining the operation of the metric.
*
* @param string1 string 1
* @param string2 string 2
*
* @return a div class html section detailing the metric operation.
*/
public String getSimilarityExplained(String string1, String string2) {
//todo this should explain the operation of a given comparison
return null; //To change body of implemented methods use File Settings File Templates.
}
/**
* gets the estimated time in milliseconds it takes to perform a similarity timing.
*
* @param string1 string 1
* @param string2 string 2
*
* @return the estimated time in milliseconds taken to perform the similarity measure
*/
public float getSimilarityTimingEstimated(final String string1, final String string2) {
//timed millisecond times with string lengths from 1 + 50 each increment
//0 0.02 0.03 0.05 0.08 0.11 0.14 0.18 0.23 0.27 0.33 0.39 0.46 0.52 0.6 0.65 0.76 0.84 0.94 1.01 1.13 1.23 1.49 1.45 1.95 1.67 2.26 1.93 2.6 2.26 2.86 2.54 3.17 2.91 3.76 3.17 3.9 3.5 4.32 3.9 5.1 4.32 5.64 4.83 5.64 5.07 6.34 5.64 7.03 5.97 7.81 6.55 8.12 7 9.23 7.52 9.71 8.12 10.68 8.46
final float str1Length = string1.length();
final float str2Length = string2.length();
return (str1Length + str2Length) * ((str1Length + str2Length) * ESTIMATEDTIMINGCONST);
}
/**
* gets the similarity of the two strings using CosineSimilarity.
*
* @param string1
* @param string2
* @return a value between 0-1 of the similarity
*/
public float getSimilarity(final String string1, final String string2) {
final ArrayList str1Tokens = tokeniser.tokenizeToArrayList(string1);
final ArrayList str2Tokens = tokeniser.tokenizeToArrayList(string2);
final Set allTokens = new HashSet();
allTokens.addAll(str1Tokens);
final int termsInString1 = allTokens.size();
final Set secondStringTokens = new HashSet();
secondStringTokens.addAll(str2Tokens);
final int termsInString2 = secondStringTokens.size();
//now combine the sets
allTokens.addAll(secondStringTokens);
final int commonTerms = (termsInString1 + termsInString2) - allTokens.size();
//return CosineSimilarity
return (float) (commonTerms) / (float) (Math.pow((float) termsInString1, 0.5f) * Math.pow((float) termsInString2, 0.5f));
}
/**
* gets the un-normalised similarity measure of the metric for the given strings.
*
* @param string1
* @param string2
* @return returns the score of the similarity measure (un-normalised)
*/
public float getUnNormalisedSimilarity(String string1, String string2) {
return getSimilarity(string1, string2);
}
}

For some insight in using the toolkit, consider the paper by Cohen, et. al. from Carnegie Mellon University at http://www.isi.edu/info-agents/workshops/ijcai03/papers/Cohen-p.pdf provides an overview of similarity measures in matching entity names. In order to look at some the metrics in the paper that are not included in SimMetrics, I downloaded their jar of metrics at http://sourceforge.net/projects/secondstring/ and looked at the JavaDocs at http://secondstring.sourceforge.net/javadoc/. Thus, between these two jars, secondstring and SimMetrics, there are plenty of opportunities to build extensible libraries for developing and using semantic distance metrics.

Saturday, March 28, 2009

Arduino Library for Processing

I have already done some work with Arduino and C#.NET in an earlier post and now decided to extend the work to Java as well with the Processing software. For example, at http://www.arduino.cc/playground/Interfacing/Processing they provide the following Processing code:

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;
int ledPin = 13;
void setup()
{
//
println(Arduino.list());
arduino = new Arduino(this, Arduino.list()[0]);
// v2
//
arduino = new Arduino(this, Arduino.list()[0], 57600);
// v1
arduino.pinMode(ledPin, Arduino.OUTPUT);
}
void draw()
{
arduino.digitalWrite(ledPin, Arduino.HIGH);
delay(1000);
arduino.digitalWrite(ledPin, Arduino.LOW);
delay(1000);
}

that can be exported to an executable jar. Futhermore, the provide the Arduino jar and source code to control the board from Processing. A nice vehicle for getting up to speed quickly with Arduino applications. For other languages beside Java and C#, refer to http://www.arduino.cc/playground/Main/InterfacingWithSoftware .

Thursday, March 19, 2009

AML-Agent Modeling Language and StarUML

Agent Modeling Language(AML) is a visual modeling language that uses the concepts of Multi-Agent Systems (MAS) theory for specification and modeling of agents. For more information, please consult that paper at http://www.whitestein.com/library/whitestein_aml-specification_v09.pdf . The AML profiler can be downloaded for StarUML at http://www.whitestein.com/library/company-and-product-resources#methodology .

Figure 1. StarUML with an AML Example


Figure 1. shows the StarUML interface with an example AML. One of the features that I like is the modeling of ontologies for the agent. Figure 2. shows a medical example.
Figure 2. Example of an OntologyClass


Clearly, AML in StarUML offers some nice possibilities and demands further investigation. I recommend using it for modeling your agent based systems.

StarUML for Generating Java, C#, C++ code

This morning as I was doing research on building bridges to ontologies based on semantic distance and I thought about using StarUML to develop the UML products that I need for both my papers, books, projects and grant work. In the past, I used Visio for such things, but I wanted to do something different and be more immersed into the open source world. Here at http://sourceforge.net/project/screenshots.php?group_id=152825 you can download the application from Sourceforge.net. Figure 1 shows the UI.

Figure 1. StarUML with SVD C# Class

I decided to try out the application by reverse engineering a C# singular value decomposition class that I am modifying for another research paper. Below is a sample of the code generated from the class.
//
//
// Generated by StarUML(tm) C# Add-In
//
// @ Project : Untitled
// @ File Name : SingularValueDecomposition.cs
// @ Date : 3/19/2009
// @ Author :
//
//

public class SingularValueDecomposition {
private double[][] U ;
private double[][] k;
private double[][] V ;
private double[] s ;
private int m ;
private int z;
private int n ;
public SingularValueDecomposition(GeneralMatrix Arg){
}
private double[] SingularValues{
get{
}
}
private GeneralMatrix S{
get{
}
}
public virtual GeneralMatrix GetU(){
}
public virtual GeneralMatrix GetV(){
}
public virtual double Norm2(){
}
public virtual double Condition(){
}
public virtual int Rank(){
}
private void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context){
}
}

The application works but as you can see sometimes the code needs to be edited, but it does support UML 2.0. I am going through and looking at the bugs in the reverse engineering part. Since the source code is available-written in Delphi, it provides an opportunity to make changes to the application. For a full list of features, consult http://staruml.sourceforge.net/en/about-2.php . As you can see, there are many possible enhancements that can aid in the development of code. I plan to now use this for my UML artifacts.

Tuesday, March 17, 2009

Hidden Markov Models-Part 2

In a previous post in January on HMM, I mentioned the work of Jean-Marc Francois at http://code.google.com/p/jahmm/wiki/Overview with respect to building Hidden Markov Models (HMM) with his java library jahmm.jar. Of course, my interest in HMM is for these domains:
  • Speech recognition
    M. T. Chan, "HMM-based Audio Visual Speech Recognition Integrating Geometrics andAppearance-based Visual Features," presented at IEEE Workshop on Multimedia Signal Processing, Cannes, France, 2001.


  • Bioinformatics / Genomics
    Thomas Plötz, GernotA. Fink,"Pattern recognition methods for advanced stochastic protein sequence analysis using HMMs", Pattern Recognition, Volume 39, 2006


  • Robotics (robot sensing)
    Sven Koenig and Reid Simmons, A Robot Navigation Architecture Based on Partially Observable Markov Decision Process Models," in Artificial Intelligence Based Mobile Robotics:CaseStudies of Successful Robot Systems, D. Kortenkamp, R. Bonasso, and R. Murphy, Eds., pp. 91-122. MIT press, 1998.


  • Economics / Finance
    Rossi, Alessandro & Gallo, GiampieroM., 2006. "Volatility estimation via hidden Markov models," Journal of Empirical Finance, Elsevier, vol. 13(2), pages 203-230,

Here is his example of building a HMM with known parameters, generating a sequence of observations with the HMM, learning parameters, and computing probabilities for a coin flipping experiment. We can use the K-means to initialize the HMM and then use Baum-Welch to optimize. The dot file used in both of these cases can be converted to graph through the graphViz package. The Viterbi algorithm can be used for making predictions about the most probable state given the sequence of observations.

import java.util.*;
import be.ac.ulg.montefiore.run.jahmm.*;
import be.ac.ulg.montefiore.run.jahmm.toolbox.*;
import be.ac.ulg.montefiore.run.jahmm.learn.*;
import be.ac.ulg.montefiore.run.jahmm.draw.*;

public class HMM_CoinFlip {static public void main(String[] argv) throws java.io.IOException {
/*populate the data with N sequences of J binary coin flips, e.g. {{0,1,....,J},....,{0,1,...,J}}
int[][] data ={{}};
/* Read data into sequences */
Vector sequences = new Vector();
for (int i = 0; i < sequence =" new" j="0;" obs =" new" kml =" new" inithmm =" kml.learn();" bwl ="new" learnthmm =" bwl.iterate(initHmm);" i =" 0;" learnthmm =" bwl.iterate(learntHmm);}" http://www.biomedcentral.com/content/pdf/1471-2164-9-S1-S8.pdf and looked at their use of JahmmVix and GHMM Hidden Markov Model Editor. JahmmViz is the GUI for the library which uses Jung- a graph drawing library. The GUI can be obtained by using Java Web Start at
http://www.run.montefiore.ulg.ac.be/~francois/software/jahmm/jahmmViz/#use . GHMM can be downloaded at http://ghmm.sourceforge.net/hmmed.html and Java Web Started at http://casp.rnet.missouri.edu/hmmeditor/ . The User's manual is at http://casp.rnet.missouri.edu/hmmeditor/manual/HMMVE_1.1_manual.pdf.

Currently, I am experimenting with these libraries and will post more on my findings with some prototypes as I continue to assemble components together for this architecture.

Friday, March 13, 2009

NIH Funding-Part 2:Reading an RSS Feed in Java

In Part 1, I showed how to write an RSS Feed. Here I show how to use Java to read an RSS feed from the NIH link at http://grants.nih.gov/grants/guide/newsfeed/fundingopps.xml .

Step 1: The RSS Reader and Testing the Code

public class XmlRSSReader
{
public XmlRSSReader() {
try {
Builder bd = new Builder();
Document doc = bd.build("fundingopps.xml");
// Get the file's root element
Element root = doc.getRootElement();
Element channel = doc.getFirstChildElement("channel");
// Get its title element
Element title = channel.getFirstChildElement("title");
Text titleText = (Text)title.getChild(0);
Elements NIHs = root.getChildElements("item");
for (int i = 0; i < NIHs.size(); i++)
Element NIH = NIHs.get(i);
// Look for a title element inside it
Element itemTitle = NIH.getFirstChildElement("title");
// If found, look for its contents
if (itemTitle != null) {
Text itemTitleText = (Text) itemTitle.getChild(0);
// Good place to search the text
// do something
if (itemTitleText.toString().indexOf(searchTerm) == -1)
//do something
}
// Get all child elements of
Elements children = NIH.getChildElements();
for (int j = 0; j < children.size(); j++) {
Element child = children.get(j);
Text childText = (Text) child.getChild(0);
if (childText != null) {
System.out.print(child.getLocalName());
System.out.print(": ");
System.out.print(childText.getValue());
System.out.println("");
}

Step 2: Test the Code

public static void main(String[] arguments) {
XmlRSSReader xrss = new XmlRSSReader();
}
}

Clearly, we can combine RSS feeds and search for items on elements such as titles to build lists of common funding opportunities to reseachers.

Wednesday, March 11, 2009

NIH Funding-Part 1:Write an RSS Feed in Java

I wanted to be able to both read and write with RSS for examining NIH, NSF and other possible funding opportunities. In Part 1, I examine how to write a RSS read. The NIH link and a sample RSS Feed for the NIH is at http://grants.nih.gov/grants/guide/newsfeed/fundingopps.xml. My first step is to be able to create RSS Feeds like the one above in Java. Here I build on the work by http://www.vogella.de/articles/RSSFeed/article.html for the code.

Step 1: The Grant Model : RSSTest

package rss.grantmodel;

public class RSSTest
{
String title;
String description;
String link;
String researcher;
String guid;
String grant;
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getGrant(){ return grant;}
public void setGrant(String grant){this.grant=grant;}
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getLink() { return link; }
public void setLink(String link) { this.link = link; }
public String getResearcher() { return researcher; }
public void setResearcher(String researcher) { this.researcher = researcher; }
public String getGuid() { return guid; }
public void setGuid(String guid) { this.guid = guid; }
}

Step 2: RSSFeedItem

package rss.grantmodel;

import java.util.ArrayList;
import java.util.List;

public class RSSFeedItem{
List entries = new ArrayList();
String channel;
String title;
String link;
String description;
String language;
String copyright;
String pubDate;

public List getEntries() {
return entries; }
public void setEntries(List entries)
{ this.entries = entries; }
public String getTitle()
{ return title; }
public void setTitle(String title)
{ this.title = title; }
public String getLink()
{ return link; }
public void setLink(String link)
{ this.link = link; }
public String getDescription()
{ return description; }
public void setDescription(String description)
{ this.description = description; }
public String getLanguage()
{ return language; }
public void setLanguage(String language)
{ this.language = language; }
public String getCopyright() { return copyright; }
public void setCopyright(String copyright) { this.copyright = copyright; }
public String getPubDate() { return pubDate; }
public void setPubDate(String pubDate) { this.pubDate = pubDate; }

Step 3: Create the XML Writer

package rss.writefeed;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import rss.grantmodel.RSSTest;
import rss.grantmodel.RSSFeedItem;

public class RSSFeedWriter
{
private String outputFile;
private RSSTest rssfeed;
public void setFile(String configFile) { this.outputFile = configFile; }
public void setRssfeed(RSSTest rssfeed) { this.rssfeed = rssfeed; }
public void write() throws Exception {
// Create a XMLOutputFactory
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
// Create XMLEventWriter
XMLEventWriter eventWriter = outputFactory .createXMLEventWriter(new FileOutputStream(outputFile));
// Create a EventFactory XMLEventFactory
eventFactory = XMLEventFactory.newInstance();
XMLEvent end = eventFactory.createDTD("\n");
// Create and write Start Tag
StartDocument startDocument = eventFactory.createStartDocument();
eventWriter.add(startDocument);
// Create open tag
eventWriter.add(end);
StartElement rssStart = eventFactory.createStartElement("", "", "rss");
eventWriter.add(rssStart);
eventWriter.add(eventFactory.createAttribute("version", "2.0"));
eventWriter.add(end);
eventWriter.add(eventFactory.createStartElement("", "", "channel"));
eventWriter.add(end);
// Write the different nodes
createNode(eventWriter, "title", rssfeed.getTitle());
createNode(eventWriter, "link", rssfeed.getLink());
createNode(eventWriter, "description", rssfeed.getDescription());
createNode(eventWriter, "language", rssfeed.getLanguage());
createNode(eventWriter, "copyright", rssfeed.getCopyright());
createNode(eventWriter, "pubdate", rssfeed.getPubDate());
for (Iterator iterator = rssfeed.getEntries().iterator(); iterator .hasNext();)
{
RSSFeedItem entry = (RSSFeedItem) iterator.next();
eventWriter.add(eventFactory.createStartElement("", "", "item"));
eventWriter.add(end);
createNode(eventWriter, "title", entry.getTitle());
createNode(eventWriter, "description", entry.getDescription());
createNode(eventWriter, "link", entry.getLink());
createNode(eventWriter, "researcher", entry.getReseacher());
createNode(eventWriter, "guid", entry.getGuid());
eventWriter.add(end);
eventWriter.add(eventFactory.createEndElement("", "", "item"));
eventWriter.add(end); } eventWriter.add(end);
eventWriter.add(eventFactory.createEndElement("", "", "channel"));
eventWriter.add(end);
eventWriter.add(eventFactory.createEndElement("", "", "rss"));
eventWriter.add(end);
eventWriter.add(eventFactory.createEndDocument());
eventWriter.close(); }

private void createNode(XMLEventWriter eventWriter, String name, String value) throws XMLStreamException
{
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
XMLEvent end = eventFactory.createDTD("\n");
XMLEvent tab = eventFactory.createDTD("\t");
// Create Start node
StartElement sElement = eventFactory.createStartElement("", "", name);
eventWriter.add(tab); eventWriter.add(sElement);
// Create Content Characters characters = eventFactory.createCharacters(value); eventWriter.add(characters);
// Create End node
EndElement eElement = eventFactory.createEndElement("", "", name);
eventWriter.add(eElement);
eventWriter.add(end); }}

Step 4: Test the Grant Model

package rss.main;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Locale;
import rss.grantmodel.RSSTest;
import rss.grantmodel.RSSFeedItem;
import rss.writefeed.RSSFeedWriter;

public class Test {

public static void main(String[] args) {
// Create the rss feed
RSSTest rssFeedTest = new RSSTest();
// Add the information
rssFeedTest.setCopyright("Copyright by Jeff B. Cromwell");
rssFeedTest.setTitle("Grant Information");
rssFeedTest.setDescription("Grant Information");
rssFeedTest.setLanguage("en");
rssFeedTest.setLink(http://www.thecromwellworkshop.com/);
Calendar cal = new GregorianCalendar();
Date creationDate = cal.getTime();
SimpleDateFormat date_format = new SimpleDateFormat( "EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
rssFeedTest.setPubDate(date_format.format(creationDate));
//add one example item
RSSFeedItem feed = new RSSFeedItem();
feed.setTitle("RSSFeed");
feed.setDescription("This is a description");
feed.setAuthor(jbcromwell@thecromwellworkshop.com);
feed.setGuid("http://www.thecromwellworkshop.com/articles/RSSFeed/article.html");
feed.setLink("http://www.thecromwellworkshop.com/articles/RSSFeed/article.html");
rssFeedTest.getEntries().add(feed);
// Write the file
RSSFeedWriter writer = new RSSFeedWriter();
writer.setFile("articles.rss");
writer.setRssfeed(rssFeedTest);
try { writer.write(); }
catch (Exception e) { // e.printStackTrace(); } }
}

This can be easily extended to a servlet for the main method. This code enables us to generate a new RSS feed based on some categorical combination of funding sources. In Part 2, we will look at reading individual RSS feeds from different funding sources.

Thursday, March 5, 2009

Android: Mobile Device Applications

One of my students mentioned in class about the Android operating system for mobile devices that uses the Java programming language at http://code.google.com/android/. Applications are written in Java and bundled into an Android package that can be installed on mobile devices. For example, you can publish your app to the Android Market,

"Android Market is a hosted service that makes it easy for users to find and download Android applications to their Android-powered devices, and makes it easy for developers to publish their applications to Android users.

To publish your application on Android Market, you first need to register with the service using your Google account and agree to the terms of service. Once you are registered, you can upload your application to the service whenever you want, as many times as you want, and then publish it when you are ready. Once published, users can see your application, download it, and rate it using the Market application installed on their Android-powered devices.

To register as an Android Market developer and get started with publishing, visit the Android Market:
http://market.android.com/publish ".

I downloaded the sdk from http://developer.android.com/sdk/1.1_r1/index.html to get the android.jar to use with Eclipse. The HelloWorld example at http://developer.android.com/guide/tutorials/hello-world.html uses

package com.example.hello;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Youtube has some good videos on applications at http://www.youtube.com/watch?v=3LkNlTNHZzE show applications without borders. One of the great features is the com.google.android.maps and android.location which provides a spatial component for location based services such as resource tracking, proximity analysis and SMS messaging. Because it is written in Java, it is easy to interface with existing AI applications written in Java.

Wednesday, March 4, 2009

Drools: Java Rules Engine

Becuase of the commerical licensing issues with Jess, I wanted to look at an alternative source for my reasoning engines. As I mentioned in my last post on Jess, Drools is an open source rule engine at http://www.jboss.org/drools/ and implements the JSR94 API as well as an innovative semantics framework. A one minute tutorial is at http://legacy.drools.codehaus.org/1+Minute+DRL+Tutorial that shows DRL syntax, semantic modules-Base Semantic module and the Java semantic module. I like the example at http://www.theserverside.com/tt/articles/article.tss?l=Drools . I downloaded the binaries and attached both drools-core-4.0.7.jar and drools-compiler-4.0.7.jar as external jars to my project. The TestHelloWorldExample project in Eclipse is


import java.io.InputStreamReader;
import java.io.Reader;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.StatefulSession;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.common.DefaultAgenda;
import org.drools.compiler.PackageBuilder;
import org.drools.event.DebugAgendaEventListener;
import org.drools.event.DebugWorkingMemoryEventListener;
import org.drools.event.DefaultAgendaEventListener;
import org.drools.event.DefaultWorkingMemoryEventListener;
import org.drools.rule.Package;

public class TestHelloWorldExample {
/**
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
//read in the source
final Reader source = new InputStreamReader( TestHelloWorldExample.class.getResourceAsStream( "HelloWorld.drl" ) );
final PackageBuilder builder = new PackageBuilder();
//this wil parse and compile in one step
builder.addPackageFromDrl( source );
// Check the builder for errors
if ( builder.hasErrors() ) {
System.out.println( builder.getErrors().toString() );
throw new RuntimeException( "Unable to compile \"HelloWorld.drl\".");
}
//get the compiled package (which is serializable)
final Package pkg = builder.getPackage();
//add the package to a rulebase (deploy the rule package).
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage( pkg );
final StatefulSession session = ruleBase.newStatefulSession();
session.addEventListener( new DebugAgendaEventListener() );
session.addEventListener( new DebugWorkingMemoryEventListener() );
final WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( session );
logger.setFileName( "log/helloworld" );
final Message message = new Message();
message.setMessage( "Hello World" );
message.setStatus( Message.HELLO );
session.insert( message );
session.fireAllRules();
logger.writeToDisk();
session.dispose();
}
public static class Message {
public static final int HELLO = 0;
public static final int GOODBYE = 1;
private String message;
private int status;
public Message() {
}
public String getMessage() {
return this.message;
}
public void setMessage(final String message) {
this.message = message;
}
public int getStatus() {
return this.status;
}
public void setStatus(final int status) {
this.status = status;
}
}
}

The input for the HelloWorld.drl given by:

package org.drools.examples
import org.drools.examples.TestHelloWorldExample.Message;
rule "Hello World"
dialect "mvel"
when
m : Message( status == Message.HELLO, message : message )
then
System.out.println( message );
modify ( m ) { message = "Goodbyte cruel world",
status = Message.GOODBYE };
System.out.println( message );
end
rule "Good Bye"
dialect "java"
when
Message( status == Message.GOODBYE, message : message )
then
System.out.println( message );
end

Combining these applications with the example provided above provides the foundation for using rules in an open source Java application.

Embedding Jess in Java for Agent Models

I am working with the reasoning mechanism for my agent models and decided to use the backward and forward chaining methods found in Jess at http://www.jessrules.com/ . I can embed Jess in Java with the following code once I add the jess.jar to the library in an IDE like Eclipse and ran the code below shown in Figure 1.


Figure 1. Java and Jess in Eclipse


import jess.Deffacts;
import jess.Fact;
import jess.JessException;
import jess.RU;
import jess.Rete;
import jess.Value;
/*
public class testJess {
/*

public static void main(String[] args) throws JessException {

String buff;
/*define instance for jess interface class*/
Rete engine = new Rete();
engine.batch("testFacts.clp");
engine.reset();
buff = "(facts)";
engine.eval(buff);
buff = "(assert (birthday Jeff))";
engine.eval(buff);/* execute it */
buff = "(facts)";
engine.eval(buff);
engine.run();
System.out.println("Happy Birthday");
buff = "(facts)";
engine.eval(buff);
/* define new fact (template using API*/
engine.eval("(deftemplate point (slot x) (slot y))");
Fact f = new Fact("point", engine);
f.setSlotValue("x", new Value(37, RU.INTEGER));
f.setSlotValue("y", new Value(49, RU.INTEGER));
engine.assertFact(f);
buff = "(facts)";
engine.eval(buff);
}
}

The working memory of Jess has three parts which contains the deftemplate that defines the different kinds of facts contained in the deffacts. Defrule defines the rules to operate on the facts. This is my testfile-testFacts.clp:

(printout t "First Jess in Java" crlf)
(deftemplate personal-data
(slot name)
(slot age)
(slot weight)
(slot height)
(multislot blood-pressure)
)


(deffacts people
(personal-data (name Jeff) (age 48) (weight 220)
(height 200) (blood-pressure 130 80))
(personal-data (name David) (age 20) (weight 170)
(height 100) (blood-pressure 200 40)))


(defrule birthday
?birthday <- (birthday ?name) ?data-fact <- (personal-data (name ?name) (age ?age)) =>
(modify ?data-fact (age (+ ?age 1)))
(retract ?birthday)
)

Using this example, one can build text files of templates, facts and rules to read by the Rete engine in Java. Other examples like Jess are open source rule engines such as

  • Drools
  • Hannurapi Rules
  • JEOPS
  • JRuleEngine
  • Mandarax
  • Open Lexicon
  • Prova
  • SweetRules
  • Take
  • Termware
  • Zionis

For more information, check out http://www.businessreviewonline.com/os/archives/2008/07/10_best_open_so.html . One example that uses the Rete engine is Drools at http://www.jboss.org/drools/ . More on this in the next post.

References

Friedman-Hill, E. (2003). Jess In Action: Rule Based Systems in Java. Greenwich, CT: Manning Publications.

Tuesday, March 3, 2009

Data Exchange Engines for EHR Systems

One of the new areas of research for The Cromwell Workshop is in the area of electronic health record research. Orlova (2005) has a nice article on 21st Century Healthcare Systems at http://www.pubmedcentral.nih.gov/articlerender.fcgi?artid=1560434 . The authors state in their abstract,

"An electronic health record - public health (EHR-PH) system prototype was developed to demonstrate the feasibility of electronic data transfer from a health care provider, i.e. hospital or ambulatory care settings, to multiple customized public health systems which include a Newborn Metabolic Screening Registry, a Newborn Hearing Screening Registry, an Immunization Registry and a Communicable Disease Registry, using HL7 messaging standards. Our EHR-PH system prototype can be considered a distributed EHR-based RHIE/RHIO model - a principal element for a potential technical architecture for a NHIN."

Their steps for an EHR-PH system protoype based on the HL-7 messaging standard involved tracking information from the hospital of birth to 4 public health programs:

Step 1. EHR-Birth Record
Step 2. Hearing Screening
Step 3. Newborn Screening
Step 4. Immunization
Step 5. Communicable Disease Reporting
Step 6. Healthcare Enterprise Viewer

They used a MVC framework in J2EE for their prototype. The openEHR foundation uses Java at http://www.openehr.org/downloads/publications/health_ict/Medinfo2007-openehr_java-ChenKlein.pdf for development. Wikipedia has a nice article on EHR at http://en.wikipedia.org/wiki/Electronic_health_record with open source software at http://en.wikipedia.org/wiki/List_of_open_source_healthcare_software.

In the course of consulting opportunities with GIS, SQL Server and .NET, another example is the South Carolina Birth Data Exchange Engine (BEE) Program which exchanges birth population data with users in both a timely and secure fashion. The “BEE” program builds on integrated/interoperable systems that permits multiple agencies and health care providers, i.e. for immunization and newborn screening, to directly share or access needed birth information for mission-critical public health practices.

This got me thinking about "How to select an EHR system" in 12 steps at http://www.aafp.org/fpm/20050200/55howt.html and with my degrees in economics, what is happening in medical economics at http://medicaleconomics.modernmedicine.com/memag/article/articleDetail.jsp?id=131518 . Furthermore, I looked at MediTech at http://www.meditech.com/Interoperability/ehrHome.htm with their interoperability and EHR initiatives. Finally, they have an interview on their Data Exchange engine at http://www.meditech.com/Interoperability/pages/1108fa_interview.htm .

Thursday, February 19, 2009

R Interface to Weka for Statistical Learning

Weka is a Java based collection of machine learning algorithms for data mining tasks that contain tools for data pre-processing, classification, regression, clustering, association rules, and visualization at http://www.cs.waikato.ac.nz/~ml/index.html. An example of classification can be seen with the following applet at http://www.cs.technion.ac.il/~rani/LocBoost/.

R is an open source application for statistical computing and graphics that I use for modeling commodity prices and have discussed in publications located at TCW. Together, they form the R/Weka interface at http://cran.r-project.org/web/packages/RWeka/index.html . The working paper on this project is at http://epub.wu-wien.ac.at/dyn/virlib/wp/eng/mediate/epub-wu-01_ba6.pdf?ID=epub-wu-01_ba6 . I am doing some work in Weka because of its preference in computer science curriculums. A comparision of Weka and R can be found at http://74.125.47.132/search?q=cache:BNwL-HtkC4IJ:wiki.pentaho.com/download/attachments/3801462/ComparingWekaAndR.pdf%3Fversion%3D1+r+and+weka&hl=en&ct=clnk&cd=8&gl=us .

A good introduction to the interface is at http://statmath.wu-wien.ac.at/~zeileis/papers/DSC-2007a.pdf . For example, they show through R a list of the Weka interfaces:

R> list_Weka_interfaces()
$Associators
[1] "Apriori" "Tertius"
$Classifiers
[1] "AdaBoostM1" "Bagging" "DecisionStump" "IBk"
[5] "J48" "JRip" "LBR" "LMT"
[9] "LinearRegression" "Logistic" "LogitBoost" "M5P"
[13] "M5Rules" "MultiBoostAB" "OneR" "PART"
[17] "SMO" "Stacking"
$Clusterers
[1] "Cobweb" "DBScan" "FarthestFirst" "SimpleKMeans"
[5] "XMeans"
$Filters
[1] "Discretize" "Normalize"

I think it is worth the effort to combine these two technolgies in a middeware web service component to enhance existing AI applications. See our pubs for how to interface C#.NET with R.

Wednesday, February 18, 2009

Jadex for BDI Agent Programming

Currently, I am working on developing EBDI agents in both C#.NET and Java for my commodity price modeling research and decided to use as a protoype Jadex at http://jadex.informatik.uni-hamburg.de/bin/view/About/Overview . Jadex is very easy to use with permits development of autonomous intelligent agents in both XML and Java that can also be used with Jade. The central idea is to build a multi-agent community or society that use artifical intelligence concepts to do statistical modeling. You can download the 60 day trial version of Jadex-2-beta2 from the above site an run the jadex platform with the Jadex Control Center v2 for your project applications. Figure 1 shows the Jadex Control Center with the HelloWorld Agent example application.


Figure 1. Jadex Control Center

There are plenty examples here to learn as well as very good documentation on the BDI agent architecture with the version of 0.96x having a User Guide, Tutorial, and Toolguide at http://jadex.informatik.uni-hamburg.de/bin/view/Resources/Online+Documentation. The API for the examples is at http://jadex.informatik.uni-hamburg.de/docs/jadex-0.94x/examples/index.html . There garbage collector example provides a good example of beliefs, goals and plans. Figure 2 shows the environment agent.

Figure 2. Garbage Collector Environment


This agent shows the environment and produces items on it. There are two plans for this agent: (1) create the plan, (2) show the gui. The garbage burner agent has three beliefs: (1) environment, (2) the items at the current position, and (3) the actual position on the grid. The goal is to both (1) burn the items, and (2) pick up the items. Therefore, there has to be two plans: (1) burn plan and (2) pickup plan. The garbage collector agent is a little more complex by having similar beliefs as the garbage burner, but has an additional belief needed to determine if the item is dirty. The goals are: (1) run the grid and look for items, (2) go to a specified position, (3) pick up the item, and (4) take the item to a burner. Thus , we have 4 plans for these goals. The final agent, the manager agent determines the state: (1) one burner/one collector, (2) two burners/six collectors, and (3) two burners/two collectors.

Since plans are in Java and agents are in XML, the CreatePlan method shows the body of the plan in Java.


package jadex.bdi.examples.garbagecollector;
import jadex.bdi.runtime.Plan;
/**
* Create pieces of garbage in the environment.
*/
public class CreatePlan extends Plan
{
/**
* The plan body.
*/
public void body()
{
Environment env = (Environment)getBeliefbase().getBelief("env").getFact();
int garb_cnt = 0;
while(true)
{
// Add a piece of waste randomly.
waitFor(1000);
// Position pos = env.getFreePosition();
Position pos = env.getRandomPosition();
if(pos!=null)
{
env.addWorldObject(Environment.GARBAGE, "garbage#"+garb_cnt++, pos);
}
}
}
}

Thus, by working through the example above and other examples in the JCC with the on-site documentation, deploying BDI agents can be done quickly for agent based applications.

Research Gate


Research Gate at https://www.researchgate.net/ is a professional network for scientists. The above figure shows the options of profile, mesages, contacts, groups and research tools available to the scientist. The research tools use semantic relations for related publications, related researchers and groups. Publication information is searched through keywords and abstracts are parsed. The research vita page for my profile includes:
  1. Academic research projects
  2. Corporate research projects

  3. Education

  4. Additional training/courses

  5. Scholarship and grants

  6. Awards and Prizes

  7. Additional information such as teaching activity, board member, journal referee, scientific and society membership
The publication page consists of:
  • Journal articles

  • Conference proceedings/articles

  • Book articles or chapters

  • Theses

  • Patents
The research skills page includes:
  • Technical

  • Statistical

  • IT

  • Other
Another interesting feature is the ability to list in your personal library your favorite papers which you can import and export as an XML file. There are privacy, notification settings that are also important for the researcher. This week I will be doing research on this site to determine how effective it is with respect to building research communties.

Monday, February 16, 2009

C4 Brain Architecture for EBDI Agents

The Media Lab at MIT developed an layered brain architecture for Synthetic Creatures at http://web.media.mit.edu/~bruce/Site01.data/ijcai01.pdf that has the following discrete systems:

  • Sensory System
  • Perception System

  • Navigation System

  • Motor System

  • Working Memory

  • Blackboard

Another paper on C4 is at http://characters.media.mit.edu/Papers/gdc01.pdf . I like their use of the Percept Tree that is encoded in a Percept memory data structure which is matched to records in Working Memory. Of course, we can add emotion to the agents by using the work of Camuri and Coglio at http://www.kestrel.edu/home/people/coglio/mm98.pdf and the work by Jiang et al. on the EBDI(emotion, belief, desire and intention) framework at http://jmvidal.cse.sc.edu/papers/jiang07a.pdf. Specifically, the BDI agent has


  • Beliefs—knowledge about the environment

  • Desires—goals of the agent

  • Intentions—decisions about present and future behavior

MSDN has a good article on BDI agents for service orchestration at http://msdn.microsoft.com/en-us/library/bb898865.aspx and the authors state that a goal directed model can be used for application design:


"This model initially has high-level plans. These high-level plans are to achieve a sequence of goals. Each goal is achieved by a set of plans. If a goal can be achieved in different ways, it is further decomposed and separate plans are developed to achieve the goal. More plans can be added to the application at any time. The set of plans that are developed to achieve a goal is a service that is defined by the goal it fulfils."


As an example of their graph:


These BDI agents then dynamically build the application at runtime by selecting the appropriate plan out of a library of plans for the goal. An example of BDI using C#.NET is at http://www.blasteinn.com/robotdata/LegoRobot_Report.pdf . Another good article on BDI is Creating Interactive Characters with BDI agents at http://cfpm.org/~emma/pubs/NorlingSonenberg04.pdf that uses JACK- an automous systems development platform. I have downloaded the 60 day trail and read the manual at http://www.aosgrp.com/documentation/jack/Agent_Manual_WEB/index.html . A good powerpoint presentation is at http://www.mip.sdu.dk/~bbk/AOSE/JACK/19991029Coburn-AgentsMelb.pdf and http://goanna.cs.rmit.edu.au/~ssardina/courses/Roma07PhDcourse/lect09/busetta99jack.pdf as I attempt to build BDI agents with JACK in Java. More later.

RDF/XML and C#.NET

RDF (Resource Description Framework) is the standard for the Semantic Web. RDF can be mixed with C#.NET in an open source project called the semantic web at http://razor.occams.info/code/semweb/ . As stated by the authors, SemWeb is a

"... library can be used for reading and writing RDF (XML, N3), keeping RDF in persistent storage (memory, MySQL, etc.), querying persistent storage via simple graph matching and SPARQL, and making SPARQL queries to remote endpoints. Limited RDFS and general-purpose inferencing is also possible. SemWeb's API is straight-forward and flexible".

A basic "Hello World" application using SemWeb is

using System;
using SemWeb;

public class Example
{
const string RDF = http://www.w3.org/1999/02/22-rdf-syntax-ns#;

public static void Main() {
MemoryStore store = new MemoryStore();
Entity computer = new Entity("http://example.org/computer");
Entity says = "http://example.org/says";
Entity wants = "http://example.org/wants";
Entity desire = new BNode();
Entity description = new Entity("http://example.org/description");
store.Add(new Statement(computer, says, (Literal)"Hello world!"));
store.Add(new Statement(computer, wants, desire));
store.Add(new Statement(desire, description, (Literal)"to be human"));
store.Add(new Statement(desire, RDF+"type", (Entity)"http://example.org/Desire"));
using (RdfWriter writer = new RdfXmlWriter(Console.Out)) { writer.Namespaces.AddNamespace("http://example.org/", "ex");
writer.Write(store);
}
}
}

A discussion on this example and others can be found at http://razor.occams.info/code/semweb/semweb-current/doc/helloworld.html. Another example of a Semantic Web framework for .NET is LinqToRDF at http://code.google.com/p/linqtordf/. Andrew Matthews has an excellent LinqToRDF tutorial which shows how to create an ontology, link the ontology to .NET and query the ontology using SPARSQL. Creation of an ontology begins with XML namespaces for OWL, RDF and XML:


@prefix rdf: .
@prefix daml: .
@prefix log: .
@prefix rdfs: .
@prefix owl: .
@prefix xsdt: .
@prefix : .


followed by some classes for the ontology:


:Album a owl:Class.
:Track a owl:Class.
:title rdfs:domain :Track;
rdfs:range xsdt:string.
:artistName
rdfs:domain :Track;
rdfs:range xsdt:string.
:albumName
rdfs:domain :Track;
rdfs:range xsdt:string.
:year
rdfs:domain :Album;
rdfs:range xsdt:integer.
:genreName
rdfs:domain :Track;
rdfs:range xsdt:string.
:comment
rdfs:domain :Track;
rdfs:range xsdt:string.
:isTrackOn
rdfs:domain :Track;
rdfs:range :Album.
:fileLocation
rdfs:domain :Track;
rdfs:range xsdt:string.

Having used Linq in .NET 3.5 in VS.NET 2008, the following class Track links to the above ontology

using LinqToRdf;
namespace RdfMusic
{
[OwlResource(OntologyName="Music", RelativeUriReference="Track")]
public class Track : OwlInstanceSupertype
{
[OwlResource(OntologyName = "Music",
RelativeUriReference = "title")]
public string Title { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference="artistName")]
public string ArtistName { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference="albumName")]
public string AlbumName { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference="year")]
public string Year { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference="genreName")]
public string GenreName { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference="comment")]
public string Comment { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference="fileLocation")]
public string FileLocation { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference="rating")]
public int Rating { get; set; }
public Track(TagHandler th, string fileLocation)
{
FileLocation = fileLocation;
Title = th.Track;
ArtistName = th.Artist;
AlbumName = th.Album;
Year = th.Year;
9
GenreName = th.Genere;
Comment = th.Comment;
}
private EntityRef _Album { get; set; }
[OwlResource(OntologyName = "Music",
RelativeUriReference = "isTrackOn")]
public Album Album
{
get
{
if (_Album.HasLoadedOrAssignedValue)
return _Album.Entity;
if (DataContext != null)
{
var ctx = (MusicDataContext)DataContext;
string trackUri = this.InstanceUri;
string trackPredicateUri =
this.PredicateUriForProperty(MethodBase.GetCurrentMethod());
_Album = new EntityRef(
from r in ((MusicDataContext)DataContext).Albums
where r.StmtObjectWithSubjectAndPredicate(trackUri,
trackPredicateUri)
select r);
return _Album.Entity;
}
return null;
}
}
public Track()
{
}
}

One of the nice features of the open source C# semWeb is the RDFS inferencing engine with

using System;
using System.IO;
using SemWeb;
using SemWeb.Inference;

public class EulerTest {
public static void Main() {
// Create the instance data
MemoryStore dataModel = new MemoryStore();
BNode me = new BNode("me");
BNode you = new BNode("you");
Entity rdfType = http://www.w3.org/1999/02/22-rdf-syntax-ns#type;
Entity rdfsLabel= http://www.w3.org/2000/01/rdf-schema#label;
Entity foafPerson = http://xmlns.com/foaf/0.1/Person;
Entity foafAgent = http://xmlns.com/foaf/0.1/Agent;
Entity foafName = http://xmlns.com/foaf/0.1/name;
dataModel.Add(new Statement(me, rdfType, foafPerson));
dataModel.Add(new Statement(you, rdfType, foafPerson));
dataModel.Add(new Statement(me, foafName, (Literal)"John Doe"));
dataModel.Add(new Statement(you, foafName, (Literal)"Sam Smith"));
// Create the RDFS engine and apply it to the data model.
RDFS engine = new RDFS();
engine.LoadSchema(RdfReader.LoadFromUri(new Uri(http://xmlns.com/foaf/0.1/index.rdf)));
dataModel.AddReasoner(engine);
// Query the data model
// Ask for who are typed as Agents.
Note that the people are
// typed as foaf:Person, and the schema asserts that foaf:Person
// is a subclass of foaf:Agent.
Console.WriteLine("Who are Agents?");
foreach (Entity r in dataModel.SelectSubjects(rdfType, foafAgent))
Console.WriteLine("\t" + r);
// Ask for the rdfs:labels of everyone. Note that the data model
// has foaf:names for the people, and the schema asserts that
// foaf:name is a subproperty of rdfs:label.
Console.WriteLine("People's labels:");
foreach (Statement s in dataModel.Select(new Statement(null, rdfsLabel, null))) Console.WriteLine("\t" + s);
}
}

In addition, there is backward-forward-backward chaining reasoning with Euler path detection-"don't step in your own steps". For more information on Euler, look at http://www.agfa.com/w3c/euler/. Thus, in the construction of intelligent autonomous Agent based models in C#, there are opportunities to implement rule based engines with ontologies.

Anatomic Pathology Laboratory Information Systems

In the course of consulting, I review Dice.com and in the process I learn much about technologies from the job descriptions. For example, a HL7 integration engineer needs to have experience with HL7 in order to design and implement the integration of Digital Pathology products with Anatomic Pathology Laboratory Information Systems (APLIS). Interesting... HL7 at http://www.hl7.org/ is the ANSI protocols for clinical and adminstrative health data, i.e. pharamacy, medical devices, imaging or insurance transactions. Basically, a XML protocol for interoperability between heterogeneous databases.

To find out more about APLIS, I read the Tuthill (2008) article on how to implement an anatomic pathology information system and the conversion of

"Approximately 2.5 million anatomic pathology cases and reports were taken from our legacy system and converted into electronic files in the CoPathPlus database."

So, this seems that APLIS is an ERP for laboratories that could be SOA\WEB 2.0 based. This link, http://www.health-infosys-dir.com/yphclis.asp, provides a listing of Laboratory Information Systems with associated web sites. As an example, Antek Healthware has a product LabDAQ at http://www.antekhealthware.com/products/labdaq/index.php that shows how LabDAQ is used as a middleware to collect results from lab analyzers that is fed into electronic medical records.

In the latest issue of LabMedicine at http://labmed.ascpjournals.org/content/current , the article by Berte (2009) states that

"All laboratory work takes place as a series of interconnected processes, from the time the test or examination is ordered by a clinician to the time the result report is available for patient diagnosis or treatment. These interconnected processes are known as the laboratory’s preanalytic, analytic, and post-analytic path of workflow."

Something to think about with interconnected processes and preanalytic, analytic and post-analytic paths in the workflows.

In addition to the above, it seems it is important to know clinical data, architecture, patient management systems, controlled medical vocabularies, DICOM, HL7 CDA, CCOW, IHE workflows, SNOMED. In addition, a basic understanding of HIPAA, identity management, auditing, and access control as well as experience with interface engines: CloverLeaf, OpenEngine, ConnectR, and BizTalk.

Thus, these job descriptions provide an invaluable tool for developing a mental map of the solutions and technologies in different problem domains.


References

Tuthill, M. (2008). Automating Anatomic Pathology. Health Management Technology. Retrieved on February 16, 2009 from http://www.healthmgttech.com/features/2008_march/0308_automating.aspx .

Berte, L. (2009). Technology Will Solve Our Problems...Not! Lab Medicine 40:75-76.

Wednesday, February 11, 2009

Google Visualization and SciVee

Last night I was watching a video on Ted.Com and viewed the graphics of the statistics presented from Gapminder.Org. This got me thinking about using the Google Visualization API Gadget Gallery at the Google Gadget Library along with SciVee for video of my research at SciVee. For visualization, here is an example of using data with their Gauge chart.

function drawGauge() {
gaugeData = new google.visualization.DataTable();
gaugeData.addColumn('number', 'Engine');
gaugeData.addColumn('number', 'Torpedo');
gaugeData.addRows(2);
gaugeData.setCell(0, 0, 120);
gaugeData.setCell(0, 1, 80);

gauge = new google.visualization.Gauge(document.getElementById('gauge'));
gaugeOptions = {
min: 0,
max: 280,
yellowFrom: 200,
yellowTo: 250,
redFrom: 250,
redTo: 280,
minorTicks: 5
};
gauge.draw(gaugeData, gaugeOptions);
}

function changeTemp(dir) {
gaugeData.setValue(0, 0, gaugeData.getValue(0, 0) + dir * 25);
gaugeData.setValue(0, 1, gaugeData.getValue(0, 1) + dir * 20);
gauge.draw(gaugeData, gaugeOptions);
}

at in the AJAX API Playground . A Test page for working on these Gadgets is at The Cromwell Workshop .

SciVee permits uploading video with scientific publications through the creation of a PubCast. Here you

  1. Create the Video for Your Paper
  2. Upload Your Paper and Video
  3. Sync Images and Paper to Video
  4. Review your Work and Inform co-authors
  5. Publish Your Pubcast

Furthermore, you can upload your publication to PubMed ID/DOI. There are some interesting videos on SciVee Videos .

Putting these two vehicles together further enhances both the publication and understanding of scientific collaboration.



Tuesday, February 10, 2009

Processing and Arduino

After a trip to the Mattress Factory Art Museum at (http://www.mattress.org/) in Pittsburgh. I have been thinking more and more about the visualization of multi-dimensional systems. In looking at the links from the last blog on agent models and GIS, I learned about the programming language "Processing" at http://processing.org/ . Since they are also doing work with Arduino,

"Processing is an open source programming language and environment for people who want to program images, animation, and interactions. It is used by students, artists, designers, researchers, and hobbyists for learning, prototyping, and production. It is created to teach fundamentals of computer programming within a visual context and to serve as a software sketchbook and professional production tool. Processing is an alternative to proprietary software tools in the same domain."

The work with Arduino at http://www.arduino.cc/ returns me to my work and thoughts on interfacing multiple sensor boards with XBee wireless technologies for the design of a human interface that monitors EKG and EEG signals as well as body movements to construct painting videos. Below is the user Interface shown in Figure 1. which is the same as Arduino's for writing programs.

Figure 1. Windows GUI with Animated Sprite Program.





More on this later.

GIS and Agent Modeling

Research into both GIS and Agent Modeling has led to this blog at http://gisagents.blogspot.com/:

"GIS and Agent-based modelling is written by Dr. Andrew Crooks, it aims at highlighting and examining the latest advances in the fields of agent-based modelling and GIS. Furthermore the blog highlights current research into these fields at the Centre for Advanced Spatial Analysis (CASA), University College London."

There are many good resources with papers and links for anyone interested in doing GIS with agent modeling.

Wednesday, February 4, 2009

FreeSwitch and .NET

I have been reading the complete IP Telephony eBook by ShoreTel along with the white papers and decided that I wanted to go further into this technology. Here are some of the advantages of IP Telephony solutions:
  1. Business application integration (for CRM database)
  2. Calendar integration
  3. Call waiting
  4. Caller ID
  5. Click-of-a-mouse simplicity—employees
    make or transfer calls right on their
    computer
  6. Conference call with document sharing
  7. Contact screen and caller information
  8. Desktop application (i.e., Microsoft
    Outlook) integration
FreeSwitch (FS) at (http://en.wikipedia.org/wiki/FreeSWITCH) is an open source communication platform for voice and chat driven products written in C that can be interfaced with applications written in C/C++, Java, .NET, PHP, Python, etc. It provides the ability to do:
  • Conferencing
  • XML-RPC control of live calls
  • IVR
  • TTS/ASR
  • PSTN
  • Voice over IP
For more general information, contact http://wiki.freeswitch.org/wiki/Main_Page . Michael Jerris has a good introduction to FS at http://taug.ca/files/Freeswitch-Intro.pdf . You can interface with FS by:
  • XML-RPC
  • Event Socket
  • Embedded Languages
  • Modules
  • ODBC
  • CDR
  • XML

I downloaded the pre-built binaries to get a view of the application, see Figure 1. The FreeSwitch Home Page is at (http://www.freeswitch.org/docs/).

Figure1 . Console Applications of FreeSwitch


From here, I downloaded the source code for all 128 projects into Visual C++ 2008 Express Edition, see Figure 2. From there, I did the build (It seem to take forever) all the projects with modules, downloads, etc. successfully and ran the FreeSwitchConsole Application.

Figure 2. FreeSwitch Visual Studio 2008 Express




The modules for FS at (http://wiki.freeswitch.org/wiki/FreeSwitch_Modules) have a java module that can be implemented from http://wiki.freeswitch.org/wiki/Java . The next step is to do some sample code to show some of the features of using this application. There are several examples at http://wiki.freeswitch.org/wiki/Category:Examples . The Answering Machine example in Javascript is interesting; however, in future posts I plan to include some .NET examples to provide additional insight into how to use and integrate these modules into your business needs.

Friday, January 30, 2009

Genetic Algorithms:Loss Functions

Steinwart's paper on "How to compare different loss functions and Risks" at http://www.c3.lanl.gov/ml/pubs/2005_loss/paper.pdf , sets the stage for modifying the Genetic Algorithm component of Kirillov mentioned in a previous post. He uses for the Evaluate function the Absolute value loss function, given by

error += Math.Abs( y - data[i + windowSize] )

The entire method is presented below:

public double Evaluate( IChromosome chromosome )
{
// get function in polish notation
string function = chromosome.ToString( );

// go through all the data
double error = 0.0;
for ( int i = 0, n = data.Length - windowSize - predictionSize; i < n; i++ )
{
// put values from current window as variables
for ( int j = 0, b = i + windowSize - 1; j < windowSize; j++ )
{
variables[j] = data[b - j];
}

// avoid evaluation errors
try
{
// evaluate the function
double y = PolishExpression.Evaluate( function, variables );
// check for correct numeric value
if ( double.IsNaN( y ) )
return 0;
// get the difference between evaluated value and
// next value after the window, and sum error

error += Math.Abs( y - data[i + windowSize] );

}
catch
{
return 0;
}
}

// return optimization function value
return 100.0 / ( error + 1 );
}


In a presentation by Wang and Zhang on "Risk and Loss Functions" at http://www.ee.columbia.edu/~dpwe/mlsp/yong-chap3.pdf , the authors review squared error Loss, Huber's Robust Loss, Absolute Loss, and e-sensitive Loss. They provide some applied examples that work well with Steinwart's work. Clearly, here is an example where one can add value by creating a class of loss functions that are tied to the empirical probability density function (pdf) of the observed data. Of course, this class can be reused in other estimation problems as well.

Tesla and CUDA

The new NVIDIA Tesla GPU computing solution for businesses that do CAD/CAM/CE, Imaging, and GIS for their clients provides personal supercomputing power which the company states is 250 times faster than standard PCs. Tesla uses the NVIDIA's CUDA parallel computing architecture and costs less that $10,000. A YouTube video or commercial can be examined at http://www.youtube.com/nvidiatesla . Developing with CUDA at
http://www.nvidia.com/object/cuda_learn.html provides the necessary toolkit and SDK to program in C for Tesla. There is a good article on "Parallel Processing with CUDA" at
http://www.nvidia.com/docs/IO/55972/220401_Reprint.pdf .

For example of both CPU and CUDA code, Consider matrix addition example by Seland at
http://heim.ifi.uio.no/~knutm/geilo2008/seland.pdf .

A: CPU Code

void add_matrix
( float* a, float* b, float* c, int N ) {
int index;
for ( int i = 0; i < N; ++i )
for ( int j = 0; j < N; ++j ) {
index = i + j*N;
c[index] = a[index] + b[index];
}
}
int main() {
add_matrix( a, b, c, N );
}

B: CUDA Code

//Compute Kernel
__global__
void add_matrix
( float* a, float* b, float* c, int N ) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
int index = i + j*N;
if ( i < N && j < N )
c[index] = a[index] + b[index];
}


int main() {
dim3 dimBlock( blocksize, blocksize );
dim3 dimGrid( N/dimBlock.x, N/dimBlock.y );
add_matrix<<>>( a, b, c, N );
}

Notice that the double for loop for the CPU is placed with a grid. This presentation examines the use of threads in thread blocks contained in a grid of thread blocks. We can extend the main function:

//Define Grid Size

const int N=1024;
const int blocksize=16;

int main() {

//CPU Memory allocation

float *a = new float[N*N];
float *b = new float[N*N];
float *c = new float[N*N];
for ( int i = 0; i < N*N; ++i ) {
a[i] = 1.0f; b[i] = 3.5f; }

//GPU Memory allocation

float *ad, *bd, *cd;
const int size = N*N*sizeof(float);
cudaMalloc( (void**)&ad, size );
cudaMalloc( (void**)&bd, size );
cudaMalloc( (void**)&cd, size );

//Copy data to GPU

cudaMemcpy( ad, a, size, cudaMemcpyHostToDevice );
cudaMemcpy( bd, b, size, cudaMemcpyHostToDevice );

//Execute Kernel

dim3 dimBlock( blocksize, blocksize );
dim3 dimGrid( N/dimBlock.x, N/dimBlock.y );
add_matrix<<>>( ad, bd, cd, N );

//Copy result back to CPU

cudaMemcpy( c, cd, size, cudaMemcpyDeviceToHost );

//Clean Up and Return

cudaFree( ad ); cudaFree( bd ); cudaFree( cd );
delete[] a; delete[] b; delete[] c;
return EXIT_SUCCESS;
}

Following these basics and using the examples in the CUDA sdk, one can easily be running parallel programs for your GIS and imaging applications on your very own personal supercomputer.

Genetic Programming for Time Series

In the last couple of blogs, I mentioned about work on my research papers and I wanted to take a moment and point out the work of "Time Series Prediction Using Genetic and Gene Expression Programming", a C# sample done by Kirillov at

http://www.codeproject.com/KB/recipes/aforge.aspx

Figure 1 shows the interface for obtaining the prediction of a growing siusoid.

Figure 1. Genetic Programming Interface



The application using three Aforge components, AForge, AForge.Genetic, AForge.Controls for the estimation and interface. Since the copyright permits re-distribution for non-commerical use, I wanted to include it here to give an idea how to quickly one can create an application from an existing framework for the prediction of univariate time series such as stock prices. Also, not the framework construction, the use of worker threads. There is a worker thread, SearchSolution, for find the solution and two delegates for asynchronous calls to set control properties.

private delegate void SetTextCallback( System.Windows.Forms.Control control, string text )
private delegate void AddSubItemCallback( System.Windows.Forms.ListView control, int item, string subitemText )

I have remove some of the code because of length, in the declation of controls region, and the initializeComponent() method.


// AForge Framework
// Time Series Prediction using Genetic Programming and Gene Expression Programming
//
// Copyright © Andrew Kirillov, 2006
// andrew.kirillov@gmail.com
//
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Threading;

using AForge;
using AForge.Genetic;
using AForge.Controls;

namespace TimeSeries
{
///


/// Summary description for Form1.
///

public class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.GroupBox groupBox1;

// remove the code for the sake of exposition
//
private double[] data = null;
private double[,] dataToShow = null;

private int populationSize = 40;
private int iterations = 100;
private int windowSize = 5;
private int predictionSize = 1;
private int selectionMethod = 0;
private int functionsSet = 0;
private int geneticMethod = 0;

private int headLength = 20;

private Thread workerThread = null;
private bool needToStop = false;

private double[,] windowDelimiter = new double[2, 2] { { 0, 0 }, { 0, 0 } };
private double[,] predictionDelimiter = new double[2, 2] { { 0, 0 }, { 0, 0 } };

// Constructor
public MainForm( )
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
chart.AddDataSeries( "data", Color.Red, Chart.SeriesType.Dots, 5 );
chart.AddDataSeries( "solution", Color.Blue, Chart.SeriesType.Line, 1 );
chart.AddDataSeries( "window", Color.LightGray, Chart.SeriesType.Line, 1, false );
chart.AddDataSeries( "prediction", Color.Gray, Chart.SeriesType.Line, 1, false );

selectionBox.SelectedIndex = selectionMethod;
functionsSetBox.SelectedIndex = functionsSet;
geneticMethodBox.SelectedIndex = geneticMethod;
UpdateSettings( );
}

///
/// Clean up any resources being used.
///

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent()
{
//
//Removed the code
//
this.components = new System.ComponentModel.Container();
}
#endregion

///
/// The main entry point for the application.
///

[STAThread]
static void Main( )
{
Application.Run( new MainForm( ) );
}

// Delegates to enable async calls for setting controls properties
private delegate void SetTextCallback( System.Windows.Forms.Control control, string text );
private delegate void AddSubItemCallback( System.Windows.Forms.ListView control, int item, string subitemText );

// Thread safe updating of control's text property
private void SetText( System.Windows.Forms.Control control, string text )
{
if ( control.InvokeRequired )
{
SetTextCallback d = new SetTextCallback( SetText );
Invoke( d, new object[] { control, text } );
}
else
{
control.Text = text;
}
}

// Thread safe adding of subitem to list control
private void AddSubItem( System.Windows.Forms.ListView control, int item, string subitemText )
{
if ( control.InvokeRequired )
{
AddSubItemCallback d = new AddSubItemCallback( AddSubItem );
Invoke( d, new object[] { control, item, subitemText } );
}
else
{
control.Items[item].SubItems.Add( subitemText );
}
}

// On main form closing
private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// check if worker thread is running
if ( ( workerThread != null ) && ( workerThread.IsAlive ) )
{
needToStop = true;
while ( !workerThread.Join( 100 ) )
Application.DoEvents( );
}
}

// Update settings controls
private void UpdateSettings( )
{
populationSizeBox.Text = populationSize.ToString( );
iterationsBox.Text = iterations.ToString( );
windowSizeBox.Text = windowSize.ToString( );
predictionSizeBox.Text = predictionSize.ToString( );
}

// Load data
private void loadDataButton_Click(object sender, System.EventArgs e)
{
// show file selection dialog
if ( openFileDialog.ShowDialog( ) == DialogResult.OK )
{
StreamReader reader = null;
// read maximum 50 points
double[] tempData = new double[50];

try
{
// open selected file
reader = File.OpenText( openFileDialog.FileName );
string str = null;
int i = 0;

//Read Data method removed
//
// Update prediction size
private void UpdatePredictionSize( )
{
if ( data != null )
{
// get new prediction size value
try
{
predictionSize = Math.Max( 1, Math.Min( 10, int.Parse(
predictionSizeBox.Text ) ) );
}
catch
{
predictionSize = 1;
}
// check if we have too few data
if ( data.Length - predictionSize - 1 < predictionsize =" 1;" text =" string.Empty;" i =" 0," n =" dataList.Items.Count;"> 1 )
dataList.Items[i].SubItems.RemoveAt( 1 );
}
}

// On button "Start"
private void startButton_Click( object sender, System.EventArgs e )
{
ClearSolution( );

// get population size
try
{
populationSize = Math.Max( 10, Math.Min( 100, int.Parse( populationSizeBox.Text
) ) );
}
catch
{
populationSize = 40;
}
// iterations
try
{
iterations = Math.Max( 0, int.Parse( iterationsBox.Text ) );
}
catch
{
iterations = 100;
}
// update settings controls
UpdateSettings( );

selectionMethod = selectionBox.SelectedIndex;
functionsSet = functionsSetBox.SelectedIndex;
geneticMethod = geneticMethodBox.SelectedIndex;

// disable all settings controls except "Stop" button
EnableControls( false );

// run worker thread
needToStop = false;
workerThread = new Thread( new ThreadStart( SearchSolution ) );
workerThread.Start( );
}

// On button "Stop"
private void stopButton_Click( object sender, System.EventArgs e )
{
// stop worker thread
needToStop = true;
while ( !workerThread.Join( 100 ) )
Application.DoEvents( );
workerThread = null;
}

// Worker thread
void SearchSolution( )
{
// constants
double[] constants = new double[10] { 1, 2, 3, 5, 7, 11, 13, 17, 19, 23 };
// create fitness function
TimeSeriesPredictionFitness fitness = new TimeSeriesPredictionFitness(
data, windowSize, predictionSize, constants );
// create gene function
IGPGene gene = ( functionsSet == 0 ) ?
(IGPGene) new SimpleGeneFunction( windowSize + constants.Length ) :
(IGPGene) new ExtendedGeneFunction( windowSize + constants.Length );
// create population
Population population = new Population( populationSize, ( geneticMethod == 0 ) ?
(IChromosome) new GPTreeChromosome( gene ) :
(IChromosome) new GEPChromosome( gene, headLength ),
fitness, ( selectionMethod == 0 ) ? (ISelectionMethod) new EliteSelection( ) :
( selectionMethod == 1 ) ? (ISelectionMethod) new RankSelection( ) :
(ISelectionMethod) new RouletteWheelSelection( )
);
// iterations
int i = 1;
// solution array
int solutionSize = data.Length - windowSize;
double[,] solution = new double[solutionSize, 2];
double[] input = new double[windowSize + constants.Length];

// calculate X values to be used with solution function
for ( int j = 0; j < bestfunction =" population.BestChromosome.ToString(" learningerror =" 0.0;" predictionerror =" 0.0;" j =" 0," n =" data.Length" k =" 0," b =" j">= n - predictionSize )
{
predictionError += Math.Abs( solution[j, 1] - data
[windowSize + j] );
}
else
{
learningError += Math.Abs( solution[j, 1] - data
[windowSize + j] );
}
}
// update solution on the chart
chart.UpdateDataSeries( "solution", solution );

// set current iteration's info
SetText( currentIterationBox, i.ToString( ) );
SetText( currentLearningErrorBox, learningError.ToString( "F3" ) );
SetText( currentPredictionErrorBox, predictionError.ToString( "F3" ) );
}
catch
{
// remove any solutions from chart in case of any errors
chart.UpdateDataSeries( "solution", null );
}


// increase current iteration
i++;

//
if ( ( iterations != 0 ) && ( i > iterations ) )
break;
}

// show solution
SetText( solutionBox, population.BestChromosome.ToString( ) );
for ( int j = windowSize, k = 0, n = data.Length; j < n; j++, k++ ) {
AddSubItem( dataList, j, solution[k, 1].ToString( ) );
}
// enable settings controls EnableControls( true );
}
// On "More settings" button click
private void moreSettingsButton_Click( object sender, System.EventArgs e ) {
ExSettingsDialog settingsDlg = new ExSettingsDialog( );
// init the dialog
settingsDlg.MaxInitialTreeLevel = GPTreeChromosome.MaxInitialLevel; settingsDlg.MaxTreeLevel = GPTreeChromosome.MaxLevel;
settingsDlg.HeadLength = headLength;
// show the dialog
if ( settingsDlg.ShowDialog( ) == DialogResult.OK ) {
GPTreeChromosome.MaxInitialLevel = settingsDlg.MaxInitialTreeLevel; GPTreeChromosome.MaxLevel = settingsDlg.MaxTreeLevel;
headLength = settingsDlg.HeadLength;
}
}
}
}

Reading this code, one can see that it is easy to use these three components and create a GUI to perform univariate time series analysis with genetic algorithms. Thus, you can download historical price series from Yahoo Finance and plug it into this application or your own customization and write an article on using genetic algorithms for forecasting stock prices at different temporal intervals. Furthermore, you could build on the interface to add more features and/or update the methods in the AForge.Genetic component.