/// <inheritdoc/>
        public override void Compute()
        {
            Clear();
            double e           = 0;
            int    weightCount = network.Flat.Weights.Length;

            for (int outputNeuron = 0; outputNeuron < network.OutputCount; outputNeuron++)
            {
                // handle context
                if (flat.HasContext)
                {
                    _workers[0].Network.ClearContext();
                }

                if (_workers.Length > 1)
                {
                    Parallel.ForEach(_workers, worker =>
                    {
                        worker.Run();
                        worker.OutputNeuron = outputNeuron;
                    });
                }
                else
                {
                    _workers[0].OutputNeuron = outputNeuron;
                    _workers[0].Run();
                }

                // aggregate workers

                foreach (ChainRuleWorker worker in _workers)
                {
                    e += worker.Error;
                    for (int i = 0; i < weightCount; i++)
                    {
                        gradients[i] += worker.Gradients[i];
                    }

                    EngineArray.ArrayAdd(Hessian, worker.Hessian);
                }
            }

            sse = e / 2;
        }