Example #1
0
        /**
         *  Purpose: Models the hypograph of the n-th power of the
         *  determinant of a positive definite matrix.
         *
         *  The convex set (a hypograph)
         *
         *    C = { (X, t) \in S^n_+ x R |  t <= det(X)^{1/n} },
         *
         *  can be modeled as the intersection of a semidefinite cone
         *
         *    [ X, Z; Z^T Diag(Z) ] >= 0
         *
         *  and a number of rotated quadratic cones and affine hyperplanes,
         *
         *    t <= (Z11*Z22*...*Znn)^{1/n}  (see geometric_mean).
         *
         *  References:
         *  [1] "Lectures on Modern Optimization", Ben-Tal and Nemirovski, 2000.
         */
        public static Variable det_rootn(Model M, Variable t, int n)
        {
            // Setup variables
            Variable Y = M.Variable(Domain.InPSDCone(2 * n));

            Variable X  = Y.Slice(new int[] { 0, 0 }, new int[] { n, n });
            Variable Z  = Y.Slice(new int[] { 0, n }, new int[] { n, 2 * n });
            Variable DZ = Y.Slice(new int[] { n, n }, new int[] { 2 * n, 2 * n });

            // Z is lower-triangular
            int[,] low_tri = new int[n * (n - 1) / 2, 2];
            int k = 0;

            for (int i = 0; i < n; i++)
            {
                for (int j = i + 1; j < n; j++)
                {
                    low_tri[k, 0] = i; low_tri[k, 1] = j; ++k;
                }
            }
            M.Constraint(Z.Pick(low_tri), Domain.EqualsTo(0.0));
            // DZ = Diag(Z)
            M.Constraint(Expr.Sub(DZ, Expr.MulElm(Z, Matrix.Eye(n))), Domain.EqualsTo(0.0));

            // t^n <= (Z11*Z22*...*Znn)
            geometric_mean(M, DZ.Diag(), t);

            // Return an n x n PSD variable which satisfies t <= det(X)^(1/n)
            return(X);
        }
Example #2
0
        /**
         *  Purpose: Models the hypograph of the n-th power of the
         *  determinant of a positive definite matrix.
         *
         *  The convex set (a hypograph)
         *
         *    C = { (X, t) \in S^n_+ x R |  t <= det(X)^{1/n} },
         *
         *  can be modeled as the intersection of a semidefinite cone
         *
         *    [ X, Z; Z^T Diag(Z) ] >= 0
         *
         *  and a number of rotated quadratic cones and affine hyperplanes,
         *
         *    t <= (Z11*Z22*...*Znn)^{1/n}  (see geometric_mean).
         *
         *  References:
         *  [1] "Lectures on Modern Optimization", Ben-Tal and Nemirovski, 2000.
         */
        public static void det_rootn(Model M, Variable X, Variable t)
        {
            int n = X.GetShape().Dim(0);

            // Setup variables
            Variable Y = M.Variable(Domain.InPSDCone(2 * n));

            // Setup Y = [X, Z; Z^T diag(Z)]
            Variable Y11 = Y.Slice(new int[] { 0, 0 }, new int[] { n, n });
            Variable Y21 = Y.Slice(new int[] { n, 0 }, new int[] { 2 * n, n });
            Variable Y22 = Y.Slice(new int[] { n, n }, new int[] { 2 * n, 2 * n });

            M.Constraint(Expr.Sub(Expr.MulElm(Matrix.Eye(n), Y21), Y22), Domain.EqualsTo(0.0));
            M.Constraint(Expr.Sub(X, Y11), Domain.EqualsTo(0.0));

            // t^n <= (Z11*Z22*...*Znn)
            Variable[] tmpv = new Variable[n];
            for (int i = 0; i < n; ++i)
            {
                tmpv[i] = Y22.Index(i, i);
            }
            Variable z = Var.Reshape(Var.Vstack(tmpv), n);

            geometric_mean(M, z, t);
        }
