private NeuralVectorFlow CreateNeuralVectors(int index)
        {
            var fs = featureStreams[index];
            var fa = fs.CreateFeatureArray(SampleSize);
            if (SubSampleSize == SampleSize)
            {
                var nv = new NeuralVectorFlow(index, new VectorFlowEntry<float>(CreateInputVector(fa), CreateOutputVector(fs), NumberOfComputationIterations));
                return nv;
            }
            else
            {
                var entries = new LinkedList<VectorFlowEntry<float>>();
                for (int i = 0; i < SampleSize; i++)
                {
                    float[] inputVector = new float[SampleSize];
                    for (int j = 0; j < SampleSize; j++)
                    {
                        inputVector[j] = fa[i, j];
                    }
                    if (i != SampleSize - 1)
                    {
                        entries.AddLast(new VectorFlowEntry<float>(inputVector, NullOutput));
                    }
                    else
                    {
                        entries.AddLast(new VectorFlowEntry<float>(inputVector, CreateOutputVector(fs), NumberOfComputationIterations));
                    }
                }
                //int size = SampleSize / SubSampleSize;
                //for (int lookupIndex = 0; lookupIndex < lookupArray.Length; lookupIndex++)
                //{
                //    Point lookupPoint = lookupArray[lookupIndex];
                //    float[] inputVector = new float[SubSampleSize * SubSampleSize];
                //    int inputIndex = 0;

                //    for (int y = lookupPoint.Y; y < lookupPoint.Y + SubSampleSize; y++)
                //    {
                //        for (int x = lookupPoint.X; x < lookupPoint.X + SubSampleSize; x++)
                //        {
                //            inputVector[inputIndex++] = fa[y, x];
                //        }
                //    }

                //    if (lookupIndex != lookupArray.Length - 1)
                //    {
                //        entries.AddLast(new VectorFlowEntry<float>(inputVector, NullOutput)); 
                //    }
                //    else
                //    {
                //        entries.AddLast(new VectorFlowEntry<float>(inputVector, CreateOutputVector(fs), NumberOfComputationIterations));
                //    }
                //}

                return new NeuralVectorFlow(index, entries.ToArray());
            }
        }
        private NeuralVectorFlow CreateNeuralVectors(int index)
        {
            var fs = featureStreams[index];
            var fa = fs.CreateFeatureArray(SampleSize);
            if (SubSampleSize == SampleSize)
            {
                var nv = new NeuralVectorFlow(index, new VectorFlowEntry<double>(CreateInputVector(fa), CreateOutputVector(fs), NumberOfComputationIterations));
                return nv;
            }
            else
            {
                var entries = new LinkedList<VectorFlowEntry<double>>();
                int size = SampleSize / SubSampleSize;
                for (int lookupIndex = 0; lookupIndex < lookupArray.Length; lookupIndex++)
                {
                    Point lookupPoint = lookupArray[lookupIndex];
                    double?[] inputVector = new double?[SubSampleSize * SubSampleSize];
                    int inputIndex = 0;

                    for (int y = lookupPoint.Y; y < lookupPoint.Y + SubSampleSize; y++)
                    {
                        for (int x = lookupPoint.X; x < lookupPoint.X + SubSampleSize; x++)
                        {
                            inputVector[inputIndex++] = fa[y, x];
                        }
                    }

                    if (lookupIndex != lookupArray.Length - 1)
                    {
                        entries.AddLast(new VectorFlowEntry<double>(inputVector, NullOutput)); 
                    }
                    else
                    {
                        entries.AddLast(new VectorFlowEntry<double>(inputVector, CreateOutputVector(fs), NumberOfComputationIterations));
                    }
                }

                return new NeuralVectorFlow(index, entries.ToArray());
            }
        }
        private void ProcessNextVectors(NativeActivityContext context, NeuralVectorFlow[] result)
        {
            bool reinitialize = false;
            IList<NeuralVectorFlow> finalResult = result;

            if (UseCache)
            {
                var vars = ComputationContext.GetVariables(context, this);
                var cache = vars.Get<SerializableCache>(CacheVarName).Cache;

                // Cache results:
                if (result != null)
                {
                    foreach (var vectors in result)
                    {
                        string key = vectors.Index.ToString();
                        cache[key] = vectors;
                    }
                }

                // Combine cached vectors with result:
                var vectorsFromCache = cachedVectorFlows.Get(context);
                cachedVectorFlows.Set(context, null);

                if (result != null)
                {
                    if (vectorsFromCache.Count != 0)
                    {
                        finalResult = result.Concat(vectorsFromCache).ToList();
                    }
                }
                else
                {
                    finalResult = vectorsFromCache.ToList();
                }
            }

            if (ReinitializationFrequency != null && DoReinitializeVectorProvider != null)
            {
                var freq = ReinitializationFrequency.Get(context);
                if (freq > 0)
                {
                    var vars = ComputationContext.GetVariables(context, this);
                    int iterations = vars.Get<int>(IterationsVarName);

                    if ((++iterations % freq) == 0)
                    {
                        context.ScheduleAction(DoReinitializeVectorProvider, OnReinitializeVectorProviderCompleted);
                        reinitialize = true;
                    }

                    vars.Set(IterationsVarName, iterations);
                }
            }

            var finalArray = finalResult as NeuralVectorFlow[];
            if (finalArray == null) finalArray = finalResult.ToArray();

            GetNextVectorsDone(context, finalArray, reinitialize ? ResetSchedule.AfterExecution : ResetSchedule.None);
        }
 private void OnGetNextVectorsCompleted(NativeActivityContext context, ActivityInstance instance, NeuralVectorFlow[] result)
 {
     ProcessNextVectors(context, result);
 }