示例#1
0
        public void LambdaFunctionTest3()
        {
            double x = 0;

            Func <double> expected = () => x * x + 1;
            var           actual   = new QuadraticObjectiveFunction(() => x * x + 1);

            for (int i = 0; i < 10; i++)
            {
                x = (i - 5) / 10.0;

                double a = actual.Function(new[] { x });
                double e = expected();

                Assert.AreEqual(e, a, 1e-10);
                Assert.IsFalse(Double.IsNaN(a));
                Assert.IsFalse(Double.IsNaN(e));
            }
        }
        public void DocumentationTest()
        {
            #region doc_example
            // Linear constraints are common in numerical optimization.
            // Constraints can be defined using strings, expressions or
            // vectors. Suppose we have a quadratic objective function:
            var f = new QuadraticObjectiveFunction("2x² + 4y² - 2xy + 6");

            // Then the following three are all equivalent:
            var lc1 = new LinearConstraint(f, "3*x + 5*y <= 7");

            double x = 0, y = 0; // Define some dummy variables
            var    lc2 = new LinearConstraint(f, () => 3 * x + 5 * y <= 7);

            var lc3 = new LinearConstraint(numberOfVariables: 2)
            {
                CombinedAs = new double[] { 3, 5 },
                ShouldBe   = ConstraintType.LesserThanOrEqualTo,
                Value      = 7
            };

            // Then, we can check whether a constraint is violated and, if so,
            // by how much.
            double[] vector = { -2, 3 };

            if (lc1.IsViolated(vector))
            {
                // act on violation...
            }

            double violation = lc2.GetViolation(vector); // negative if violated

            #endregion

            double expected = -2;
            double v1       = lc1.GetViolation(vector);
            double v2       = lc2.GetViolation(vector);
            double v3       = lc3.GetViolation(vector);

            Assert.AreEqual(expected, v1);
            Assert.AreEqual(expected, v2);
            Assert.AreEqual(expected, v3);
        }
示例#3
0
        public void Hessian_test_4()
        {
            const int    Size      = 30;
            const double Tolerance = 1e-8;

            for (int i = 0; i < 10; i++)
            {
                double[,] mat = Matrix.Random(Size);
                double[,] Q   = mat.DotWithTransposed(mat);
                double[] d = Vector.Random(Size);

                var qof = new QuadraticObjectiveFunction(Q, d);

                var calculator = new FiniteDifferences(Size, qof.Function);

                double[][] result = calculator.Hessian(Vector.Random(Size));

                Assert.IsTrue(result.IsEqual(Q, Tolerance));
            }
        }
        public void HomogeneousTest2()
        {
            double[,] quadraticTerms =
            {
                { 1, 0, 1 },
                { 0, 2, 0 },
                { 1, 0, 1 },
            };

            double[] linearTerms = { 0, 0, 0 };

            var target = new QuadraticObjectiveFunction(quadraticTerms, linearTerms);

            var function = target.Function;
            var gradient = target.Gradient;

            FiniteDifferences fd = new FiniteDifferences(3, function);

            double[][] x =
            {
                new double[] {      1,  2,   3 },
                new double[] {      3,  1,   4 },
                new double[] {     -6,  5,   9 },
                new double[] {     31, 25, 246 },
                new double[] { -0.102,  0,  10 },
            };

            { // Gradient test
                for (int i = 0; i < x.Length; i++)
                {
                    double[] expected = fd.Gradient(x[i]);
                    double[] actual   = gradient(x[i]);

                    for (int j = 0; j < actual.Length; j++)
                    {
                        Assert.AreEqual(expected[j], actual[j], 1e-8);
                    }
                }
            }
        }
示例#5
0
        public void ConstructorTest1()
        {
            var f = new QuadraticObjectiveFunction("a + b = 0");

            var constraints1 = new[]
            {
                new LinearConstraint(f, "0.0732 * a + 0.0799 * b = 0.098"),
                new LinearConstraint(f, "a + b = 1"),
                new LinearConstraint(f, "a >= 0"),
                new LinearConstraint(f, "b >= 0"),
                new LinearConstraint(f, "a >= 0.5")
            };

            var constraints2 = new[]
            {
                new LinearConstraint(f, "0.0732 * a + 0.0799 * b - 0.098 = 0"),
                new LinearConstraint(f, "a + b -2 = -1"),
                new LinearConstraint(f, "-a <= 0"),
                new LinearConstraint(f, "-b <= 0"),
                new LinearConstraint(f, "-a + 0.5 <= 0")
            };

            for (int i = 0; i < constraints1.Length; i++)
            {
                var c1 = constraints1[i];
                var c2 = constraints2[i];

                for (double a = -10; a < 10; a += 0.1)
                {
                    for (double b = -10; b < 10; b += 0.1)
                    {
                        double[] x        = { a, b };
                        double   actual   = c1.GetViolation(x);
                        double   expected = c2.GetViolation(x);
                        Assert.AreEqual(expected, actual);
                    }
                }
            }
        }
        /// <summary>
        /// Perform portfolio optimization for a provided matrix of historical returns and an array of expected returns
        /// </summary>
        /// <param name="historicalReturns">Matrix of annualized historical returns where each column represents a security and each row returns for the given date/time (size: K x N).</param>
        /// <param name="expectedReturns">Array of double with the portfolio annualized expected returns (size: K x 1).</param>
        /// <param name="covariance">Multi-dimensional array of double with the portfolio covariance of annualized returns (size: K x K).</param>
        /// <returns>Array of double with the portfolio weights (size: K x 1)</returns>
        public double[] Optimize(double[,] historicalReturns, double[] expectedReturns = null, double[,] covariance = null)
        {
            covariance = covariance ?? historicalReturns.Covariance();
            var returns = (expectedReturns ?? historicalReturns.Mean(0)).Subtract(_riskFreeRate);

            var size = covariance.GetLength(0);
            var x0   = Vector.Create(size, 1.0 / size);
            var k    = returns.Dot(x0);

            var constraints = new List <LinearConstraint>
            {
                // Sharpe Maximization under Quadratic Constraints
                // https://quant.stackexchange.com/questions/18521/sharpe-maximization-under-quadratic-constraints
                // (µ − r_f)^T w = k
                new LinearConstraint(size)
                {
                    CombinedAs = returns,
                    ShouldBe   = ConstraintType.EqualTo,
                    Value      = k
                }
            };

            // Σw = 1
            constraints.Add(GetBudgetConstraint(size));

            // lw ≤ w ≤ up
            constraints.AddRange(GetBoundaryConditions(size));

            // Setup solver
            var optfunc = new QuadraticObjectiveFunction(covariance, Vector.Create(size, 0.0));
            var solver  = new GoldfarbIdnani(optfunc, constraints);

            // Solve problem
            var success     = solver.Minimize(Vector.Copy(x0));
            var sharpeRatio = returns.Dot(solver.Solution) / solver.Value;

            return(success ? solver.Solution : x0);
        }
