/*
* File: DatasetReader.java
* Author: Justin Basilico
* Course: PO CS 152: Neural Networks
* Assignment: Final Project
* Updated: 2001.12.18
* Created: 2001.12.04
*
* Description:
* This file contains the DatasetReader abstract class, which just has static
* methods for reading in datasets for the network based on the file format of
* the dataset.
*
* Copyright: Justin Basilico (2001).
*/
import java.io.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;
/**
* DatasetReader class
*
* This abstract class just contains static methods for reading in datasets of
* NetworkInput objects from files based on a specific format. The current
* formats supported are: double array.
*
* Double array format: Text values:
*
*
*
*
*
* ...
*
* @author Justin Basilico
* @version 2001.12.18
*/
public abstract class DatasetReader
extends Object
{
/**
* readDoubleDataset
*
* This method takes a String file name and reads a dataset of double
* arrays in from that file name, returning it as an array of NetworkInput
* objects. If the given file name does not exist or if there is an error
* while reading in, it returns null. The array is all made up of
* InputOutputPairs where both the input and output are arrays of doubles.
*
* The file should have on the first line the integer size of the input
* and output arrays. Then it reads every two lines, using the first line
* as the array of double input values of the given input size and the
* second line as the array of double output values of the given output
* size.
*
* @param fileName The String name of the file to read the dataset of
* double values from.
* @return The array of NetworkInputs that correspond to the
* InputOutputPair where both the input and the output are arrays
* of doubles that are read from the given file. If the given file
* does not exist or there is an error while reading it in, it
* just returns null.
*/
public static NetworkInput[] readDoubleDataset(
String fileName) // File to read dataset from.
{
// Open the file.
BufferedReader br = openFile(fileName);
if ( br == null )
{
// Error: Problem opening the file.
return null;
}
// Read in the first line.
String s = readLine(br);
if ( s == null )
{
// Error: No data in the file.
System.err.println("Error: No data in specified file.");
closeFile(br);
return null;
}
// Make a tokenizer for the first line.
StringTokenizer st = new StringTokenizer(s);
if ( st.countTokens() < 2 )
{
// Error: Not enough tokens on the first line.
System.err.println("Error: Sizes of inputs and outputs not "
+ "specified.");
closeFile(br);
return null;
}
// Get the size of the input for the dataset.
int inputSize = Integer.parseInt(st.nextToken());
int outputSize = Integer.parseInt(st.nextToken());
String inputString = null;
String outputString = null;
// Create a list for the dataset.
LinkedList dataList = new LinkedList();
// Read in the input and output line.
while ( (inputString = readLine(br)) != null
&& (outputString = readLine(br)) != null )
{
// Read in the input and output array.
double[] input = readDoubleArray(inputString, inputSize);
double[] output = readDoubleArray(outputString, outputSize);
// Add the input output pair to the data list.
dataList.addLast(new InputOutputPair(input, output));
}
// Done reading, close the file.
closeFile(br);
// Make a dataset from the given list.
return makeDatasetFromList(dataList);
}
/**
* readDoubleArray
*
* This method takes a String and an integer size. The String is assumed
* to be the String representation of the given size number of double
* values. It creates array of the given size and reads at most that
* number of doubles in from the given String, filling in the remaining
* space with 0.0.
*
* @param line The String line to read the double array in from.
* @param size The integer size of the array to create.
* @return The array of doubles of the given size that are the double
* values from the given String up to the given size, or if there
* are not enough String tokens on the line to fill the array, the
* rest are filled with 0.0.
*/
public static double[] readDoubleArray(
String line, // String line to read from.
int size) // Integer size to read.
{
// Make a StringTokenizer for the line
StringTokenizer st = new StringTokenizer(line);
// Create the array of doubles, start with them all 0.0.
double[] result = new double[size];
Utilities.zeroArray(result);
// Keep reading as long as there is room in the array and still tokens
// on the line.
for (int i = 0; i < result.length && st.hasMoreTokens(); i++)
// Parse the next double token from the line.
result[i] = Double.parseDouble(st.nextToken());
// Return the array.
return result;
}
/**
* makeDatasetFromList
*
* This method takes a LinkedList of NetworkInput objects and returns an
* array of NetworkInputs which were the NetworkInput objects that were
* in the given list.
*
* @param list A LinkedList of NetworkInput objects.
* @return An array of NetworkInputs that are the NetworkInputs which were
* in the given list.
* @see java.util.LinkedList
*/
public static NetworkInput[] makeDatasetFromList(
LinkedList list) // List of NetworkInputs.
{
// The dataset.
NetworkInput[] dataset = new NetworkInput[list.size()];
// Get the iterator for the list.
Iterator it = list.iterator();
for (int i = 0; i < dataset.length && it.hasNext(); i++)
// Read the next NetworkInput from the list.
dataset[i] = (NetworkInput) it.next();
// Return the dataset.
return dataset;
}
/**
* openFile
*
* This method takes a String file name and tries to open a BufferedReader
* to read that file. If the file exists and a BufferedReader is
* successfully opened for that file, it returns the BufferedReader.
* Otherwise, it returns null. The reason for this method is just to
* easily deal with the IOExceptions.
*
* @param fileName The String file name to open a BufferedReader for.
* @return A new BufferedReader for the given file name, or null if there
* is no such file.
* #see java.io.BufferedReader
* @see java.io.IOException
*/
public static BufferedReader openFile(
String fileName) // The file to open.
{
try
{
// Try to open the file.
return new BufferedReader(new FileReader(fileName));
}
catch ( IOException ioe )
{
// Error: Problem opening the file.
System.err.println("Could not open file: " + fileName + ".");
System.err.println("IOException is: " + ioe);
return null;
}
}
/**
* readLine
*
* This method takes a BufferedReader and reads the next String line in
* from the BufferedReader by using the readLine() method. It returns the
* result of that call as long as it doesn't throw an IOException and if
* it does, then it returns null. It also just catches the IOException
* that can be thrown and instead just returns null.
*
* @param br The BufferedReader to read a String line in from.
* @return The next String line from the BufferedReader, if there is one.
* Otherwise, it returns null.
* @see java.io.BufferedReader.readLine()
* @see java.io.IOException
*/
public static String readLine(
BufferedReader br) // BufferedReader to read in.
{
try
{
// Return the read line.
return br.readLine();
}
catch ( IOException ioe )
{
// Error: IOException reading the line from the file.
System.err.println("Error reading from file: " + ioe);
return null;
}
}
/**
* closeFile
*
* This method takes a BufferedReader and closes it. It just calls the
* close() method on the given BufferedReader and catches the IOException
* that might be thrown.
*
* @param br The BufferedReader to close.
* @see java.io.BufferedReader.close()
* @see java.io.IOExeption
*/
public static void closeFile(
BufferedReader br) // BufferedReader to close.
{
try
{
// Close the BufferedReader.
br.close();
}
catch ( IOException ioe )
{
// Error: Problem closing the file.
System.err.println("Error closing file: " + ioe);
}
}
}