289 lines
9.6 KiB
C++
Executable File
289 lines
9.6 KiB
C++
Executable File
/*
|
|
* 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: Wed 03 May 2006 13:18:41 CEST
|
|
* Last modified: Wed 08 Aug 2007 18:22:48 CEST
|
|
*/
|
|
|
|
#ifndef WTM_TOPOLOGY_HPP_INCLUDED
|
|
#define WTM_TOPOLOGY_HPP_INCLUDED
|
|
|
|
#include <cmath>
|
|
|
|
#include "operators.hpp"
|
|
|
|
/**
|
|
* \file wtm_topology.hpp
|
|
* \brief File contains template classes for setting up topology in the network.
|
|
* \ingroup neural_net
|
|
*/
|
|
namespace neural_net
|
|
{
|
|
/**
|
|
* \addtogroup neural_net
|
|
*/
|
|
/*\@{*/
|
|
|
|
/**
|
|
* \class Basic_topology
|
|
* \brief Basic class for topologies.
|
|
* \param Result_type type of result of the topology as a functor
|
|
* that calculates didtance between two points
|
|
* in particular case two neurons.
|
|
* \param Index_type is a type is index that is used in neural network.
|
|
*/
|
|
template
|
|
<
|
|
typename Result_type,
|
|
typename Index_type
|
|
>
|
|
class Basic_topology
|
|
{
|
|
public:
|
|
typedef Result_type result_type;
|
|
typedef Index_type value_type;
|
|
};
|
|
|
|
/**
|
|
* \class City_topology
|
|
* \brief Topology for neural network that calculates distance between two neurons.
|
|
* \param Index_type is a type of index.
|
|
* \f[
|
|
* d (n,m) = |n_1-m_1| + |n_2-m_2|
|
|
* \f]
|
|
*/
|
|
template < typename Index_type >
|
|
class City_topology
|
|
: public Basic_topology < Index_type, Index_type >
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Function claculates distance.
|
|
* \param index_1_1 is first index of first neuron.
|
|
* \param index_1_2 is second index of first neuron.
|
|
* \param index_2_1 is first index of second neuron.
|
|
* \param index_2_2 is second index of second neuron.
|
|
* \f[
|
|
* d (n,m) = |n_1-m_1| + |n_2-m_2|
|
|
* \f]
|
|
* where: n is first neuron, m is second neuron.
|
|
*/
|
|
inline Index_type operator()
|
|
(
|
|
Index_type const & index_1_1,
|
|
Index_type const & index_1_2,
|
|
Index_type const & index_2_1,
|
|
Index_type const & index_2_2
|
|
) const
|
|
{
|
|
return
|
|
(
|
|
::operators::abs ( index_1_1 - index_2_1 )
|
|
+ ::operators::abs ( index_1_2 - index_2_2 )
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \class Max_topology
|
|
* \brief Topology for neural network that calculates distance between two neurons.
|
|
* \param Index_type is a type of index.
|
|
* \f[
|
|
* d (n,m) = \max ( |n_1-m_1|, |n_2-m_2| )
|
|
* \f]
|
|
*/
|
|
template < typename Index_type >
|
|
class Max_topology
|
|
: public Basic_topology < Index_type, Index_type >
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Function claculates distance.
|
|
* \param index_1_1 is first index of first neuron.
|
|
* \param index_1_2 is second index of first neuron.
|
|
* \param index_2_1 is first index of second neuron.
|
|
* \param index_2_2 is second index of second neuron.
|
|
* \f[
|
|
* d (n,m) = \max ( |n_1-m_1|, |n_2-m_2| )
|
|
* \f]
|
|
* where: n is first neuron, m is second neuron.
|
|
*/
|
|
inline Index_type operator()
|
|
(
|
|
Index_type const & index_1_1,
|
|
Index_type const & index_1_2,
|
|
Index_type const & index_2_1,
|
|
Index_type const & index_2_2
|
|
) const
|
|
{
|
|
return
|
|
(
|
|
::std::max
|
|
(
|
|
::operators::abs ( index_1_1 - index_2_1 ),
|
|
::operators::abs ( index_1_2 - index_2_2 )
|
|
)
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \class Hexagonal_topology
|
|
* \brief Topology for neural network that calculates distance between two neurons.
|
|
* \param Index_type is a type of index.
|
|
* \f{eqnarray*}
|
|
* h_1 (x) & = & \frac{ x_1 + 1 }{2} + x_2\\
|
|
* h_2 (x) & = & \frac{h_{off}}{2} + x_2 - x_1 / 2;\\
|
|
* t_1 & = & \max ( h_1 (n), h_1 (m) ) - \min ( h_1 (n), h_1 (m) )\\
|
|
* t_2 & = & \max ( h_2 (n), h_2 (m) ) - \min ( h_2 (n), h_2 (m) )\\
|
|
* d (n,m) & = & \left\{
|
|
* \begin{array}{ll}
|
|
* \max (|t_1|,|t_2|) & if \; sign \; of \; t_1 \; and \; t_2 \; is \; the \; same\\
|
|
* |t_1|+|t_2| & otherwise
|
|
* \end{array} \right.
|
|
* \f}
|
|
*/
|
|
template < typename Index_type >
|
|
class Hexagonal_topology
|
|
: public Basic_topology < Index_type, Index_type >
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
* \param hex_offset_ is an offset of the hexagonal topology.
|
|
* This value have to be not less than number of rows in neuron
|
|
* container counted from 0.
|
|
*/
|
|
inline explicit Hexagonal_topology ( Index_type const & hex_offset_ )
|
|
: hex_offset ( hex_offset_ )
|
|
{}
|
|
|
|
/** Copy constructor. */
|
|
template < typename Index_type_2 >
|
|
inline Hexagonal_topology ( Hexagonal_topology < Index_type_2 > const & hex_topology )
|
|
: Basic_topology < Index_type_2, Index_type_2 >(),
|
|
hex_offset ( hex_topology.hex_offset )
|
|
{}
|
|
|
|
/**
|
|
* Function calculates distance.
|
|
* \param index_1_1 is first index of first neuron.
|
|
* \param index_1_2 is second index of first neuron.
|
|
* \param index_2_1 is first index of second neuron.
|
|
* \param index_2_2 is second index of second neuron.
|
|
* \f{eqnarray*}
|
|
* h_1 (x) & = & \frac{ x_1 + 1 }{2} + x_2\\
|
|
* h_2 (x) & = & \frac{h_{off}}{2} + x_2 - x_1 / 2;\\
|
|
* t_1 & = & \max ( h_1 (n), h_1 (m) ) - \min ( h_1 (n), h_1 (m) )\\
|
|
* t_2 & = & \max ( h_2 (n), h_2 (m) ) - \min ( h_2 (n), h_2 (m) )\\
|
|
* d (n,m) & = & \left\{
|
|
* \begin{array}{ll}
|
|
* \max (|t_1|,|t_2|) & if \; sign \; of \; t_1 \; and \; t_2 \; is \; the \; same\\
|
|
* |t_1|+|t_2| & otherwise
|
|
* \end{array} \right.
|
|
* \f}
|
|
* where: n is firs neuron, m is second.
|
|
*/
|
|
Index_type operator()
|
|
(
|
|
Index_type const & index_1_1,
|
|
Index_type const & index_1_2,
|
|
Index_type const & index_2_1,
|
|
Index_type const & index_2_2
|
|
) const
|
|
{
|
|
Index_type hex_index_1_1;
|
|
Index_type hex_index_1_2;
|
|
Index_type hex_index_2_1;
|
|
Index_type hex_index_2_2;
|
|
|
|
Index_type tmp_hex_index_1;
|
|
Index_type tmp_hex_index_2;
|
|
|
|
// recalculate indexes to the better indexes used in hexagonal space
|
|
hex_index_1_1 = ( index_1_1 + 1 ) / 2 + index_1_2;
|
|
hex_index_1_2 = ( hex_offset / 2 + index_1_2 ) - index_1_1 / 2;
|
|
|
|
hex_index_2_1 = ( index_2_1 + 1 ) / 2 + index_2_2;
|
|
hex_index_2_2 = ( hex_offset / 2 + index_2_2 ) - index_2_1 / 2;
|
|
|
|
// calculate difference between points in hexagonal space
|
|
tmp_hex_index_1 = ::std::max ( hex_index_1_1, hex_index_2_1 )
|
|
- ::std::min ( hex_index_1_1, hex_index_2_1 );
|
|
tmp_hex_index_2 = ::std::max ( hex_index_1_2, hex_index_2_2 )
|
|
- ::std::min ( hex_index_1_2, hex_index_2_2 );
|
|
|
|
// here we have special algebra to calculate distance,
|
|
// bacause of special basis in this space:
|
|
// ( 1, 1 ); ( -1, -1 ) have distance 1 the same as
|
|
// ( -1, 0 ); ( 0, -1 ); ( 1, 0 ); ( 0, 1 ).
|
|
if ( tmp_hex_index_1 == 0 && tmp_hex_index_2 == 0 )
|
|
{
|
|
return static_cast < Index_type > ( 0 );
|
|
}
|
|
|
|
// check if values have the same direction if yes it means that we have to use
|
|
// reasoning based on assumption that ( -1, -1 ) and ( 1, 1 ) have distance 1.
|
|
if ( ( ( hex_index_1_1 > hex_index_2_1 ) && ( hex_index_1_2 > hex_index_2_2 ) )
|
|
|| ( ( hex_index_1_1 < hex_index_2_1 ) && ( hex_index_1_2 < hex_index_2_2 ) )
|
|
)
|
|
{
|
|
return ::std::max ( tmp_hex_index_1, tmp_hex_index_2 );
|
|
}
|
|
else
|
|
{
|
|
return ::operators::abs ( tmp_hex_index_1 ) + ::operators::abs ( tmp_hex_index_2 );
|
|
}
|
|
|
|
return static_cast < Index_type > ( 0 );
|
|
}
|
|
|
|
protected:
|
|
Index_type hex_offset;
|
|
};
|
|
/*\@}*/
|
|
|
|
} // namespace neural_net
|
|
|
|
#endif // WTM_TOPOLOGY_HPP_INCLUDED
|
|
|