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); }
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); } } } }
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); }
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)); }
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)); } } }
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); }
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); } }); }
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); } }
/// <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(); }
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"; }
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); }
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); }
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)); } }
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)); } }
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."; } }
[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); } }
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); }
/// <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)) { }