// Copyright: Copyright (c) MOSEK ApS, Denmark. All rights reserved. // // File: elastic.cs // // Purpose: Demonstrates model parametrization on the example of an elastic net linear regression: // // min_x |Ax-b|_2 + lambda1*|x|_1 + lambda2*|x|_2 using System; using mosek.fusion; namespace mosek.fusion.example { public class elastic { // Construct the model with parameters b, lambda1, lambda2 // and with prescribed matrix A public static Model initializeModel(int m, int n, double[,] A) { Model M = new Model(); Variable x = M.Variable("x", n); // t >= |Ax-b|_2 where b is a parameter Parameter b = M.Parameter("b", m); Variable t = M.Variable(); M.Constraint(Expr.Vstack(t, Expr.Sub(Expr.Mul(A, x), b)), Domain.InQCone()); // p_i >= |x_i|, i=1..n Variable p = M.Variable(n); M.Constraint(Expr.Hstack(p, x), Domain.InQCone()); // q >= |x|_2 Variable q = M.Variable(); M.Constraint(Expr.Vstack(q, x), Domain.InQCone()); // Objective, parametrized with lambda1, lambda2 // t + lambda1*sum(p) + lambda2*q Parameter lambda1 = M.Parameter("lambda1"); Parameter lambda2 = M.Parameter("lambda2"); Expression obj = Expr.Add(new Expression[] {t, Expr.Mul(lambda1, Expr.Sum(p)), Expr.Mul(lambda2, q)}); M.Objective(ObjectiveSense.Minimize, obj); // Return the ready model return M; } public static void smallExample() { //Create a small example int m = 4; int n = 2; double[,] A = { {1.0, 2.0}, {3.0, 4.0}, {-2.0, -1.0}, {-4.0, -3.0} }; double[] sol; Model M = initializeModel(m, n, A); // For convenience retrieve some elements of the model Parameter b = M.GetParameter("b"); Parameter lambda1 = M.GetParameter("lambda1"); Parameter lambda2 = M.GetParameter("lambda2"); Variable x = M.GetVariable("x"); // First solve b.SetValue(new double[]{0.1, 1.2, -1.1, 3.0}); lambda1.SetValue(0.1); lambda2.SetValue(0.01); M.Solve(); sol = x.Level(); Console.WriteLine("Objective {0}, solution {1}, {2}", M.PrimalObjValue(), sol[0], sol[1]); // Increase lambda1 lambda1.SetValue(0.5); M.Solve(); sol = x.Level(); Console.WriteLine("Objective {0}, solution {1}, {2}", M.PrimalObjValue(), sol[0], sol[1]); // Now change the data completely b.SetValue(new double[] {1.0, 1.0, 1.0, 1.0}); lambda1.SetValue(0.0); lambda2.SetValue(0.0); M.Solve(); sol = x.Level(); Console.WriteLine("Objective {0}, solution {1}, {2}", M.PrimalObjValue(), sol[0], sol[1]); // And increase lamda2 lambda2.SetValue(1.4145); M.Solve(); sol = x.Level(); Console.WriteLine("Objective {0}, solution {1}, {2}", M.PrimalObjValue(), sol[0], sol[1]); M.Dispose(); } public static void Main() { smallExample(); } } }