/*
* Copyright (c) 2006, Seweryn Habdank-Wojewodzki
* Copyright (c) 2006, Janusz Rybarski
*
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions
* and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
* AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* e-mail: habdank AT gmail DOT com
* e-mail: janusz.rybarski AT gmail DOT com
*
* File created: Thu 10 Apr 2006 11:05:06 CEST
* Last modified: Wed 08 Aug 2007 18:22:31 CEST
*/
#include <boost/cstdint.hpp>
#include "../include/debugger.hpp"
#include "../include/std_headers.hpp"
#include "../include/neural_net_headers.hpp"
#include "../include/data_parser.hpp"
#include "configuration.hpp"
// PMAP is used just to hold program for debugging memory usage
#ifdef PMAP
#include <cstdio>
#endif //PMAP
/**
* \mainpage Kohonen Neural Network Library Demo
*
* \par Program is designed for making pattern recognition using Kohonen Self-oragnizing Map.
*
* \section intro_sec Introduction
*
* \section options Options
*
* \par Program usage:
*
* knnl_demo [OPTIONS] [FILE]
*
* If FILE is not given then standard input (stdin) is taken as input stream.
*
* \par Generic options:
*
* - -h help message
*
* - -V version string
*
* - -r number of rows in neural matrix
*
* - -c number of columns in neural martix
*
* - -e number of epochs that training process will pass
*
* \par Hidden options:
*
* - -i [ --input-file ] arg input file name
*
* \author Seweryn Habdank-Wojewodzki
* \author Janusz Rybarski
*/
/**
* \file main.cpp
* \brief Main file of the program contains ::boost::int32_t main ( ::boost::int32_t argc, char * argv[] ) function :-)
*/
/**
* \var DEBUGGER_STREAM
* \brief Set dynamical pointer to the stream.
* \code
* DEBUGGER_STREAM =
* ::std::auto_ptr < ::std::ofstream > ( new ::std::ofstream ( "_debugger.out" ) );
* \endcode
*/
#ifdef FTDEBUG
::std::auto_ptr < ::std::ofstream > DEBUGGER_STREAM;
#endif //FTDEGUG
/**
* \defgroup data_storages Data storages
*/
/**
* Configuration.
* \ingroup data_storages
*/
::config::Configuration CONF;
/**
* Main function of the program.
*/
::boost::int32_t main ( ::boost::int32_t argc, char * argv[] )
{
#ifdef FTDEBUG
DEBUGGER_STREAM =
::std::auto_ptr < ::std::ofstream >
( new ::std::ofstream ( "_debugger.out" ) );
#endif //FTDEBUG
// set program name and version number
CONF.set_program_name ( "Kohonen Network Library Demo" );
CONF.set_version_number ( "0.0.1" );
::boost::int32_t return_value = 1;
// flag used when compilation is prepared for the tests using pmap linux command
#ifdef PMAP
::std::cout << "Press any key.";
getchar ();
#endif //PMAP
try
{
// try to read command line
return_value = ::config::do_program_options ( argc, argv, CONF );
// if PROCEED was returned then follow the white rabbit
if ( return_value != ::config::PROCEED )
{
return return_value;
}
// set NULL to the istream pointer
::std::istream * file_ptr = static_cast < ::std::istream * > ( 0 );
// if input_file_name is empty set standard input as input for the program
// this is important when program have to work as filter for the stream console
if ( CONF.parameters.input_file_name == "" )
{
file_ptr = new ::std::istream ( ::std::cin.rdbuf() ) ;
// ::std::cout << "No file name specified." << ::std::endl;
}
else
{
// set real file as input stream
file_ptr = new ::std::ifstream ( CONF.parameters.input_file_name.c_str() );
// ::std::cout << CONF.parameters.input_file_name << ::std::endl;
if ( !file_ptr )
{
::std::cout << "Error in reading file." << ::std::endl;
::std::exit ( EXIT_FAILURE );
}
}
// read file for very big files if could cause problems,
// but for files smaller than available memory this is faster solution
::std::stringstream tmp_stream;
tmp_stream << file_ptr->rdbuf();
delete file_ptr;
// start random generator
::std::srand (static_cast<unsigned int> (time (NULL)));
// it could cause problems
try
{
// set number of rows for network
::boost::int32_t R = CONF.parameters.no_rows;
// set number of columns for network
::boost::int32_t C = CONF.parameters.no_columns;
// set number of the the training epochs
// one epoch it is training through all data stored in container
::boost::int32_t const no_epochs = CONF.parameters.no_epochs;
// example of using macro for debugging
D ( R );
D ( C );
D ( no_epochs );
typedef double data_type;
// type of the single data vector
// for example if we have pairs of the data like:
// { (1,2.4), (2,3.2), (3,4.7) }
// data_type describes a type of the single element
// V_d describes type of (1,2.4)
typedef ::std::vector < data_type > V_d;
// type below describes type of the container of all data
typedef ::std::vector < V_d > V_v_d;
// list container is quite good for storing data,
// but thare is no possibility to use ::std::random_shuffle()
//typedef ::std::list < V_d > V_v_d;
V_v_d data;
::data_parser::Data_parser < V_v_d > data_parser;
data_parser ( tmp_stream, data );
D ( data.size() );
// configure Cauchy hat function
typedef ::neural_net::Cauchy_function < V_d::value_type, V_d::value_type, ::boost::int32_t > C_a_f;
// Activation function for neurons
C_a_f c_a_f ( 2.0, 1 );
// configure Gauss hat function
typedef ::neural_net::Gauss_function < V_d::value_type, V_d::value_type, ::boost::int32_t > G_a_f;
// Activation function for neurons
G_a_f g_a_f ( 2.0, 1 );
// prepare Euclidean distance function
typedef ::distance::Euclidean_distance_function < V_d > E_d_t;
E_d_t e_d;
// and weighted Euclidean distance function
typedef ::distance::Weighted_euclidean_distance_function < V_d, V_d > We_d_t;
V_d coefs;
::neural_net::Ranges < V_v_d > data_ranges ( *data.begin() );
data_ranges ( data );
//preparing proper parameters for weighted distance
V_d::const_iterator pos_max = data_ranges.get_max().begin();
V_d::const_iterator pos_min = data_ranges.get_min().begin();
for ( ;