/* * 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); } } }