示例#7
0
        public void GoldfarbIdnaniConstructorTest1()
        {
            double[,] D = Matrix.Identity(3);
            double[] d = { 0, 5, 0 };

            double[,] A =
            {
                { -4, -3, 0 },
                {  2,  1, 0 },
                {  0, -2, 1 },
            };

            double[] b = { -8, 2, 0 };

            List <LinearConstraint> constraints = new List <LinearConstraint>();

            constraints.Add(new LinearConstraint(-4, -3, +0)
            {
                Value = -8
            });
            constraints.Add(new LinearConstraint(+2, +1, +0)
            {
                Value = +2
            });
            constraints.Add(new LinearConstraint(+0, -2, +1)
            {
                Value = +0
            });

            QuadraticObjectiveFunction f = new QuadraticObjectiveFunction("2x² + y - z + 2");

            GoldfarbIdnani target = new GoldfarbIdnani(f, constraints);

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));
        }
示例#8
0
        public Tuple <QuadraticObjectiveFunction, List <LinearConstraint> > objectFuncQHStyle()
        {
            Matrix <double> QMatrix = Matrix <double> .Build.Dense(_aMatrix.RowCount, _aMatrix.RowCount);

            Vector <double> HVector = Vector <double> .Build.Dense(_aMatrix.RowCount);

            for (int r = 0; r < _aMatrix.RowCount; r++)
            {
                Matrix <double> Q = Matrix <double> .Build.Dense(_aMatrix.RowCount, _aMatrix.RowCount);

                Vector <double> H = Vector <double> .Build.Dense(_aMatrix.RowCount);

                for (int c1 = 0; c1 < _aMatrix.RowCount; c1++)
                {
                    for (int c2 = 0; c2 < _aMatrix.RowCount; c2++)
                    {
                        Q[c1, c2] = 2 * _aMatrix[r, c1] * _aMatrix[r, c2];
                    }
                    H[c1] = -2 * _aMatrix[r, c1] * _expTrigProb[r];
                }
                HVector = HVector.Add(H);
                QMatrix = QMatrix.Add(Q);
            }
            string[] variablesName = new string[_aMatrix.RowCount];
            for (int i = 0; i < variablesName.Length; i++)
            {
                variablesName[i] = "x" + i.ToString();
            }
            QuadraticObjectiveFunction f = new QuadraticObjectiveFunction
                                               (QMatrix.ToArray(), HVector.ToArray(), variablesName);

            f.ConstantTerm = _expTrigProb.Sum(x => x * x);
            List <LinearConstraint> constraints = ConstraintConstruct();

            return(new Tuple <QuadraticObjectiveFunction, List <LinearConstraint> >(item1: f, item2: constraints));
        }
        public void OperatorDivisionTest()
        {
            double x = 0;
            double y = 0;
            double z = 0;

            Func <double> expected1 = () => 2 * y * x - x * y + y * z;
            var           actual1   = new QuadraticObjectiveFunction(() => 2 * y * x - x * y + y * z);
            var           actual    = actual1 / 5;

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    for (int k = 0; k < 10; k++)
                    {
                        x = (i - 5) / 10.0;
                        y = (j - 5) / 10.0;
                        z = (k - 5) / 10.0;

                        double a = actual.Function(new[] { x, y, z });
                        double e = expected1() / 5;

                        Assert.AreEqual(e, a, 1e-10);
                        Assert.IsFalse(double.IsNaN(a));
                        Assert.IsFalse(double.IsNaN(e));
                    }
                }
            }

            Assert.ThrowsException <DivideByZeroException>(() =>
            {
                var resultant = actual / 0;
                Assert.IsNull(resultant);
            });
        }
        public void LambdaFunctionTest()
        {
            double x = 0;
            double y = 0;

            Func <double> expected = () => - 2 * x * x + x * y - y * y + 5 * y;
            var           actual   = new QuadraticObjectiveFunction(() => - 2 * x * x + x * y - y * y + 5 * y);

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    x = (i - 5) / 10.0;
                    y = (j - 5) / 10.0;

                    double a = actual.Function(new[] { x, y });
                    double e = expected();

                    Assert.AreEqual(e, a, 1e-10);
                    Assert.IsFalse(double.IsNaN(a));
                    Assert.IsFalse(double.IsNaN(e));
                }
            }
        }