Example #3
0
        public static void Main(string[] args)
        {
            int    ncols  = 50;
            int    nrows  = 50;
            int    seed   = 0;
            double sigma  = 1.0;
            int    ncells = nrows * ncols;
            Random gen    = new Random(seed);

            double[] f = new double[ncells];

            //Random signal with Gaussian noise
            for (int i = 0; i < ncells; i++)
            {
                double xx = Math.Sqrt(-2.0 * Math.Log(gen.NextDouble()));
                double yy = Math.Sin(2.0 * Math.PI * gen.NextDouble());
                f[i] = Math.Max(Math.Min(1.0, xx * yy), .0);
            }


            Model M = new Model("TV");

            try
            {
                Variable u = M.Variable(new int[] { nrows + 1, ncols + 1 },
                                        Domain.InRange(0.0, 1.0));
                Variable t = M.Variable(new int[] { nrows, ncols }, Domain.Unbounded());

                Variable ucore = u.Slice(new int[] { 0, 0 }, new int[] { nrows, ncols });

                Expression deltax = Expr.Sub(u.Slice(new int[] { 1, 0 },
                                                     new int[] { nrows + 1, ncols }),
                                             ucore);
                Expression deltay = Expr.Sub(u.Slice(new int[] { 0, 1 },
                                                     new int[] { nrows, ncols + 1 }),
                                             ucore);

                M.Constraint(Expr.Stack(2, t, deltax, deltay), Domain.InQCone().Axis(2));

                Matrix mat_f = Matrix.Dense(nrows, ncols, f);
                M.Constraint(Expr.Vstack(sigma, Expr.Flatten(Expr.Sub(ucore, mat_f))),
                             Domain.InQCone());

                M.SetLogHandler(Console.Out);

                M.Objective(ObjectiveSense.Minimize, Expr.Sum(t));

                M.Solve();
            }
            finally
            {
                M.Dispose();
            }
        }
Example #4
0
        public static void Main(string[] args)
        {
            using (Model M = new Model("pow1"))
            {
                Variable x  = M.Variable("x", 3, Domain.Unbounded());
                Variable x3 = M.Variable();
                Variable x4 = M.Variable();

                // Create the linear constraint
                double[] aval = new double[] { 1.0, 1.0, 0.5 };
                M.Constraint(Expr.Dot(x, aval), Domain.EqualsTo(2.0));

                // Create the exponential conic constraint
                // Create the conic constraints
                M.Constraint(Var.Vstack(x.Slice(0, 2), x3), Domain.InPPowerCone(0.2));
                M.Constraint(Expr.Vstack(x.Index(2), 1.0, x4), Domain.InPPowerCone(0.4));

                // Set the objective function
                double[] cval = new double[] { 1.0, 1.0, -1.0 };
                M.Objective(ObjectiveSense.Maximize, Expr.Dot(cval, Var.Vstack(x3, x4, x.Index(0))));

                // Solve the problem
                M.Solve();

                // Get the linear solution values
                double[] solx = x.Level();
                Console.WriteLine("x,y,z = {0}, {1}, {2}", solx[0], solx[1], solx[2]);
            }
        }
Example #5
0
                public static void Main(string[] args)
                {
                    using (Model M = new Model("sdo1"))
                    {
                        // Setting up the variables
                        Variable X = M.Variable("X", Domain.InPSDCone(3));
                        Variable x = M.Variable("x", Domain.InQCone(3));

                        DenseMatrix C  = new DenseMatrix(new double[][] { new double[] { 2, 1, 0 }, new double[] { 1, 2, 1 }, new double[] { 0, 1, 2 } });
                        DenseMatrix A1 = new DenseMatrix(new double[][] { new double[] { 1, 0, 0 }, new double[] { 0, 1, 0 }, new double[] { 0, 0, 1 } });
                        DenseMatrix A2 = new DenseMatrix(new double[][] { new double[] { 1, 1, 1 }, new double[] { 1, 1, 1 }, new double[] { 1, 1, 1 } });

                        // Objective
                        M.Objective(ObjectiveSense.Minimize, Expr.Add(Expr.Dot(C, X), x.Index(0)));

                        // Constraints
                        M.Constraint("c1", Expr.Add(Expr.Dot(A1, X), x.Index(0)), Domain.EqualsTo(1.0));
                        M.Constraint("c2", Expr.Add(Expr.Dot(A2, X), Expr.Sum(x.Slice(1, 3))), Domain.EqualsTo(0.5));

                        M.Solve();

                        Console.WriteLine("[{0}]", (new Utils.StringBuffer()).A(X.Level()).ToString());
                        Console.WriteLine("[{0}]", (new Utils.StringBuffer()).A(x.Level()).ToString());
                    }
                }
