public void Optimize(Dictionary<double, double> values)
        {
            var costFunction = new SquareCostFunction(_lppl);
              var lastCost = 10E6;
              var cost = 0.0;
              var costs = new List<double>();

              _lpplGradient = new LpplGradient(_lppl, values);

              var setpsSinceLastChange = 0;
              var maxNorm = 10E6;

              double stepSize = 10E-5;

              do
              {
            var gradient = new DenseVector(3, 0.0);

            foreach (var value in values)
            {
              var t = value.Key;
              var deltaValue = value.Value - _lppl.Value(t);
              gradient += - _lpplGradient.Gradient(t) * deltaValue;
            }

            _lppl.M -= gradient[0] * stepSize;
            _lppl.Omega -= gradient[1] * stepSize;
            _lppl.Tc -= gradient[2] * stepSize;

            var optimizer = new LpplLinearOptimizer(_lppl);
            optimizer.Optimize(values);

            cost = costFunction.Evaluate(values);
            costs.Add(costFunction.Evaluate(values));

            if (lastCost - cost < 0)
            {
              stepSize /= 2.0;
              setpsSinceLastChange++;
            }
            lastCost = cost;

            //var norm = gradient.Norm(1);
            //if (norm < maxNorm)
            //{
            //  maxNorm = norm;
            //  setpsSinceLastChange = 0;
            //}
            Console.WriteLine(cost);
            Console.WriteLine(gradient);
              } while (setpsSinceLastChange < 2);

              Console.WriteLine(costs.ToListPlot());
        }
        public void Optimize(Dictionary<double, double> values)
        {
            _clcf = new ConstraintLcFunction(_lcf, values);

              var costFunction = new CostFunction(_clcf, values);
              var lastCost = costFunction.Evaluate();
              var costs = new List<double>();

              var expectedStepSize = 0.01;
              var setpsSinceLastChange = 0;
              var stepsSinceDecrease = 0;

              do
              {
            costs.Add(lastCost);

            var gradient = costFunction.Gradient();

            var norm = Math.Sqrt(gradient.ScalarProduct(gradient));
            var stepSize = - expectedStepSize / norm;

            _clcf.AddToB(stepSize.ScalarProduct(gradient));

            double cost = costFunction.Evaluate();

            if (lastCost - cost < 0 && stepsSinceDecrease > 5)
            {
              Console.WriteLine("DECREASE STEP SIZE:" + expectedStepSize);
              expectedStepSize /= 2.0;
              setpsSinceLastChange++;
              stepsSinceDecrease = 0;
            }
            else if (Math.Abs(lastCost - cost) < 10E-15)
            {
              break;
            }
            lastCost = cost;

            Console.WriteLine(cost);
            Console.WriteLine(gradient.ListToString());
            stepsSinceDecrease++;
              } while (setpsSinceLastChange < 20);

              Console.WriteLine(costs.ToListPlot());
        }