示例#11
0
        public void GoldfarbIdnaniConstructorTest3()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = 2x² - xy + 4y² - 5x - 6y
            //
            //  s.t.   x - y  ==   5  (x minus y should be equal to 5)
            //             x  >=  10  (x should be greater than or equal to 10)
            //

            // In this example we will be using some symbolic processing.
            // The following variables could be initialized to any value.
            double x = 0, y = 0;

            // Create our objective function using a lambda expression
            var f = new QuadraticObjectiveFunction(() => 2 * (x * x) - (x * y) + 4 * (y * y) - 5 * x - 6 * y);

            // Now, create the constraints
            List <LinearConstraint> constraints = new List <LinearConstraint>();

            constraints.Add(new LinearConstraint(f, () => x - y == 5));
            constraints.Add(new LinearConstraint(f, () => x >= 10));

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnaniQuadraticSolver solver = new GoldfarbIdnaniQuadraticSolver(2, constraints);


            double[,] A =
            {
                { 1, -1 },
                { 1,  0 },
            };

            double[] b =
            {
                5,
                10,
            };

            Assert.IsTrue(A.IsEqual(solver.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(solver.ConstraintValues));


            double[,] Q =
            {
                { +2 * 2,     -1 },
                {     -1, +4 * 2 },
            };

            double[] d = { -5, -6 };


            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));


            // And attempt to solve it.
            double minimumValue = solver.Minimize(f);
        }
示例#12
0
        public override void Initialize()
        {
            SetStartDate(2015, 1, 1);
            SetEndDate(DateTime.Now);
            SetCash(10000);

            foreach (var equity in _equities)
            {
                AddSecurity(SecurityType.Equity, equity, Resolution.Minute);
            }

            _s          = new int[_stocks.Length];
            _x0         = new int[_stocks.Length];
            _x1         = Enumerable.Repeat(1d / _stocks.Length, _stocks.Length).ToArray();
            _symbolData = new Dictionary <Symbol, SymbolData>();

            _bb     = new BollingerBands(_spy, 22, 1.05m, MovingAverageType.Simple);
            _spyWvf = new RollingWindow <decimal>(22);

            foreach (var stock in _stocks)
            {
                var closes      = new RollingWindow <decimal>(17 * 390);
                var dailyCloses = new RollingWindow <TradeBar>(29);

                var dailyConsolidator = new TradeBarConsolidator(TimeSpan.FromDays(1));
                dailyConsolidator.DataConsolidated += (sender, consolidated) => _symbolData[consolidated.Symbol].UpdateDaily(consolidated);
                SubscriptionManager.AddConsolidator(stock, dailyConsolidator);

                _symbolData.Add(stock, new SymbolData(closes, dailyCloses));
            }

            var spyDailyCloses = new RollingWindow <TradeBar>(28);

            var spyDailyConsolidator = new TradeBarConsolidator(TimeSpan.FromDays(1));

            spyDailyConsolidator.DataConsolidated += (sender, consolidated) => _symbolData[consolidated.Symbol].UpdateDaily(consolidated);
            SubscriptionManager.AddConsolidator(_spy, spyDailyConsolidator);
            _symbolData.Add(_spy, new SymbolData(null, spyDailyCloses));


            var vxxDailyConsolidator = new TradeBarConsolidator(TimeSpan.FromDays(1));

            vxxDailyConsolidator.DataConsolidated += (sender, consolidated) => _symbolData[consolidated.Symbol].UpdateDaily(consolidated);
            SubscriptionManager.AddConsolidator(_vxx, vxxDailyConsolidator);

            _symbolData.Add(_spy, new SymbolData(null, spyDailyCloses));

            Schedule.On(DateRules.EveryDay(), TimeRules.AfterMarketOpen("SPY", 15d), () =>
            {
                if (_symbolData[_spy].IsReady)
                {
                    return;
                }

                var vxxCloses = _symbolData[_vxx].DailyHistory.Select(tb => tb.Close);
                var vxxLows   = _symbolData[_vxx].DailyHistory.Select(tb => tb.Low);

                // William's VIX Fix indicator a.k.a. the Synthetic VIX
                var previousMax = vxxCloses.Take(28).Max();
                var previousWvf = 100 * (previousMax - vxxLows.Skip(27).First()) / previousMax;

                var max = vxxCloses.Skip(1).Max();
                var wvf = 100 * (max - vxxLows.Last()) / max;

                if (previousWvf < WvfLimit && wvf >= WvfLimit)
                {
                    SetHoldings(_vxx, 0);
                    SetHoldings(_xiv, 0.07);
                }
                else if (previousWvf > WvfLimit && wvf <= WvfLimit)
                {
                    SetHoldings(_vxx, 0.07);
                    SetHoldings(_xiv, 0);
                }
            });

            Schedule.On(DateRules.EveryDay(), TimeRules.AfterMarketOpen("SPY", 15d), () =>
            {
                if (_symbolData[_spy].IsReady)
                {
                    return;
                }

                var spyCloses = _symbolData[_spy].NDaysDailyHistory(22).Select(tb => tb.Close);
                var spyLows   = _symbolData[_spy].NDaysDailyHistory(22).Select(tb => tb.Low);
                var max       = spyCloses.Max();
                var wvf       = 100 * (max - spyLows.Last()) / max;
                _bb.Update(DateTime.Now, wvf);
                _spyWvf.Add(wvf);

                var rangeHigh = _spyWvf.Max() * 0.9m;

                var latestClose = _symbolData[_spy].NDaysDailyHistory(1).First().Close;
                var spy_higher_then_Xdays_back = latestClose > _symbolData[_spy].NDaysDailyHistory(3).First().Close;
                var spy_lower_then_longterm    = latestClose > _symbolData[_spy].NDaysDailyHistory(40).First().Close;
                var spy_lower_then_midterm     = latestClose > _symbolData[_spy].NDaysDailyHistory(14).First().Close;

                // Alerts Criteria
                var alert2 = !(_spyWvf[0] >= _bb.UpperBand && _spyWvf[0] >= rangeHigh) &&
                             (_spyWvf[1] >= _bb.UpperBand && _spyWvf[2] >= rangeHigh);

                if ((alert2 || spy_higher_then_Xdays_back) && (spy_lower_then_longterm || spy_lower_then_midterm))
                {
                    SetHoldings(_spy, 0.3);
                    SetHoldings(_shortSpy, 0);
                }
                else
                {
                    SetHoldings(_spy, 0);
                    SetHoldings(_shortSpy, 0.3);
                }
            });

            Schedule.On(DateRules.EveryDay(), TimeRules.AfterMarketOpen("SPY", 15d), () =>
            {
                if (_symbolData[_spy].IsReady)
                {
                    return;
                }

                var returns = new List <double[]>(); // 28?

                foreach (var stock in _stocks)
                {
                    _symbolData[stock].UpdateWeights();
                    returns.Add(_symbolData[stock].PercentReturn.Select(pr => (double)(pr / _symbolData[stock].Norm)).ToArray());
                }

                var retNorm    = _symbolData.Select(s => s.Value.Norm);
                var retNormMax = retNorm.Max();
                var epsFactor  = retNormMax > 0 ? 0.9m : 1.0m;
                var eps        = (double)(epsFactor * retNormMax);

                var constraints = new List <LinearConstraint>();

                constraints.Add(new LinearConstraint(Enumerable.Repeat(1.0, _stocks.Length).ToArray())
                {
                    ShouldBe = ConstraintType.EqualTo,
                    Value    = 1
                });

                constraints.Add(new LinearConstraint(retNorm.Select(x => (double)x).ToArray())
                {
                    ShouldBe = ConstraintType.GreaterThanOrEqualTo,
                    Value    = eps + eps * 0.01
                }); // Add and subtract small bounce to achieve inequality?

                constraints.Add(new LinearConstraint(retNorm.Select(x => (double)x).ToArray())
                {
                    ShouldBe = ConstraintType.LesserThanOrEqualTo,
                    Value    = eps - eps * 0.01
                }); // Add and subtract small bounce to achieve inequality?

                constraints.Add(new LinearConstraint(_stocks.Length)
                {
                    VariablesAtIndices = Enumerable.Range(0, _stocks.Length).ToArray(),
                    ShouldBe           = ConstraintType.GreaterThanOrEqualTo,
                    Value = 0
                });

                constraints.Add(new LinearConstraint(_stocks.Length)
                {
                    VariablesAtIndices = Enumerable.Range(0, _stocks.Length).ToArray(),
                    ShouldBe           = ConstraintType.LesserThanOrEqualTo,
                    Value = 1
                });

                var initialGuess = new double[_stocks.Length];
                var f            = new QuadraticObjectiveFunction(() => Variance(initialGuess, returns.ToMatrix()));

                var solver = new GoldfarbIdnani(f, constraints);
                solver.Minimize();

                var weights     = _x1;
                var totalWeight = weights.Sum();

                if (solver.Status == GoldfarbIdnaniStatus.Success)
                {
                    weights = solver.Solution;
                }

                for (var i = 0; i < _stocks.Length; i++)
                {
                    SetHoldings(_stocks[i], weights[i] / totalWeight);
                }
            });
        }