Example #6
0
                public static void Main(string[] args)
                {
                    using (Model M = new Model("cqo1"))
                    {
                        Variable x = M.Variable("x", 3, Domain.GreaterThan(0.0));
                        Variable y = M.Variable("y", 3, Domain.Unbounded());

                        // Create the aliases
                        //      z1 = [ y[0],x[0],x[1] ]
                        //  and z2 = [ y[1],y[2],x[2] ]
                        Variable z1 = Variable.Vstack(y.Index(0), x.Slice(0, 2));
                        Variable z2 = Variable.Vstack(y.Slice(1, 3), x.Index(2));

                        // Create the constraint
                        //      x[0] + x[1] + 2.0 x[2] = 1.0
                        double[] aval = new double[] { 1.0, 1.0, 2.0 };
                        M.Constraint("lc", Expr.Dot(aval, x), Domain.EqualsTo(1.0));

                        // Create the constraints
                        //      z1 belongs to C_3
                        //      z2 belongs to K_3
                        // where C_3 and K_3 are respectively the quadratic and
                        // rotated quadratic cone of size 3, i.e.
                        //                 z1[0] > sqrt(z1[1]^2 + z1[2]^2)
                        //  and  2.0 z2[0] z2[1] > z2[2]^2
                        Constraint qc1 = M.Constraint("qc1", z1.AsExpr(), Domain.InQCone());
                        Constraint qc2 = M.Constraint("qc2", z2.AsExpr(), Domain.InRotatedQCone());

                        // Set the objective function to (y[0] + y[1] + y[2])
                        M.Objective("obj", ObjectiveSense.Minimize, Expr.Sum(y));

                        // Solve the problem
                        M.Solve();

                        // Get the linearsolution values
                        double[] solx = x.Level();
                        double[] soly = y.Level();

                        Console.WriteLine("x1,x2,x3 = {0}, {1}, {2}", solx[0], solx[1], solx[2]);
                        Console.WriteLine("y1,y2,y3 = {0}, {1}, {2}", soly[0], soly[1], soly[2]);
                        // Get conic solution of qc1
                        double[] qc1lvl = qc1.Level();
                        double[] qc1sn  = qc1.Dual();

                        Console.Write("qc1 levels = {0}", qc1lvl[0]);
                        for (int i = 1; i < qc1lvl.Length; ++i)
                        {
                            Console.Write(", {0}", qc1lvl[i]);
                        }
                        Console.WriteLine();

                        Console.Write("qc1 dual conic var levels = {0}", qc1sn[0]);
                        for (int i = 1; i < qc1sn.Length; ++i)
                        {
                            Console.Write(", {0}", qc1sn[i]);
                        }
                        Console.WriteLine();
                    }
                }
