package main;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Scanner;
import odor.Odor;
import odor.OdorPreprocessor;
import structures.Network;
import util.FileUtil;
import util.Gaussian;
import util.SingleValueGaussian;
import util.SummedGaussian;
import util.Util;
/*
* THIS SOFTWARE IS PROTECTED UNDER THE MIT LICENSE FOR FREE AND OPEN-SOURCE SOFTWARE
*
* Copyright (C) 2011 by Thomas Cleland, Pedro Rittner
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
/*
* GLOBAL TO-DO LIST
*
* 1. TODO Change all Odors to exponentials
* 1a. TODO Write JUnit tests for Odor, Network
* 2. TODO Get Standard I/O Working
* 3. TODO Setup command-line parameters
* 4. TODO Change the way Odors are saved to files and read
*/
/*
* PRIORITY TO-DO LIST
*
* FIXME Odors and things that use them.
*/
public class Main
{
public static boolean VERBOSE = false;
public static final String PROGRAM_NAME = "Neuro-Baldr v1.00";
public static final short PRECISION = 3;
public static final int ODOR_INPUT_SUM = 1000;
public static final int NUM_COLS = 20;
//public static int UNIVERSAL_TO_MITRAL_WEIGHT = 1;
public static BufferedWriter LOG_WRITER;
public static void main(String[] args) throws IOException, InitializationException
{
//NeuroBaldrControlFrame f = new NeuroBaldrControlFrame(5, Odor.generateOdorBattery(5, NUM_COLS, ODOR_INPUT_SUM, 25));
/*
// DEMO
SummedGaussian g = new SummedGaussian(100, 100, 25, 100, 1000);
Odor od1 = new Odor(NUM_COLS, g);
Network n = new Network(NUM_COLS);
n.initialize(null);
double[] inputs = od1.getInputs();
double[] outputs= n.fire(od1);
Util.printArray(inputs);
Util.printArray(outputs);
*/
Network n = new Network(NUM_COLS);
n.initialize(null);
Odor[] battery= OdorPreprocessor.generateSimilarOdors(2, NUM_COLS);
double[][] outputs = new double[NUM_COLS][battery.length];
int counter = 0;
for (Odor od : battery)
{
System.out.println("Odor #"+(counter));
for (double i : od.getInputs())
{
System.out.println(i);
}
System.out.println();
outputs[counter] = n.fire(od);
for (double a: outputs[counter])
{
System.out.println(a);
}
counter++;
}
System.out.println("-----------------");
System.out.println("Angle Between Odors #0 & #1 PRE : "+Util.angleBetweenVectors(battery[0].getInputs(), battery[1].getInputs()));
System.out.println("Angle Between Odors #0 & #1 POST: "+Util.angleBetweenVectors(outputs[0], outputs[1]));
/*
if (args != null && args.length != 0)
{
Main.parseOutputFile(args[1]);
}
SummedGaussian g = new SummedGaussian(100, 100, 25, 100);
Odor[] arr = {new Odor(NUM_COLS, g)};
Network n = parseParametersFile(args[2]);
n.initialize(null);
Odor[] battery = (args != null && args.length != 0)? Main.parseInputFile(args[0]) : (arr);
for (Odor od : battery)
{
double[] output = n.fire(od);
n.resetGranules();
//LOG
if (Main.LOG_WRITER != null)
{
Main.attemptNewLineToLog();
Main.attemptWriteToLog("Angle b/w Input&Output = "+
Math.acos( Util.dotProduct(od.getInputs(), output) / (Util.magnitude(od.getInputs()) * Util.magnitude(output)) ) );
}
//DEBUG
if (Main.VERBOSE)
{
System.out.println();
System.out.println("Angle b/w Input&Output = "+
Math.acos( Util.dotProduct(od.getInputs(), output) / (Util.magnitude(od.getInputs()) * Util.magnitude(output)) ) );
}
}
//LOG
if (Main.LOG_WRITER != null)
{
Main.LOG_WRITER.close();
}
*/
}
//TODO parse network parameters file
private static Network parseParametersFile(String filename)
{
if (filename == null || filename.compareTo("") == 0) return new Network(Main.NUM_COLS);
File parametersFile = new File(System.getProperty("user.dir")+File.separatorChar+filename);
//TODO Interesting Network variables
Network network = null;
int numCols = 0;
int granulesPerColumn = 1;
double intercolumnConnectivity = 0.20;
boolean dynamicItercolumnConnectivity = false;
Gaussian granuleToMitralWeight = null;
Gaussian granuleActivationThreshold = null;
Gaussian mitralToGranuleWeights = null;
String[] lines = Util.truncateLinesAtChar(FileUtil.readFileLines(parametersFile), '=');
if (lines == null || lines.length != 7)
{
//DEBUG
if (Main.VERBOSE)
{
System.out.println();
System.out.println("-COULD NOT READ PARAMS FILE; DEFAULT NETWORK USED-");
}
//LOG
if (Main.LOG_WRITER != null)
{
Main.attemptNewLineToLog();
Main.attemptWriteToLog("-COULD NOT READ PARAMS FILE; DEFAULT NETWORK USED-");
}
return new Network(Main.NUM_COLS);
}
for (int x = 0; x < lines.length; x++)
{
switch (x)
{
case 0:
{
numCols = Integer.parseInt(lines[x]);
break;
}
case 1:
{
granulesPerColumn = Integer.parseInt(lines[x]);
break;
}
case 2:
{
intercolumnConnectivity = Double.parseDouble(lines[x]);
break;
}
case 3:
{
dynamicItercolumnConnectivity = Boolean.parseBoolean(lines[x]);
break;
}
case 4:
{
if (lines[x].contains( (CharSequence)"(" ))
{
lines[x] = Util.removeChar(lines[x], '(');
lines[x] = Util.removeChar(lines[x], ')');
granuleToMitralWeight = new Gaussian( Double.parseDouble(lines[x]) );
}
else
granuleToMitralWeight = new SingleValueGaussian(Double.parseDouble(lines[x]));
break;
}
case 5:
{
if (lines[x].contains( (CharSequence)"(" ))
{
lines[x] = Util.removeChar(lines[x], '(');
lines[x] = Util.removeChar(lines[x], ')');
granuleActivationThreshold = new Gaussian(Double.parseDouble(lines[x]));
}
else
granuleActivationThreshold = new SingleValueGaussian(Double.parseDouble(lines[x]));
break;
}
case 6:
{
if (lines[x].contains( (CharSequence)"(" ))
{
lines[x] = Util.removeChar(lines[x], '(');
lines[x] = Util.removeChar(lines[x], ')');
mitralToGranuleWeights = new Gaussian(Double.parseDouble(lines[x]));
}
else
mitralToGranuleWeights = new SingleValueGaussian(Double.parseDouble(lines[x]));
break;
}
}
}
network = new Network( numCols,
granulesPerColumn,
intercolumnConnectivity,
dynamicItercolumnConnectivity,
granuleToMitralWeight,
granuleActivationThreshold,
mitralToGranuleWeights);
return network;
}
//TODO write javadoc
private static Odor[] parseInputFile(String filename)
{
File inputFile = new File(System.getProperty("user.dir")+File.separatorChar+filename);
Odor[] inputBattery = null;
if (inputFile.exists() && inputFile.canRead())
{
inputBattery = Odor.fileToBattery(inputFile);
}
return inputBattery;
}
//TODO write javadoc
private static void parseOutputFile(String fileName)
{
File outputFile;
try
{
outputFile = new File(System.getProperty("user.dir")+File.separatorChar+fileName);
outputFile.createNewFile();
Main.LOG_WRITER = new BufferedWriter(new FileWriter(outputFile));
Main.attemptWriteToLog("SIMUL START "+DateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
Main.attemptNewLineToLog();
}
catch (IOException e)
{
javax.swing.JOptionPane.showMessageDialog(null, "Couldn't Create Output File: No Output Will be Written");
Main.LOG_WRITER = null;
}
}
/**
* Writes message to output file, if it exists.
* @param msg
*/
public static void attemptWriteToLog(String msg)
{
try
{
Main.LOG_WRITER.write(msg);
}
catch (IOException e)
{
System.err.println("Unable to write \""+msg+"\" to file");
}
}
/**
* Writes newline character to output file, if it exists.
*/
public static void attemptNewLineToLog()
{
try
{
Main.LOG_WRITER.newLine();
}
catch (IOException e)
{
System.err.println("Unable to write newline to file");
}
}
}