示例#13
0
        public void GoldfarbIdnaniMinimizeLessThanWithEqualityTest()
        {
            // This test reproduces Issue #33 at Google Code Tracker
            // https://code.google.com/p/accord/issues/detail?id=33

            // Create objective function using the
            // Hessian Q and linear terms vector d.

            double[,] Q =
            {
                {  0.12264004, 0.011579293, 0.103326825, 0.064073439 },
                { 0.011579293,    0.033856, 0.014311947, 0.014732381 },
                { 0.103326825, 0.014311947,  0.17715681, 0.067615114 },
                { 0.064073439, 0.014732381, 0.067615114,  0.11539609 }
            };

            Assert.IsTrue(Q.IsPositiveDefinite());

            double[] d = { 0, 0, 0, 0 };

            var f = new QuadraticObjectiveFunction(Q, d, "a", "b", "c", "d");

            // Now, create the constraints
            var constraints = new LinearConstraintCollection();

            constraints.Add(new LinearConstraint(f, "0.0732 * a + 0.0799 * b + 0.1926 * c + 0.0047 * d = 0.098"));
            constraints.Add(new LinearConstraint(f, "a + b + c + d = 1"));
            constraints.Add(new LinearConstraint(f, "-a <= 0"));
            constraints.Add(new LinearConstraint(f, "-b <= 0"));
            constraints.Add(new LinearConstraint(f, "-c <= 0"));
            constraints.Add(new LinearConstraint(f, "-d <= 0"));
            constraints.Add(new LinearConstraint(f, "-a + 0.5 <= 0.0"));

            Assert.AreEqual(-1, constraints[6].CombinedAs[0]);
            Assert.AreEqual(-0.5, constraints[6].Value);
            Assert.AreEqual(0.1, constraints[6].GetViolation(new double[] { 0.6 }), 1e-10);
            Assert.AreEqual(-0.1, constraints[6].GetViolation(new double[] { 0.4 }), 1e-10);

            bool psd = Q.IsPositiveDefinite();

            double[] b;
            int      eq;

            double[,] A = constraints.CreateMatrix(4, out b, out eq);

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);

            // And attempt to solve it.
            Assert.IsTrue(solver.Minimize());
            double minValue = solver.Value;

            double[] expected = { 0.50000000000000, 0.30967169476486, 0.19032830523514, 0 };
            double[] actual   = solver.Solution;

            for (int i = 0; i < constraints.Count; i++)
            {
                double error = constraints[i].GetViolation(actual);
                Assert.IsTrue(error >= 0);
            }

            for (int i = 0; i < expected.Length; i++)
            {
                double e = expected[i];
                double a = actual[i];
                Assert.AreEqual(e, a, 1e-10);
            }
        }
