private void Init(ConnectedLayer connectedLayer)
        {
            ConnectedLayerIndex = connectedLayer.Index;
            InitInputValueAccessItems(connectedLayer);
            OutputBuffer = connectedLayer.OutputBuffer;
            BiasValueIndex = connectedLayer.BiasValueIndex;
            InnerItarationOutputValueStack = connectedLayer.InnerItarationOutputValueStack;
            IsOutput = connectedLayer.IsOutput;
            if ((connectedLayer.StructuralElementFlags & NNStructuralElement.RTLRInformation) != 0)
            {
                Method = ForwardComputationMethod.RTLR;
                UpperNonInputLayerInfos = connectedLayer.UpperNonInputLayerInfos;
                PBiasBuffers = connectedLayer.PBiasBuffers;
                PWeightBuffers = connectedLayer.PWeightBuffers;
                PrevPBiasBuffers = connectedLayer.PrevPBiasBuffers;
                PrevPWeightBuffers = connectedLayer.PrevPWeightBuffers;
                NetDerivBuffer = connectedLayer.NetDerivBuffer;
                GradientBuffers = connectedLayer.GradientBuffers;
                GradientSumBuffers = connectedLayer.GradientSumBuffers;
                BiasGradientValueIndex = connectedLayer.BiasGradientValueIndex;
                BiasGradientSumValueIndex = connectedLayer.BiasGradientSumValueIndex;
            }
            else if (connectedLayer.InnerItarationOutputValueStack != null)
            {
                Debug.Assert(connectedLayer.InnerItarationInputValueStacks != null);

                Method = ForwardComputationMethod.BPTT;
            }
            else
            {
                Method = ForwardComputationMethod.FeedForward;
            }
        }
        protected LayerBackwardCompute(LayerForwardCompute forwardCompute, ConnectedLayer connectedLayer)
        {
            Contract.Requires(forwardCompute != null);
            Contract.Requires(connectedLayer != null);
            Contract.Requires((connectedLayer.StructuralElementFlags & NNStructuralElement.BackwardImplementation) != 0 &&
                (connectedLayer.StructuralElementFlags & NNStructuralElement.GradientInformation) != 0);

            Init(forwardCompute, connectedLayer);
        }
        private void Init(LayerForwardCompute forwardCompute, ConnectedLayer connectedLayer)
        {
            ForwardCompute = forwardCompute;

            InitLowerErrorValueAccessItems(connectedLayer);
            ErrorBuffer = connectedLayer.ErrorBuffer;
            GradientBuffers = connectedLayer.GradientBuffers;
            GradientSumBuffers = connectedLayer.GradientSumBuffers;
            BiasGradientValueIndex = connectedLayer.BiasGradientValueIndex;
            BiasGradientSumValueIndex = connectedLayer.BiasGradientSumValueIndex;
            OutputErrorBuffer = connectedLayer.OutputErrorBuffer;
        }
        internal void InitializeAlgo(BufferAllocator allocator, LearningRule rule, ConnectedLayer[] connectedLayers, ManagedNNInitParameters initPars)
        {
            Contract.Requires(rule != null);
            Contract.Requires(connectedLayers != null);
            Contract.Requires(connectedLayers.Length > 0);
            Contract.Requires(initPars != null);

            Rule = rule;
            ConnectedLayers = connectedLayers;
            RunParallel = initPars.RunParallel;
            Ininitalize(allocator);
        }
        public ActivationLayerBackwardCompute(ActivationLayerForwardCompute forwardCompute, ConnectedLayer connectedLayer)
            : base(forwardCompute, connectedLayer)
        {
            Contract.Requires(forwardCompute != null);
            Contract.Requires(connectedLayer != null);
            Contract.Requires((connectedLayer.StructuralElementFlags & NNStructuralElement.BackwardImplementation) != 0 &&
                (connectedLayer.StructuralElementFlags & NNStructuralElement.GradientInformation) != 0);

            Function = forwardCompute.Function;

            forwardCompute.FeedForwardOps.Initialize(this);
            forwardCompute.BPTTOps.Initialize(this);
        } 
        public ActivationLayerForwardCompute(NeuralNetworkFactory factory, ConnectedLayer connectedLayer)
            : base(factory, connectedLayer)
        {
            Contract.Requires(connectedLayer != null);
            Contract.Requires(connectedLayer.Layer is ActivationLayer);

            FeedForwardOps = factory.CreateFeedForwardOps();
            FeedForwardOps.Initialize(this);
            BPTTOps = factory.CreateBPTTOps();
            BPTTOps.Initialize(this);
            RTLROps = factory.CreateRTLROps();
            RTLROps.Initialize(this);
            Function = ((ActivationLayer)connectedLayer.Layer).Function;
        } 
        protected LayerBackwardComputeBase(LayerForwardComputeBase forwardCompute, ConnectedLayer connectedLayer)
        {
            Contract.Requires(forwardCompute != null);
            Contract.Requires(connectedLayer != null);
            Contract.Requires((connectedLayer.StructuralElementFlags & NNStructuralElement.BackwardImplementation) != 0 &&
                (connectedLayer.StructuralElementFlags & NNStructuralElement.GradientInformation) != 0);

            ForwardCompute = forwardCompute;

            InitLowerErrorValueAccessItems(connectedLayer);
            ErrorBuffer = connectedLayer.ErrorBuffer;
            GradientBuffers = connectedLayer.GradientBuffers;
            GradientSumBuffers = connectedLayer.GradientSumBuffers;
            BiasGradientValueIndex = connectedLayer.BiasGradientValueIndex;
            BiasGradientSumValueIndex = connectedLayer.BiasGradientSumValueIndex;
            OutputErrorBuffer = connectedLayer.OutputErrorBuffer;
        }
        private void InitLowerErrorValueAccessItems(ConnectedLayer connectedLayer)
        {
            if (connectedLayer.WeightedOutputErrorBuffers == null) return;

            var items = new LinkedList<ErrorValueAccess>();

            for (int outputErrorBufferIndex = 0; outputErrorBufferIndex < connectedLayer.WeightedOutputErrorBuffers.Length; outputErrorBufferIndex++)
            {
                var weightedOutputErrorBuffer = connectedLayer.WeightedOutputErrorBuffers[outputErrorBufferIndex];
                int wibValueBufferSize = weightedOutputErrorBuffer.ValueBuffer.Size;
                items.AddLast(
                    new ErrorValueAccess(
                        weightedOutputErrorBuffer.ValueBuffer.Size,
                        weightedOutputErrorBuffer.ValueBuffer.MinValue,
                        weightedOutputErrorBuffer.WeightBuffer.MinValue));
            }

            LowerErrorValueAccessItems = items.ToArray();
        }
        private void InitInputValueAccessItems(ConnectedLayer connectedLayer)
        {
            int count = connectedLayer.WeightedInputBuffers.Length;
            var items = new InputValueAccess[count];

            for (int inputBufferIndex = 0; inputBufferIndex < count; inputBufferIndex++)
            {
                var weightedInputBuffer = connectedLayer.WeightedInputBuffers[inputBufferIndex];
                int wibValueBufferSize = weightedInputBuffer.ValueBuffer.Size;
                items[inputBufferIndex] =
                    new InputValueAccess(
                        weightedInputBuffer.ValueBuffer.Size,
                        weightedInputBuffer.ValueBuffer.MinValue,
                        weightedInputBuffer.WeightBuffer.MinValue,
                        connectedLayer.InnerItarationInputValueStacks != null ? connectedLayer.InnerItarationInputValueStacks[inputBufferIndex] : null);
            }

            InputValueAccessItems = items;
        }
        protected internal virtual LayerBackwardCompute CreateBackwardCompute(ConnectedLayer connectedLayer)
        {
            Contract.Requires(connectedLayer != null);

            throw new InvalidOperationException("Backward computation is not supported.");
        } 
        protected LayerForwardCompute(NeuralNetworkFactory factory, ConnectedLayer connectedLayer)
        {
            Contract.Requires(connectedLayer != null);

            Init(connectedLayer);
        }
 protected internal override LayerBackwardCompute CreateBackwardCompute(ConnectedLayer connectedLayer)
 {
     return new ActivationLayerBackwardCompute(this, connectedLayer);
 } 
        private void InitInputValueAccessItems(ConnectedLayer connectedLayer)
        {
            var items = new LinkedList<InputValueAccess>();

            for (int inputBufferIndex = 0; inputBufferIndex < connectedLayer.WeightedInputBuffers.Length; inputBufferIndex++)
            {
                var weightedInputBuffer = connectedLayer.WeightedInputBuffers[inputBufferIndex];
                int wibValueBufferSize = weightedInputBuffer.ValueBuffer.Size;
                items.AddLast(
                    new InputValueAccess(
                        weightedInputBuffer.ValueBuffer.Size,
                        weightedInputBuffer.ValueBuffer.MinValue,
                        weightedInputBuffer.WeightBuffer.MinValue,
                        connectedLayer.InnerItarationInputValueStacks != null ? connectedLayer.InnerItarationInputValueStacks[inputBufferIndex] : null));
            }

            InputValueAccessItems = items.ToArray();
        } 
 internal void InitializeAlgo(BufferAllocator allocator, LearningRule learningRule, ConnectedLayer[] connectedLayer)
 {
     throw new NotImplementedException();
 }