// <summary>ソースコード：ニューラルネットワークコーディングサンプル</summary>
// <author>CommonMP</author>
using System;
using System.Collections.Generic;
using System.Text;


namespace CommonMP.HYMCO.OptionImpl.NeuralNetworkSample
{
    /// <summary><para>class outline:</para>
    /// <para>ニューロン基本形</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2010/02/01][新規作成]</para>
    /// </remarks>
    public class NN_Neuron
    {
        /// <summary>ニューロン出力値（０～１）</summary>
        protected double m_dOut = 0.0;
        /// <summary>ニューロン内部状態</summary>
        protected double m_dU = 0.0;
        /// <summary>学習用誤差データ</summary>
        protected double m_dDlt = 0.0;

        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> NN_Neuron csObj = new NN_Neuron( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public NN_Neuron()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>ニューロン出力値取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = GetOut( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>ニューロン出力値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual double GetOut() { return m_dOut; }
        /// <summary><para>method outline:</para>
        /// <para>ニューロン誤差信号値取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = GetOut( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>ニューロン誤差信号値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual double GetDlt() { return m_dDlt; }

        /// <summary><para>method outline:</para>
        /// <para>ニューロン内部状態計算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = CalOut(dU)</para>
        /// </example>
        /// <param name="dU">入力総和値</param>
        /// <returns>ニューロン出力値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual double CalOut(double dU)
        {
            m_dU = dU;
            m_dOut = NN_Neuron.Sigmoid01(m_dU);
            return m_dOut;
        }
        /// <summary><para>method outline:</para>
        /// <para>誤差信号値計算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = CalDlt(dEps)</para>
        /// </example>
        /// <param name="dEps">誤差総和値</param>
        /// <returns>ニューロン誤差信号値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual double CalDlt(double dEps)
        {
            m_dDlt = dEps * m_dOut * (1.0 - m_dOut);
            return m_dDlt;
        }

        /// <summary>シグモイド関数値のクリッピング有無フラグ </summary>
        public static bool bClippingFlg = true;
        /// <summary>シグモイド関数のクリッピング最大値 </summary>
        public static double dMax01 = 0.99;
        /// <summary>シグモイド関数のクリッピング最小値 </summary>
        public static double dMin01 = 0.01;
        /// <summary>シグモイド関数の傾き（値が大きいほど　急激な立ち上がりとなる：非線形性が増す） </summary>
        public static double m_dSlope = 5.0;

        /// <summary><para>method outline:</para>
        /// <para>シグモイド関数</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = CalDlt(dEps)</para>
        /// </example>
        /// <param name="dU">関数入力値</param>
        /// <returns>計算結果</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public static double Sigmoid01(
                            double dU
                                        )
        {
            double dRtn = (1.0 + Math.Tanh(m_dSlope * dU)) / 2.0;
            if (bClippingFlg == true)
            {   // 学習収束を早める為クリッピングありならば
                if (dRtn > dMax01) { dRtn = dMax01; }
                else if (dRtn < dMin01) { dRtn = dMin01; }
            }
            return dRtn;
        }
    }

    /// <summary><para>class outline:</para>
    /// <para>バイアスニューロン</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2010/02/01][新規作成]</para>
    /// </remarks>
    public class NN_BiasNeuron : NN_Neuron
    {
        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> NN_BiasNeuron csObj = new NN_BiasNeuron( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public NN_BiasNeuron()
        {
            //m_dOut = 0.0;
            m_dOut = 1.0;
        }
        /// <summary><para>method outline:</para>
        /// <para>ニューロン出力値取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = GetOut( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>ニューロン出力値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override double GetOut()
        {
            return 1.0;
        }
        /// <summary><para>method outline:</para>
        /// <para>ニューロン内部状態計算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = CalOut(dU)</para>
        /// </example>
        /// <param name="dU">入力総和値</param>
        /// <returns>ニューロン出力値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override double CalOut(double dU)
        {
            return 1.0;
        }
    }

    /// <summary><para>class outline:</para>
    /// <para>入力層ニューロン</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2010/02/01][新規作成]</para>
    /// </remarks>
    public class NN_InputNeuron : NN_Neuron
    {
        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> NN_InputNeuron csObj = new NN_InputNeuron( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public NN_InputNeuron()
        {
        }
        /// <summary><para>method outline:</para>
        /// <para>ニューロン内部状態計算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>double dDt = CalOut(dU)</para>
        /// </example>
        /// <param name="dU">入力総和値</param>
        /// <returns>ニューロン出力値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override double CalOut(double dU)
        {
            m_dOut = dU;
            return m_dOut;
        }
    }


}