示例#14
0
        /// <summary>
        ///   Computes the optimization algorithm when the user
        ///   presses the "Compute" button in the main interface.
        /// </summary>
        ///
        private void btnCompute_Click(object sender, EventArgs e)
        {
            // First, get what the user entered on screen:
            String strObjective = tbObjective.Text;

            String[] strConstraints = tbConstraints.Lines;

            // Check if this is a minimization or maximization task
            bool minimize = (string)comboBox1.SelectedItem == "min";

            // Now we can start creating our function:
            QuadraticObjectiveFunction function;

            LinearConstraint[] constraints = new LinearConstraint[strConstraints.Length];


            // Attempt to parse the string and create the objective function
            if (!QuadraticObjectiveFunction.TryParse(strObjective, out function))
            {
                tbSolution.Text = "Invalid objective function.";
                return;
            }

            // Create list of constraints
            for (int i = 0; i < constraints.Length; i++)
            {
                if (!LinearConstraint.TryParse(strConstraints[i], function, out constraints[i]))
                {
                    tbSolution.Text = "Invalid constraint at line " + i + ".";
                    return;
                }
            }


            // After the text has been parsed, create the solver
            var solver = new GoldfarbIdnani(function, constraints);


            // Solve the optimization problem:
            if (minimize)
            {
                solver.Minimize(); // the user wants to minimize it
            }
            else
            {
                solver.Maximize();   // the user wants to maximize it
            }
            if (solver.Status == GoldfarbIdnaniStatus.NonPositiveDefinite)
            {
                tbSolution.Text = "Function is not positive definite.";
                return;
            }
            else if (solver.Status == GoldfarbIdnaniStatus.NoPossibleSolution)
            {
                tbSolution.Text = "No possible solution could be attained.";
                return;
            }


            // Retrieve the computed solution
            double[] solution = solver.Solution;

            // And let's format and display it:
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Solution:");
            sb.AppendLine();
            sb.AppendLine(" " + strObjective + " = " + solver.Value);
            sb.AppendLine();

            for (int i = 0; i < solution.Length; i++)
            {
                string variableName = function.Indices[i];
                sb.AppendLine(" " + variableName + " = " + solution[i]);
            }

            tbSolution.Text = sb.ToString();
        }
示例#15
0
        public void BalanceAccord()
        {
            var func        = new QuadraticObjectiveFunction(H.ToArray(), dVector.ToArray());
            var constraints = new List <LinearConstraint>();

            //добавление ограничений узлов
            for (var j = 0; j < measuredValues.ToArray().Length; j++)
            {
                if (inputData.balanceSettings.balanceSettingsConstraints == 0 || measureIndicator[j, j] == 0.0)
                {
                    constraints.Add(new LinearConstraint(1)
                    {
                        VariablesAtIndices = new[] { j },
                        ShouldBe           = ConstraintType.GreaterThanOrEqualTo,
                        Value = inputData.BalanceInputVariables[j].technologicLowerBound
                    });

                    constraints.Add(new LinearConstraint(1)
                    {
                        VariablesAtIndices = new[] { j },
                        ShouldBe           = ConstraintType.LesserThanOrEqualTo,
                        Value = inputData.BalanceInputVariables[j].technologicUpperBound
                    });
                }
                else
                {
                    constraints.Add(new LinearConstraint(1)
                    {
                        VariablesAtIndices = new[] { j },
                        ShouldBe           = ConstraintType.GreaterThanOrEqualTo,
                        Value = inputData.BalanceInputVariables[j].metrologicLowerBound
                    });

                    constraints.Add(new LinearConstraint(1)
                    {
                        VariablesAtIndices = new[] { j },
                        ShouldBe           = ConstraintType.LesserThanOrEqualTo,
                        Value = inputData.BalanceInputVariables[j].metrologicUpperBound
                    });
                }
            }
            //Ограничения для решения задачи баланса
            for (var j = 0; j < reconciledValues.ToArray().Length; j++)
            {
                var notNullElements        = Array.FindAll(incidenceMatrix.ToArray().GetRow(j), x => Math.Abs(x) > 0.0000001);
                var notNullElementsIndexes = new List <int>();
                for (var k = 0; k < measuredValues.ToArray().Length; k++)
                {
                    if (Math.Abs(incidenceMatrix[j, k]) > 0.0000001)
                    {
                        notNullElementsIndexes.Add(k);
                    }
                }

                constraints.Add(new LinearConstraint(notNullElements.Length)
                {
                    VariablesAtIndices = notNullElementsIndexes.ToArray(),
                    CombinedAs         = notNullElements,
                    ShouldBe           = ConstraintType.EqualTo,
                    Value = reconciledValues[j]
                });
            }

            var      solver = new GoldfarbIdnani(func, constraints);
            DateTime CalculationTimeStart = DateTime.Now;

            if (!solver.Minimize())
            {
                throw new ApplicationException("Failed to solve balance task.");
            }
            DateTime CalculationTimeFinish = DateTime.Now;
            double   disbalanceOriginal    = incidenceMatrix.Multiply(measuredValues).Subtract(reconciledValues).ToArray().Euclidean();
            double   disbalance            = incidenceMatrix.Multiply(SparseVector.OfVector(new DenseVector(solver.Solution))).Subtract(reconciledValues).ToArray().Euclidean();

            double[] solution = new double[countOfThreads];
            sol = new double[countOfThreads];
            for (int i = 0; i < solution.Length; i++)
            {
                solution[i] = solver.Solution[i];
                sol[i]      = solution[i];
            }

            balanceOutput          = new BalanceOutput();
            balanceOutputVariables = new List <OutputVariables>();
            for (int i = 0; i < solution.Length; i++)
            {
                InputVariables outputVariable = inputData.BalanceInputVariables[i];
                balanceOutputVariables.Add(new OutputVariables()
                {
                    id         = outputVariable.id,
                    name       = outputVariable.name,
                    value      = solution[i],
                    source     = outputVariable.sourceId,
                    target     = outputVariable.destinationId,
                    upperBound = (inputData.balanceSettings.balanceSettingsConstraints == 0 || measureIndicator[i, i] == 0.0) ? technologicRangeUpperBound[i] : metrologicRangeUpperBound[i],
                    lowerBound = (inputData.balanceSettings.balanceSettingsConstraints == 0 || measureIndicator[i, i] == 0.0) ? technologicRangeLowerBound[i] : metrologicRangeLowerBound[i]
                });
            }
            balanceOutput.CalculationTime        = (CalculationTimeFinish - CalculationTimeStart).TotalSeconds;
            balanceOutput.balanceOutputVariables = balanceOutputVariables;
            balanceOutput.DisbalanceOriginal     = disbalanceOriginal;
            balanceOutput.Disbalance             = disbalance;
            balanceOutput.GlobaltestValue        = GTR;
            balanceOutput.Status = "Success";
        }
