/// <inheritdoc />
        public override void Iteration()
        {
            if (!_initComplete)
            {
                _hessian.Init(_network, Training);
                _initComplete = true;
            }

            PreIteration();

            _hessian.Clear();
            _weights = NetworkCODEC.NetworkToArray(_network);

            _hessian.Compute();
            double currentError = _hessian.SSE;

            SaveDiagonal();

            double startingError = currentError;
            bool   done          = false;
            bool   singular;

            while (!done)
            {
                ApplyLambda();
                var decomposition = new LUDecomposition(_hessian.HessianMatrix);

                singular = decomposition.IsNonsingular;

                if (singular)
                {
                    _deltas = decomposition.Solve(_hessian.Gradients);
                    UpdateWeights();
                    currentError = CalculateError();
                }

                if (!singular || currentError >= startingError)
                {
                    _lambda *= ScaleLambda;
                    if (_lambda > LambdaMax)
                    {
                        _lambda = LambdaMax;
                        done    = true;
                    }
                }
                else
                {
                    _lambda /= ScaleLambda;
                    done     = true;
                }
            }

            Error = currentError;

            PostIteration();
        }
        /// <summary>
        /// Perform one iteration.
        /// </summary>
        public override void Iteration()
        {
            LUDecomposition decomposition;

            PreIteration();

            _hessian.Clear();
            _weights = NetworkCODEC.NetworkToArray(_network);

            _hessian.Compute();
            double currentError = _hessian.SSE;

            SaveDiagonal();

            double startingError = currentError;
            bool   done          = false;

            while (!done)
            {
                ApplyLambda();
                decomposition = new LUDecomposition(_hessian.HessianMatrix);

                if (decomposition.IsNonsingular)
                {
                    _deltas = decomposition.Solve(_hessian.Gradients);

                    UpdateWeights();
                    currentError = CalculateError();

                    if (currentError < startingError)
                    {
                        _lambda /= LevenbergMarquardtTraining.ScaleLambda;
                        done     = true;
                    }
                }

                if (!done)
                {
                    _lambda *= LevenbergMarquardtTraining.ScaleLambda;
                    if (_lambda > LevenbergMarquardtTraining.LambdaMax)
                    {
                        _lambda = LevenbergMarquardtTraining.LambdaMax;
                        done    = true;
                    }
                }
            }

            Error = currentError;

            PostIteration();
        }