public static INetwork BuildLSTM(NetworkSettings settings, CellLayerSettings lstmSettings, HiddenLayerSettings prevHiddenSettings, HiddenLayerSettings lastHiddenSettings)
        {
            Network lstm = new Network(settings);

            IEnumerable <INeuron> prevLayer = lstm.BuildInputNeurons(settings);

            if (prevHiddenSettings != null)
            {
                lstm.HiddenLayers = lstm.BuildHiddenLayers(prevLayer, prevHiddenSettings);
            }

            if (lstm.HiddenLayers != null)
            {
                prevLayer = lstm.HiddenLayers.Last();
            }
            else
            {
                lstm.HiddenLayers = new List <ICollection <IHiddenNeuron> >();
                prevLayer         = lstm.InputNeurons;
            }

            var lstmLayers = lstm.BuildLSTMCells(prevLayer, lstmSettings);

            foreach (ICollection <IHiddenNeuron> layer in lstmLayers)
            {
                lstm.HiddenLayers.Add(layer);
                prevLayer = layer;
            }

            if (lastHiddenSettings != null)
            {
                var hiddenLayers = lstm.BuildHiddenLayers(prevLayer, lastHiddenSettings);
                foreach (ICollection <IHiddenNeuron> layer in hiddenLayers)
                {
                    lstm.HiddenLayers.Add(layer);
                }
            }

            return(lstm);
        }
        internal IList <ICollection <ILSTMCell> > BuildLSTMCells(IEnumerable <INeuron> prevLayer, CellLayerSettings settings)
        {
            var tempLayers = new List <ICollection <ILSTMCell> >(settings.LayersCount);

            ushort recurrentInputs = (ushort)(settings.HasSelfConnection ? 1 : 0);

            for (int i = 0; i < settings.LayersCount; i++)
            {
                var tempHidden = new List <ILSTMCell>(settings.NeuronsCount);
                for (int j = 0; j < settings.NeuronsCount; j++)
                {
                    ushort rn     = (ushort)(recurrentInputs + (settings.Direction == RecurrentDirection.Both ? settings.NeuronsCount : j));
                    var    neuron = new LSTMCell(settings.FunctionType, rn);

                    foreach (var inNeuron in prevLayer)
                    {
                        ConnectAxon(inNeuron, neuron, settings.NeuronsCount);
                    }
                    tempHidden.Add(neuron);
                }

                if (settings.Direction == RecurrentDirection.Forward || settings.Direction == RecurrentDirection.Both)
                {
                    for (int k = 0; k < settings.NeuronsCount; k += 2)
                    {
                        if (k + 1 < settings.NeuronsCount)
                        {
                            ConnectRecurrentAxon(tempHidden[k], tempHidden[k + 1], settings.HasSelfConnection);
                        }
                    }
                }

                if (settings.Direction == RecurrentDirection.Backward || settings.Direction == RecurrentDirection.Both)
                {
                    for (int k = settings.NeuronsCount - 1; k >= 0; k -= 2)
                    {
                        if (k - 1 < settings.NeuronsCount)
                        {
                            ConnectRecurrentAxon(tempHidden[k], tempHidden[k - 1], settings.HasSelfConnection);
                        }
                    }
                }
            }
            return(tempLayers);
        }