示例#16
0
        public double[] Solve(double[] x0, double[,] a, double[] b, double[] measurability, double[] tolerance, double[] lower, double[] upper)
        {
            // Проверка аргументов на null
            _ = x0 ?? throw new ArgumentNullException(nameof(x0));
            _ = a ?? throw new ArgumentNullException(nameof(a));
            _ = b ?? throw new ArgumentNullException(nameof(b));
            _ = measurability ?? throw new ArgumentNullException(nameof(measurability));
            _ = tolerance ?? throw new ArgumentNullException(nameof(tolerance));
            _ = lower ?? throw new ArgumentNullException(nameof(lower));
            _ = upper ?? throw new ArgumentNullException(nameof(upper));

            //Проверка аргументов на размерности
            if (x0.Length == 0)
            {
                throw new ArgumentException(nameof(x0));
            }
            if (a.GetLength(1) != x0.Length)
            {
                throw new ArgumentException("Array length by dimension 1 is not equal to X0 length.", nameof(a));
            }
            if (b.Length != a.GetLength(0))
            {
                throw new ArgumentException("Array length is not equal to A length by 0 dimension.", nameof(b));
            }
            if (measurability.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(measurability));
            }
            if (tolerance.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(tolerance));
            }
            if (lower.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(lower));
            }
            if (upper.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(upper));
            }

            var i = Matrix.Diagonal(measurability);
            var w = Matrix.Diagonal(1.Divide(tolerance.Pow(2)));

            var h = i.Dot(w);
            var d = h.Dot(x0).Multiply(-1);

            var func        = new QuadraticObjectiveFunction(h, d);
            var constraints = new List <LinearConstraint>();

            //Нижние и верхние границы
            for (var j = 0; j < x0.Length; j++)
            {
                constraints.Add(new LinearConstraint(1)
                {
                    VariablesAtIndices = new[] { j },
                    ShouldBe           = ConstraintType.GreaterThanOrEqualTo,
                    Value = lower[j]
                });

                constraints.Add(new LinearConstraint(1)
                {
                    VariablesAtIndices = new[] { j },
                    ShouldBe           = ConstraintType.LesserThanOrEqualTo,
                    Value = upper[j]
                });
            }

            //Ограничения для решения задачи баланса
            for (var j = 0; j < b.Length; j++)
            {
                var notNullElements        = Array.FindAll(a.GetRow(j), x => Math.Abs(x) > 0.0000001);
                var notNullElementsIndexes = new List <int>();
                for (var k = 0; k < x0.Length; k++)
                {
                    if (Math.Abs(a[j, k]) > 0.0000001)
                    {
                        notNullElementsIndexes.Add(k);
                    }
                }

                constraints.Add(new LinearConstraint(notNullElements.Length)
                {
                    VariablesAtIndices = notNullElementsIndexes.ToArray(),
                    CombinedAs         = notNullElements,
                    ShouldBe           = ConstraintType.EqualTo,
                    Value = b[j]
                });
            }

            var solver = new GoldfarbIdnani(func, constraints);

            if (!solver.Minimize())
            {
                throw new ApplicationException("Failed to solve balance task.");
            }

            DisbalanceOriginal = a.Dot(x0).Subtract(b).Euclidean();
            Disbalance         = a.Dot(solver.Solution).Subtract(b).Euclidean();

            return(solver.Solution);
        }
示例#17
0
        public void GoldfarbIdnaniConstructorTest8()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = x² + 2xy + y² - y
            //
            //  s.t.   x >=  1
            //         y >=  1
            //

            double x = 0, y = 0;

            // http://www.wolframalpha.com/input/?i=min+x%C2%B2+%2B+2xy+%2B+y%C2%B2+-+y%2C+x+%3E%3D+1%2C+y+%3E%3D+1
            var f = new QuadraticObjectiveFunction(() => (x * x) + 2 * (x * y) + (y * y) - y);

            List <LinearConstraint> constraints = new List <LinearConstraint>();

            constraints.Add(new LinearConstraint(f, () => x >= 1));
            constraints.Add(new LinearConstraint(f, () => y >= 1));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            double[,] A =
            {
                { 1, 0 },
                { 0, 1 },
            };

            double[] b =
            {
                1,
                1,
            };

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));

            double[,] Q =
            {
                { 2, 2 },
                { 2, 2 },
            };

            double[] d = { 0, -1 };


            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));

            bool thrown = false;

            try
            {
                target.Minimize(f);
            }
            catch (NonPositiveDefiniteMatrixException)
            {
                thrown = true;
            }

            Assert.IsTrue(thrown);
        }