Example #7
0
        public static double[] fitpoly(double[,] data, int n)
        {
            using (var M = new Model("smooth poly"))
            {
                int      m     = data.GetLength(0);
                double[] Adata = new double[m * (n + 1)];
                for (int j = 0, k = 0; j < m; ++j)
                {
                    for (int i = 0; i < n + 1; ++i, ++k)
                    {
                        Adata[k] = Math.Pow(data[j, 0], i);
                    }
                }

                Matrix   A = Matrix.Dense(m, n + 1, Adata);
                double[] b = new double[m];
                for (int j = 0; j < m; ++j)
                {
                    b[j] = data[j, 1];
                }

                Variable x  = M.Variable("x", n + 1, Domain.Unbounded());
                Variable z  = M.Variable("z", 1, Domain.Unbounded());
                Variable dx = diff(M, x);

                M.Constraint(Expr.Mul(A, x), Domain.EqualsTo(b));

                // z - f'(t) >= 0, for all t \in [a, b]
                Variable ub = M.Variable(n, Domain.Unbounded());
                M.Constraint(Expr.Sub(ub,
                                      Expr.Vstack(Expr.Sub(z, dx.Index(0)), Expr.Neg(dx.Slice(1, n)))),
                             Domain.EqualsTo(0.0));
                nn_finite(M, ub, data[0, 0], data[m - 1, 0]);

                // f'(t) + z >= 0, for all t \in [a, b]
                Variable lb = M.Variable(n, Domain.Unbounded());
                M.Constraint(Expr.Sub(lb,
                                      Expr.Vstack(Expr.Add(z, dx.Index(0)), dx.Slice(1, n).AsExpr())),
                             Domain.EqualsTo(0.0));
                nn_finite(M, lb, data[0, 0], data[m - 1, 0]);

                M.Objective(ObjectiveSense.Minimize, z);
                M.Solve();
                return(x.Level());
            }
        }
Example #8
0
                // returns variables u representing the derivative of
                //  x(0) + x(1)*t + ... + x(n)*t^n,
                // with u(0) = x(1), u(1) = 2*x(2), ..., u(n-1) = n*x(n).
                public static Variable diff(Model M, Variable x)
                {
                    int      n   = (int)x.Size() - 1;
                    Variable u   = M.Variable(n, Domain.Unbounded());
                    Variable tmp = Variable.Reshape(x.Slice(1, n + 1), new NDSet(1, n));

                    M.Constraint(Expr.Sub(u, Expr.MulElm(new DenseMatrix(1, n, Range(1.0, n + 1)), tmp)), Domain.EqualsTo(0.0));
                    return(u);
                }
Example #9
0
        public static Model miqcqp_sdo_relaxation(int n, Matrix P, double[] q)
        {
            Model M = new Model();

            Variable Z = M.Variable("Z", Domain.InPSDCone(n + 1));

            Variable X = Z.Slice(new int[] { 0, 0 }, new int[] { n, n });
            Variable x = Z.Slice(new int[] { 0, n }, new int[] { n, n + 1 });

            M.Constraint(Expr.Sub(X.Diag(), x), Domain.GreaterThan(0.0));
            M.Constraint(Z.Index(n, n), Domain.EqualsTo(1.0));

            M.Objective(ObjectiveSense.Minimize, Expr.Add(
                            Expr.Sum(Expr.MulElm(P, X)),
                            Expr.Mul(2.0, Expr.Dot(x, q))
                            ));

            return(M);
        }
Example #10
0
                static void solve(int n, double[] P, double[] q)
                {
                    using (Model M = new Model())
                    {
                        Variable Z = M.Variable(n + 1, Domain.InPSDCone());

                        Variable X = Z.Slice(new int[] { 0, 0 }, new int[] { n, n });
                        Variable x = Z.Slice(new int[] { 0, n }, new int[] { n, n + 1 });
                        M.Constraint(Expr.Sub(X.Diag(), x), Domain.GreaterThan(0.0));

                        M.Constraint(Z.Index(n, n), Domain.EqualsTo(1.0));
                        Expression two_xq = Expr.Mul(2.0, Expr.Dot(x, q));
                        Expression trPX   = Expr.Sum(Expr.MulElm(Matrix.Dense(n, n, P), X));
                        M.Objective(ObjectiveSense.Minimize, Expr.Add(trPX, two_xq));
                        Console.Write("solution status= %s\n", M.GetPrimalSolutionStatus());

                        M.Solve();
                    }
                }