示例#18
0
        public void GoldfarbIdnaniConstructorTest9()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = 2x² + xy + y² - 5y
            //
            //  s.t.  -x - 3y >= -2
            //        -x -  y >= 0
            //              x >=  0
            //              y >=  0
            //



            double x = 0, y = 0;

            var f = new QuadraticObjectiveFunction(() => 2 * (x * x) + (x * y) + (y * y) - 5 * y);

            List <LinearConstraint> constraints = new List <LinearConstraint>();

            constraints.Add(new LinearConstraint(f, () => - x - 3 * y >= -2));
            constraints.Add(new LinearConstraint(f, () => - x - y >= 0));
            constraints.Add(new LinearConstraint(f, () => x >= 0));
            constraints.Add(new LinearConstraint(f, () => y >= 0));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            double[,] expectedA =
            {
                { -1, -3 },
                { -1, -1 },
                {  1,  0 },
                {  0,  1 },
            };

            double[] expectedb =
            {
                -2, 0, 0, 0
            };

            double[,] expectedQ =
            {
                { 4, 1 },
                { 1, 2 },
            };

            double[] expectedd =
            {
                0, -5
            };

            // Tested against R's QuadProg package

            /*
             * Qmat = matrix(c(4,1,1,2),2,2)
             * dvec = -c(0, -5)
             * Amat =  matrix(c(-1, -3, -1, -1, 1, 0, 0, 1), 2,4)
             * bvec = c(-2, 0, 0, 0)
             *
             * solve.QP(Qmat, dvec, Amat, bvec)
             */

            var actualA = target.ConstraintMatrix;
            var actualb = target.ConstraintValues;
            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(expectedA.IsEqual(actualA));
            Assert.IsTrue(expectedb.IsEqual(actualb));
            Assert.IsTrue(expectedQ.IsEqual(actualQ));
            Assert.IsTrue(expectedd.IsEqual(actuald));

            double min = target.Minimize(f);

            double[] solution = target.Solution;

            Assert.AreEqual(0, solution[0], 1e-10);
            Assert.AreEqual(0, solution[1], 1e-10);

            Assert.AreEqual(0.0, min, 1e-10);

            Assert.AreEqual(0, target.Lagrangian[0], 1e-10);
            Assert.AreEqual(5, target.Lagrangian[1], 1e-10);
            Assert.AreEqual(5, target.Lagrangian[2], 1e-10);
            Assert.AreEqual(0, target.Lagrangian[3], 1e-10);


            Assert.IsFalse(Double.IsNaN(min));

            foreach (double v in target.Solution)
            {
                Assert.IsFalse(double.IsNaN(v));
            }

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
示例#19
0
        public void GoldfarbIdnaniConstructorTest7()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = 3x² + 2xy + 3y² - y
            //
            //  s.t.   x >=  1
            //         y >=  1
            //

            double x = 0, y = 0;

            // http://www.wolframalpha.com/input/?i=min+x%C2%B2+%2B+2xy+%2B+y%C2%B2+-+y%2C+x+%3E%3D+1%2C+y+%3E%3D+1
            var f = new QuadraticObjectiveFunction(() => 3 * (x * x) + 2 * (x * y) + 3 * (y * y) - y);

            List <LinearConstraint> constraints = new List <LinearConstraint>();

            constraints.Add(new LinearConstraint(f, () => x >= 1));
            constraints.Add(new LinearConstraint(f, () => y >= 1));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            double[,] A =
            {
                { 1, 0 },
                { 0, 1 },
            };

            double[] b =
            {
                1,
                1,
            };

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));

            double[,] Q =
            {
                { 6, 2 },
                { 2, 6 },
            };

            double[] d = { 0, -1 };


            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));

            double minValue = target.Minimize(f);

            double[] solution = target.Solution;

            Assert.AreEqual(7, minValue);
            Assert.AreEqual(1, solution[0]);
            Assert.AreEqual(1, solution[1]);

            Assert.AreEqual(8, target.Lagrangian[0], 1e-5);
            Assert.AreEqual(7, target.Lagrangian[1], 1e-5);

            foreach (double v in target.Solution)
            {
                Assert.IsFalse(double.IsNaN(v));
            }

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
示例#20
0
        private void button1_Click(object sender, EventArgs e)
        {
            String objectiveString = tbObjective.Text;

            String[] constraintStrings = tbConstraints.Lines;
            bool     minimize          = (string)comboBox1.SelectedItem == "min";

            QuadraticObjectiveFunction function;

            LinearConstraint[] constraints = new LinearConstraint[constraintStrings.Length];

            try
            {
                // Create objective function
                function = new QuadraticObjectiveFunction(objectiveString);
            }
            catch (FormatException)
            {
                tbSolution.Text = "Invalid objective function.";
                return;
            }

            // Create list of constraints
            for (int i = 0; i < constraints.Length; i++)
            {
                try
                {
                    constraints[i] = new LinearConstraint(function, constraintStrings[i]);
                }
                catch (FormatException)
                {
                    tbSolution.Text = "Invalid constraint at line " + i + ".";
                    return;
                }
            }

            // Create solver
            var solver = new GoldfarbIdnaniQuadraticSolver(function.NumberOfVariables, constraints);

            try
            {
                // Solve the minimization or maximization problem
                double value = (minimize) ? solver.Minimize(function) : solver.Maximize(function);

                // Grab the solution found
                double[] solution = solver.Solution;

                // Format and display solution
                StringBuilder sb = new StringBuilder();

                sb.AppendLine("Solution:");
                sb.AppendLine();
                sb.AppendLine(" " + objectiveString + " = " + value);
                sb.AppendLine();
                for (int i = 0; i < solution.Length; i++)
                {
                    string variableName = function.Indices[i];
                    sb.AppendLine(" " + variableName + " = " + solution[i]);
                }

                tbSolution.Text = sb.ToString();
            }
            catch (NonPositiveDefiniteMatrixException)
            {
                tbSolution.Text = "Function is not positive definite.";
            }
            catch (ConvergenceException)
            {
                tbSolution.Text = "No possible solution could be attained.";
            }
        }
示例#21
0
        [Ignore()] // TODO: Remove this attribute
        public void GoldfarbIdnaniMinimizeTest1()
        {
            // This test reproduces Issue #33 at Google Code Tracker
            // https://code.google.com/p/accord/issues/detail?id=33

            // Create objective function using the
            // Hessian Q and linear terms vector d.

            double[,] Q =
            {
                {  0.12264004, 0.011579293, 0.103326825, 0.064073439 },
                { 0.011579293,    0.033856, 0.014311947, 0.014732381 },
                { 0.103326825, 0.014311947,  0.17715681, 0.067615114 },
                { 0.064073439, 0.014732381, 0.067615114,  0.11539609 }
            };

            Assert.IsTrue(Q.IsPositiveDefinite());

            double[] d = { 0, 0, 0, 0 };

            var f = new QuadraticObjectiveFunction(Q, d, "a", "b", "c", "d");

            // Now, create the constraints
            var constraints = new LinearConstraintCollection();

            constraints.Add(new LinearConstraint(f, "0.0732 * a + 0.0799 * b + 0.1926 * c + 0.0047 * d = 0.098"));
            constraints.Add(new LinearConstraint(f, "a + b + c + d = 1"));
            constraints.Add(new LinearConstraint(f, "a >= 0"));
            constraints.Add(new LinearConstraint(f, "b >= 0"));
            constraints.Add(new LinearConstraint(f, "c >= 0"));
            constraints.Add(new LinearConstraint(f, "d >= 0"));
            constraints.Add(new LinearConstraint(f, "a >= 0.5"));



            double[] b;
            int      eq;

            double[,] A = constraints.CreateMatrix(4, out b, out eq);

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);

            // And attempt to solve it.
            Assert.IsTrue(solver.Minimize());
            double minValue = solver.Value;

            double[] expected = { 0.5, 0.336259542, 0.163740458, 0 };
            double[] actual   = solver.Solution;

            double v0 = constraints[0].GetViolation(actual);
            double v1 = constraints[1].GetViolation(actual);
            double v2 = constraints[2].GetViolation(actual);
            double v3 = constraints[3].GetViolation(actual);
            double v4 = constraints[4].GetViolation(actual);
            double v5 = constraints[5].GetViolation(actual);
            double v6 = constraints[6].GetViolation(actual);

            for (int i = 0; i < expected.Length; i++)
            {
                double e = expected[i];
                double a = actual[i];
                Assert.AreEqual(e, a);
            }
        }
示例#22
0
        public void GoldfarbIdnaniConstructorTest3()
        {
            // http://www.wolframalpha.com/input/?i=min+2x%C2%B2+-+xy+%2B+4y%C2%B2+-+5x+-+6y+s.t.+x+-+y++%3D%3D+++5%2C+x++%3E%3D++10

            // Solve the following optimization problem:
            //
            //  min f(x) = 2x² - xy + 4y² - 5x - 6y
            //
            //  s.t.   x - y  ==   5  (x minus y should be equal to 5)
            //             x  >=  10  (x should be greater than or equal to 10)
            //

            // In this example we will be using some symbolic processing.
            // The following variables could be initialized to any value.
            double x = 0, y = 0;

            // Create our objective function using a lambda expression
            var f = new QuadraticObjectiveFunction(() => 2 * (x * x) - (x * y) + 4 * (y * y) - 5 * x - 6 * y);

            // Now, create the constraints
            List <LinearConstraint> constraints = new List <LinearConstraint>();

            constraints.Add(new LinearConstraint(f, () => x - y == 5));
            constraints.Add(new LinearConstraint(f, () => x >= 10));

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);


            double[,] A =
            {
                { 1, -1 },
                { 1,  0 },
            };

            double[] b =
            {
                5,
                10,
            };

            Assert.IsTrue(A.IsEqual(solver.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(solver.ConstraintValues));


            double[,] Q =
            {
                { +2 * 2,     -1 },
                {     -1, +4 * 2 },
            };

            double[] d = { -5, -6 };


            var actualQ = f.QuadraticTerms;
            var actuald = f.LinearTerms;

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));


            // And attempt to solve it.
            bool success = solver.Minimize();

            Assert.AreEqual(170, solver.Value);
            Assert.IsTrue(success);
        }
示例#23
0
 /// <summary>
 ///     Constructs a new <see cref="GoldfarbIdnani" /> class.
 /// </summary>
 /// <param name="function">The objective function to be optimized.</param>
 /// <param name="constraints">The problem's constraints.</param>
 public GoldfarbIdnani(QuadraticObjectiveFunction function, IEnumerable <LinearConstraint> constraints)
     : this(function, new LinearConstraintCollection(constraints))
 {
 }