Example #11
0
        // Set up a small artificial conic problem to test with
        public static void SetupExample(Model M)
        {
            Variable x  = M.Variable("x", 3, Domain.GreaterThan(0.0));
            Variable y  = M.Variable("y", 3, Domain.Unbounded());
            Variable z1 = Var.Vstack(y.Index(0), x.Slice(0, 2));
            Variable z2 = Var.Vstack(y.Slice(1, 3), x.Index(2));

            M.Constraint("lc", Expr.Dot(new double[] { 1.0, 1.0, 2.0 }, x), Domain.EqualsTo(1.0));
            M.Constraint("qc1", z1, Domain.InQCone());
            M.Constraint("qc2", z2, Domain.InRotatedQCone());
            M.Objective("obj", ObjectiveSense.Minimize, Expr.Sum(y));
        }
Example #12
0
        public static void Main(string[] args)
        {
            double[] c = { 7.0, 10.0, 1.0, 5.0 };
            int      n = 4;

            using (Model M = new Model("mioinitsol"))
            {
                Variable x = M.Variable("x", n, Domain.GreaterThan(0.0));
                x.Slice(0, 3).MakeInteger();

                // Create the constraint
                M.Constraint(Expr.Sum(x), Domain.LessThan(2.5));

                // Set the objective function to (c^T * x)
                M.Objective("obj", ObjectiveSense.Maximize, Expr.Dot(c, x));

                // Assign values to integer variables.
                // We only set a slice of x
                double[] init_sol = { 1, 1, 0 };
                x.Slice(0, 3).SetLevel(init_sol);

                // Solve the problem
                M.Solve();

                // Get the solution values
                double[] sol = x.Level();
                Console.Write("x = [");
                for (int i = 0; i < n; i++)
                {
                    Console.Write("{0}, ", sol[i]);
                }
                Console.WriteLine("]");

                // Was the initial solution used?
                int    constr    = M.GetSolverIntInfo("mioConstructSolution");
                double constrVal = M.GetSolverDoubleInfo("mioConstructSolutionObj");
                Console.WriteLine("Initial solution utilization: " + constr);
                Console.WriteLine("Initial solution objective: " + constrVal);
            }
        }
Example #13
0
        /**
         *  Purpose: Models the convex set
         *
         *    S = { (x, t) \in R^n x R | x >= 0, t <= (x1 * x2 * ... *xn)^(1/n) }.
         *
         *  using three-dimensional power cones
         */
        public static void geometric_mean(Model M, Variable x, Variable t)
        {
            int n = (int)x.GetSize();

            if (n == 1)
            {
                M.Constraint(Expr.Sub(t, x), Domain.LessThan(0.0));
            }
            else
            {
                Variable t2 = M.Variable();
                M.Constraint(Var.Hstack(t2, x.Index(n - 1), t), Domain.InPPowerCone(1 - 1.0 / n));
                geometric_mean(M, x.Slice(0, n - 1), t2);
            }
        }
Example #14
0
        // Geometric mean
        // |t| <= (x_1...x_n)^(1/n), x_i>=0, x is a vector Variable of length >= 1
        public static void geo_mean(Model M, Variable t, Variable x)
        {
            int n = (int)x.GetSize();

            if (n == 1)
            {
                abs(M, x, t);
            }
            else
            {
                Variable t2 = M.Variable();
                M.Constraint(Expr.Hstack(t2, x.Index(n - 1), t), Domain.InPPowerCone(1.0 - 1.0 / n));
                geo_mean(M, t2, x.Slice(0, n - 1));
            }
        }
Example #15
0
        public static void Main(string[] args)
        {
            using (Model M = new Model("ceo1"))
            {
                Variable x = M.Variable("x", 3, Domain.Unbounded());

                // Create the constraint
                //      x[0] + x[1] + x[2] = 1.0
                M.Constraint("lc", Expr.Sum(x), Domain.EqualsTo(1.0));

                // Create the exponential conic constraint
                Constraint expc = M.Constraint("expc", x, Domain.InPExpCone());

                // Set the objective function to (x[0] + x[1])
                M.Objective("obj", ObjectiveSense.Minimize, Expr.Sum(x.Slice(0, 2)));

                // Solve the problem
                M.Solve();

                // Get the linear solution values
                double[] solx = x.Level();
                Console.WriteLine("x1,x2,x3 = {0}, {1}, {2}", solx[0], solx[1], solx[2]);

                // Get conic solution of expc
                double[] expclvl = expc.Level();
                double[] expcsn  = expc.Dual();

                Console.Write("expc levels = {0}", expclvl[0]);
                for (int i = 1; i < expclvl.Length; ++i)
                {
                    Console.Write(", {0}", expclvl[i]);
                }
                Console.WriteLine();

                Console.Write("expc dual conic var levels = {0}", expcsn[0]);
                for (int i = 1; i < expcsn.Length; ++i)
                {
                    Console.Write(", {0}", expcsn[i]);
                }
                Console.WriteLine();
            }
        }
Example #16
0
        public static void Main(string[] args)
        {
            int m = 3;
            int n = m * m;

            //fixed cells in human readable (i.e. 1-based) format
            int[,] hr_fixed =
            {
                { 1, 5, 4 },
                { 2, 2, 5 }, { 2, 3, 8 }, { 2, 6, 3 },
                { 3, 2, 1 }, { 3, 4, 2 }, { 3, 5, 8 }, { 3, 7, 9 },
                { 4, 2, 7 }, { 4, 3, 3 }, { 4, 4, 1 }, { 4, 7, 8 }, { 4, 8, 4 },
                { 6, 2, 4 }, { 6, 3, 1 }, { 6, 6, 9 }, { 6, 7, 2 }, { 6, 8, 7 },
                { 7, 3, 4 }, { 7, 5, 6 }, { 7, 6, 5 }, { 7, 8, 8 },
                { 8, 4, 4 }, { 8, 7, 1 }, { 8, 8, 6 },
                { 9, 5, 9 }
            };
            int nf = hr_fixed.Length / 3;

            int[,] fixed_cells = new int[nf, 3];
            for (int i = 0; i < nf; i++)
            {
                for (int d = 0; d < m; d++)
                {
                    fixed_cells[i, d] = hr_fixed[i, d] - 1;
                }
            }

            using (Model M = new Model("SUDOKU")) {
                M.SetLogHandler(Console.Out);
                Variable x = M.Variable(new int[] { n, n, n }, Domain.Binary());

                //each value only once per dimension
                for (int d = 0; d < m; d++)
                {
                    M.Constraint(Expr.Sum(x, d), Domain.EqualsTo(1.0));
                }

                //each number must appears only once in a block
                for (int k = 0; k < n; k++)
                {
                    for (int i = 0; i < m; i++)
                    {
                        for (int j = 0; j < m; j++)
                        {
                            Variable block = x.Slice(new int[] { i *m, j *m, k },
                                                     new int[] { (i + 1) * m, (j + 1) * m, k + 1 });
                            M.Constraint(Expr.Sum(block), Domain.EqualsTo(1.0));
                        }
                    }
                }

                M.Constraint(x.Pick(fixed_cells), Domain.EqualsTo(1.0));

                M.Solve();

                //print the solution, if any...
                if (M.GetPrimalSolutionStatus() == SolutionStatus.Optimal ||
                    M.GetPrimalSolutionStatus() == SolutionStatus.NearOptimal)
                {
                    print_solution(m, x);
                }
                else
                {
                    Console.WriteLine("No solution found!\n");
                }
            }
        }
Example #17
0
 // returns variables u representing the derivative of    
 //  x(0) + x(1)*t + ... + x(n)*t^n,
 // with u(0) = x(1), u(1) = 2*x(2), ..., u(n-1) = n*x(n).
 public static Variable diff(Model M, Variable x)
 {
   int n = (int)x.Size()-1;
   Variable u = M.Variable(n, Domain.Unbounded());
   Variable tmp = Variable.Reshape(x.Slice(1,n+1),new NDSet(1,n));    
   M.Constraint(Expr.Sub(u, Expr.MulElm(new DenseMatrix(1,n,Range(1.0,n+1)), tmp)), Domain.EqualsTo(0.0));
   return u;
 }
Example #18
0
 // A helper method computing a semidefinite slice of a 3-dim variable
 public static Variable Slice(Variable X, int d, int j)
 {
     return
         (X.Slice(new int[] { j, 0, 0 }, new int[] { j + 1, d, d })
          .Reshape(new int[] { d, d }));
 }
Example #19
0
        // returns variables u representing the derivative of
        //  x(0) + x(1)*t + ... + x(n)*t^n,
        // with u(0) = x(1), u(1) = 2*x(2), ..., u(n-1) = n*x(n).
        public static Variable diff(Model M, Variable x)
        {
            int      n = (int)x.GetSize() - 1;
            Variable u = M.Variable(n, Domain.Unbounded());

            M.Constraint(Expr.Sub(u, Expr.MulElm(Matrix.Dense(n, 1, Range(1.0, n + 1)), x.Slice(1, n + 1))), Domain.EqualsTo(0.0));
            return(u);
        }
Example #20
0
                public static void Main(string[] args)
                {
                    int    ncols = 50;
                    int    nrows = 50;
                    int    seed  = 0;
                    double sigma = 1.0;

                    int ncells = nrows * ncols;

                    Random gen = new Random(seed);

                    double[] f = new double[ncells];

                    for (int i = 0; i < ncells; i++)
                    {
                        double xx = Math.Sqrt(-2.0 * Math.Log(gen.NextDouble()));
                        double yy = Math.Sin(2.0 * Math.PI * gen.NextDouble());
                        f[i] = Math.Max(Math.Min(1.0, xx * yy), .0);
                    }

                    //TAG:begin-tv-code

                    //TAG:begin-tv-init
                    Model M = new Model("TV");

                    try
                    {
                        Variable u = M.Variable(new int[] { nrows + 1, ncols + 1 },
                                                Domain.InRange(0.0, 1.0));
                        Variable t = M.Variable(new int[] { nrows, ncols }, Domain.Unbounded());
                        //TAG:end-tv-init

                        //TAG:begin-tv-core-grid
                        Variable ucore = u.Slice(new int[] { 0, 0 }, new int[] { nrows, ncols });
                        //TAG:end-tv-core-grid

                        //TAG:begin-tv-deltas
                        Expression deltax = Expr.Sub(u.Slice(new int[] { 1, 0 },
                                                             new int[] { nrows + 1, ncols }),
                                                     ucore);
                        Expression deltay = Expr.Sub(u.Slice(new int[] { 0, 1 },
                                                             new int[] { nrows, ncols + 1 }),
                                                     ucore);
                        //TAG:end-tv-deltas

                        //TAG:begin-tv-norms
                        M.Constraint(Expr.Stack(2, t, deltax, deltay), Domain.InQCone().Axis(2));
                        //TAG:end-tv-norms

                        //TAG:begin-tv-sigma
                        Matrix mat_f = Matrix.Dense(nrows, ncols, f);
                        M.Constraint(Expr.Vstack(sigma, Expr.Flatten(Expr.Sub(ucore, mat_f))),
                                     Domain.InQCone());
                        //TAG:end-tv-sigma

                        /*
                         * boundary conditions are not actually needed
                         * M.constraint( Expr.sub( u.slice( [n-1,0] ,[n,m] ), u.slice([n,0],[n+1,m]) ),
                         * Domain.equalsTo(0.));
                         * M.constraint( Expr.sub( u.slice( [0,n-1] ,[n,m] ), u.slice([0,n],[n,m+1]) ),
                         * Domain.equalsTo(0.));
                         */

                        M.SetLogHandler(Console.Out);

                        //TAG:begin-tv-obj-fun
                        M.Objective(ObjectiveSense.Minimize, Expr.Sum(t));
                        //TAG:end-tv-obj-fun

                        M.Solve();
                    }
                    finally
                    {
                        M.Dispose();
                    }
                    //TAG:end-tv-code
                }