Exemplo n.º 1
0
def test_ecos_trivial_invpos():

    x = cvx.Variable( (2), name='x')

    constraints  = [x[0] >= 0]

    constraints += [x[1] >= x[0]]
    constraints += [x[1] >= cvx.inv_pos(x[0])]

    objective = x[1]
    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose=True)
    canon.assign_values({})

    solution = cvx.solve(canon, verbose = True)

    if solution:

        print('Solution obj:', solution['info']['pcost'])
        print('Solution   x:', solution['x'][0:2])

        assert( np.allclose(solution['x'][0:2], [1.0, 1.0]) )

    reset_symbols()
Exemplo n.º 2
0
def test_ecos_leastsquares():

    x = cvx.Variable (name='x')
    F = cvx.Parameter(name='F')
    g = cvx.Parameter(name='g')

    objective = cvx.square(cvx.norm( F*x - g ))

    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, [])

    canon = Canonicalize(problem, verbose=True)

    # Set values of parameters
    parameters = {
        'F' : 42,
        'g' : 42,
    }

    canon.assign_values(parameters)

    solution = cvx.solve(canon, verbose = True)

    if solution:
        print('Solution obj:', solution['info']['pcost'])
        print('Solution   x:', solution['x'][0])

        assert( np.isclose(solution['x'][0], 1.0) )

    reset_symbols()
Exemplo n.º 3
0
def test_ecos_trivial_geomean():

    x = cvx.Variable( (2), name='x')

    constraints  = [x[0] >= 0]

    constraints += [x[1] <= cvx.geo_mean(x[0], 5)]
    constraints += [x[1] >= 5]

    objective = x[0] + x[1]  # farthest down and left
    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose=True)
    canon.assign_values({})

    solution = cvx.solve(canon, verbose = True)

    if solution:

        print('Solution obj:', solution['info']['pcost'])
        print('Solution   x:', solution['x'][0:2])

        assert( np.allclose(solution['x'][0:2], [5.0, 5.0]) )

    reset_symbols()
Exemplo n.º 4
0
def test_ecos_polyhedradist():
    import cvx_sym as cvx

    n = 2  # number of dimensions
    m = 3  # number of lines defining polyhedron 1
    p = 3  # number of lines defining polyhedron 2

    x1 = cvx.Variable ((n,1),name='x1')
    x2 = cvx.Variable ((n,1),name='x2')

    A1 = cvx.Parameter((m,n),name='A1')
    A2 = cvx.Parameter((p,n),name='A2')
    B1 = cvx.Parameter((m,1),name='B1')
    B2 = cvx.Parameter((p,1),name='B2')

    objective = cvx.square(cvx.norm(x1 - x2))

    constraints  = [ A1[i,:].T * x1 <= B1[i] for i in range(m) ]
    constraints += [ A2[i,:].T * x2 <= B2[i] for i in range(p) ]

    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose=True)

    # Set values of parameters
    parameters = {
        'A1' : np.array([[-1,1],[1,1],[0,-1]]),
        'B1' : np.array([[3],[3],[0]]),

        'A2' : np.array([[.5,-1],[0,1],[+1,0]]),
        'B2' : np.array([[-3],[3],[5]]),
    }

    canon.assign_values(parameters)

    solution = cvx.solve(canon, verbose = True)

    if solution:
        print('Solution obj:', solution['info']['pcost'])

        # Gather the OG solution variables

        v_indices = [n for n, vn in enumerate(canon.vars.keys()) if 'x' in vn]
        x_solution = [solution['x'][i] for i in v_indices]

        print('Solution   x:', x_solution)
        print('Solution vec:', solution['x'])

        # Solution is found at intersection of polyhedra
        assert( np.allclose(x_solution, [0,3, 0,3],  atol=1e-4) )

        # So therefore the objective should be near zero
        assert( np.allclose(solution['info']['pcost'], 0.0 ) )

    reset_symbols()
Exemplo n.º 5
0
def test_ecos_robustlp():

    import cvx_sym as cvx

    n = 2  # number of dimensions
    m = 3  # number of elementwise elements

    x = cvx.Variable ((n,1),name='x')

    A = cvx.Parameter((m,n),name='A')
    B = cvx.Parameter((m,1),name='B')
    C = cvx.Parameter((n,1),name='C')
    P = cvx.Parameter((m,n),name='P')

    objective = C.T * x

    constraints = [A[i].T * x + cvx.norm(P[i].T * x) <= B[i] for i in range(m)]

    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose=True)

    # Set values of parameters
    parameters = {
        'A' : np.array([[1,1],[1,1],[1,1]]),
        'B' : np.array([[3],[3],[3]]),

        'C' : np.array([[.1],[.2]]),
        'P' : np.array([[1,2],[3,4],[5,6]])
    }

    canon.assign_values(parameters)

    solution = cvx.solve(canon, verbose = True)

    if solution:
        print('Solution obj:', solution['info']['pcost'])

        # Gather the OG solution variables

        v_indices = [n for n, vn in enumerate(canon.vars.keys()) if 'x' in vn]
        x_solution = [solution['x'][i] for i in v_indices]

        print('Solution   x:', x_solution)
        print('Solution vec:', solution['x'])

        assert( np.allclose(x_solution, [3,-3] ) )

    reset_symbols()
Exemplo n.º 6
0
def test_smith_sq():
    """ Smith Form of Minimize(square(v0)) """

    v0 = Variable(name='v0')
    v1 = Variable(name='v1')

    p0 = Parameter(name='p0')
    p1 = Parameter(name='p1')

    obj = square(v0)
    con = []

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True, only='smith')

    assert (len(c.constraints) == 1)
    assert (c.objective is not obj)
    assert ('sym0' == c.objective.name)

    assert (hasattr(c.constraints[0].expr.args[0], 'name'))
    assert (c.constraints[0].expr.args[0].name == 'sym0')

    assert (hasattr(c.constraints[0].expr.args[1], 'args'))
    assert (hasattr(c.constraints[0].expr.args[1].args[0], 'value'))
    assert (c.constraints[0].expr.args[1].args[0].value == -1.0)

    assert (hasattr(c.constraints[0].expr.args[1].args[1], 'name'))
    assert (c.constraints[0].expr.args[1].args[1].name == 'square')

    reset_symbols()
Exemplo n.º 7
0
def test_matrix_sq():
    """ Matrix Form of Minimize(square(v0)) """

    v0 = Variable(name = 'v0')
    v1 = Variable(name = 'v1')

    p0 = Parameter(name = 'p0')
    p1 = Parameter(name = 'p1')

    obj = square(v0)
    con = []

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True)

    assert(c.c == [0, 0, 1])
    assert(c.A is None)
    assert(c.b is None)

    assert_G =  {
                    'row':[0, 1, 2],
                    'col':[2, 2, 0],
                    'val':[Constant(-1.0), Constant(-1.0), Constant(2.0)]
                }


    assert_h = [Constant(1.0), Constant(-1.0), Constant(0.0)]
    assert_G = COO_to_CS(assert_G, (len(assert_h), len(c.c)), 'col')

    assert(c.G == assert_G)
    assert(all([c.h[n].value == t.value for n, t in enumerate(assert_h)]))

    assert(c.dims == {'q': [3], 'l': 0})

    reset_symbols()
Exemplo n.º 8
0
def test_relax_sq2norm_constr():
    """ Relaxed Form of Minimize(square(norm(v0))) with v0 >= p0"""

    v0 = Variable(name = 'v0')
    v1 = Variable(name = 'v1')

    p0 = Parameter(name = 'p0')
    p1 = Parameter(name = 'p1')

    obj = square(norm(v0))
    con = [v0 >= p0]  # should become -v0 + p0 <= 0

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True, only='relax')

    assert( type(c.constraints[-1]) is le)
    assert( type(c.constraints[-1].expr) is sums.sum)
    assert( type(c.constraints[-1].expr.args[0]) is muls.smul)
    assert( type(c.constraints[-1].expr.args[1]) is muls.smul)
    assert( c.objective is not obj   )
    assert( 'sym0' == c.objective.name )

    string_equals = [
        """((-1.0 * sym1) + (1.0 * norm2(v0))) <= 0""",
        """((-1.0 * sym0) + (1.0 * square(sym1))) <= 0""",
        """((-1.0 * v0) + (p0 * 1.0)) <= 0""",
    ]

    for n, string in enumerate(string_equals):
        print(c.constraints[n],'==',string,'?')
        assert(str(c.constraints[n]) == string)
        print('SUCCESS!')

    reset_symbols()
Exemplo n.º 9
0
def test_relax_sq2norm():
    """ Relaxed Form of Minimize(square(norm(v0))) """

    v0 = Variable(name = 'v0')
    v1 = Variable(name = 'v1')

    p0 = Parameter(name = 'p0')
    p1 = Parameter(name = 'p1')

    obj = square(norm(v0))
    con = []

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True, only='relax')

    assert( c.objective is not obj   )
    assert( 'sym0' == c.objective.name )

    # Let up on the testing rigor a bit, now that we checked core fundamentals

    string_equals = [
        """((-1.0 * sym1) + (1.0 * norm2(v0))) <= 0""",
        """((-1.0 * sym0) + (1.0 * square(sym1))) <= 0""",
    ]

    for n, string in enumerate(string_equals):
        print(c.constraints[n],'==',string,'?')
        assert(str(c.constraints[n]) == string)
        print('SUCCESS!')

    reset_symbols()
Exemplo n.º 10
0
def test_relax_sq():
    """ Relaxed Form of Minimize(square(v0)) """

    v0 = Variable(name = 'v0')
    v1 = Variable(name = 'v1')

    p0 = Parameter(name = 'p0')
    p1 = Parameter(name = 'p1')

    obj = square(v0)
    con = []

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True, only='relax')

    assert( len(c.constraints) == 1 )
    assert( c.objective is not obj   )
    assert( 'sym0' == c.objective.name )

    assert(type(c.constraints[0]) is le)

    assert(c.constraints[0].expr.args[0].curvature == 0)
    assert(c.constraints[0].expr.args[1].curvature == +1)
    assert(c.constraints[0].expr.args[1].symbol_groups()[0][0].value == 1.0)
    assert(c.constraints[0].expr.args[1].symbol_groups()[2][0].name == 'square')

    reset_symbols()
Exemplo n.º 11
0
def test_relax_least_squares_constr():
    """ Relaxed Form : Minimize(square(norm(F*x - g))) with x >= p0 """

    x = Variable ((3,1),name='x')
    F = Parameter((3,3),name='F')
    g = Parameter((3,1),name='g')

    objective = square(norm( F*x - g ))

    objective = Minimize(objective)
    problem   = Problem(objective, [x >= 0])

    c = Canonicalize(problem, verbose=True, only='relax')

    string_equals = [
        """(sym2 + (-1.0 * matmul(F, x))) == 0""",
        """(sym3 + (-1.0 * sym2) + (g * 1.0)) == 0""",
        """((-1.0 * sym1) + (1.0 * norm2(sym3))) <= 0""",
        """((-1.0 * sym0) + (1.0 * square(sym1))) <= 0""",
        """((-1.0 * x)) <= 0""",
    ]

    for n, string in enumerate(string_equals):
        print(c.constraints[n],' ???? ',string, end=' ')
        assert(str(c.constraints[n]) == string)
        print('... SUCCESS!')

    reset_symbols()
Exemplo n.º 12
0
def test_norm_inf():

    x = Variable((3, 1), name='x')

    objective = norm(x, kind='inf')  # returns max(abs(x))

    objective = Minimize(objective)
    problem = Problem(objective, [])

    c = Canonicalize(problem, verbose=True, only='smith')

    assert (len(c.constraints) == 4)

    string_equals = [
        """(sym1[0][0] + (-1.0 * abs(x[0][0]))) == 0""",
        """(sym1[1][0] + (-1.0 * abs(x[1][0]))) == 0""",
        """(sym1[2][0] + (-1.0 * abs(x[2][0]))) == 0""",
        """(sym0 + (-1.0 * max(sym1))) == 0""",
    ]

    for n, string in enumerate(string_equals):
        print(c.constraints[n], ' ???? ', string, end=' ')
        assert (str(c.constraints[n]) == string)
        print('... SUCCESS!')

    reset_symbols()
Exemplo n.º 13
0
def test_ecos_chebyshevcenter():

    import cvx_sym as cvx

    n = 2
    m = 3

    r = cvx.Variable((1,1),name='r')
    x = cvx.Variable((n,1),name='x')

    A = cvx.Parameter((m,n),name='A')
    B = cvx.Parameter((m,1),name='B')

    objective = -r

    constraints  = [A[i,:].T * x + r * cvx.norm(A[i,:]) <= B[i] for i in range(m)]
    constraints += [r >= 0]

    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose=True)

    # Set values of parameters
    parameters = {
        'A' : np.array([[-1,1],[1,1],[0,-1]]),
        'B' : np.array([[3],[3],[0]]),
    }

    canon.assign_values(parameters)

    solution = cvx.solve(canon, verbose = True)

    if solution:
        print('Solution obj:', solution['info']['pcost'])

        # Gather the OG solution variables

        v_indices = [n for n, vn in enumerate(canon.vars.keys()) if 'x' in vn]
        x_solution = [solution['x'][i] for i in v_indices]

        print('Solution   x:', x_solution)
        print('Solution vec:', solution['x'])

        assert( np.allclose(x_solution, [0, 1.242641] ) )

    reset_symbols()
Exemplo n.º 14
0
def test_ecos_leastsquares_constr():

    x = cvx.Variable ((3,1),name='x')
    F = cvx.Parameter((3,3),name='F')
    g = cvx.Parameter((3,1),name='g')

    U = cvx.Parameter((3,1),name='U')
    L = cvx.Parameter((3,1),name='L')

    constraints  = []
    objective = cvx.square(cvx.norm( F*x - g ))

    constraints += [ x <= U ]
    constraints += [ L <= x ]

    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose=True)

    # Set values of parameters
    parameters = {
        'F' : np.array([[1,2,3],[4,5,6],[7,8,9]]),
        'g' : np.array([[1],[2],[3]]),

        'U' : np.array([[42],[42],[42]]),
        'L' : np.array([[1],[2],[3]])
    }

    canon.assign_values(parameters)

    solution = cvx.solve(canon, verbose = True)

    if solution:
        print('Solution obj:', solution['info']['pcost'])

        # Gather the OG solution variables

        v_indices = [n for n, vn in enumerate(canon.vars.keys()) if 'x' in vn]
        x_solution = [solution['x'][i] for i in v_indices]

        print('Solution   x:', x_solution)
        print('Solution vec:', solution['x'])

        assert( np.allclose(x_solution, [1,2,3] ) )

    reset_symbols()
Exemplo n.º 15
0
def test_matrix_sq2norm_sqcon():
    """ Relaxed Form : Minimize(square(norm(v0))) with v0 >= square(v1) """

    v0 = Variable(name = 'v0')
    v1 = Variable(name = 'v1')

    p0 = Parameter(name = 'p0')
    p1 = Parameter(name = 'p1')

    obj = square(norm(v0 + v1))
    con = [v0 >= square(v1)]  # should become -v0 + square(v1) <= 0

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True)

    sym3 = [v for vn, v in c.vars.items() if vn == 'sym3'][0]

    assert_A = {'row': [0, 0, 0],
         'col': [0, 1, 4],
         'val': [Constant(-1.0), Constant(-1.0), Constant(1.0)]}

    assert_b = [Constant(0.0)]
    #assert_G = {'row': [0, 0, 1, 2, 3, 4, 5, 6, 7, 8],
    #     'col': [0, 5, 3, 4, 2, 2, 3, 5, 5, 1],
    #     'val': [Constant(-1.0), Constant(0.0), Constant(-1.0), Constant(1.0),
    #             Constant(-1.0), Constant(-1.0), Constant(2.0), Constant(-1.0),
    #             Constant(-1.0), Constant(2.0)]}

    assert_G = {'row': [0, 0, 1, 2, 3, 4, 5, 6, 7, 8],
         'col': [0, 5, 3, 4, 2, 2, 3, 5, 5, 1],
         'val': [Constant(-1.0), Constant(1.0), Constant(-1.0), Constant(1.0),
                 Constant(-1.0), Constant(-1.0), Constant(2.0), Constant(-1.0),
                 Constant(-1.0), Constant(2.0)]}

    assert_h = [ (-1.0 * sym3), Constant(0.0), Constant(0.0), Constant(1.0),
                Constant(-1.0), Constant(0.0), Constant(1.0),
                Constant(-1.0), Constant(0.0)]

    assert_h = [Constant(0.0), Constant(0.0), Constant(0.0), Constant(1.0),
                Constant(-1.0), Constant(0.0), Constant(1.0), Constant(-1.0),
                Constant(0.0)]

    assert_dims = {'q': [2, 3, 3], 'l': 1}

    assert_A = COO_to_CS(assert_A, (len(assert_b), len(c.c)), 'col')
    assert_G = COO_to_CS(assert_G, (len(assert_h), len(c.c)), 'col')

    assert_c = [0.0, 0.0, 1.0, 0.0, 0.0, 0.0]

    assert(c.c == assert_c)
    assert(c.A == assert_A)
    assert(c.b == assert_b)

    assert(c.G == assert_G)
    assert(all([c.h[n].value == t.value for n, t in enumerate(assert_h)]))

    assert(c.dims == assert_dims)

    reset_symbols()
Exemplo n.º 16
0
def test_ecos_trivial_norm1():

    x = cvx.Variable((3,1),name='x')

    constraints   = [x >= -1]
    constraints  += [x <= +1]

    objective = cvx.norm(x, kind=1)
    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose=True)
    canon.assign_values({})

    solution = cvx.solve(canon, verbose = True)

    if solution:
        print('Solution obj:', solution['info']['pcost'])
        print('Solution   x:', solution['x'])

        assert( np.allclose(solution['x'][0:3], [0.0, 0.0, 0.0]) )

    reset_symbols()
Exemplo n.º 17
0
def test_matrix_least_squares_constr():
    """ Minimize(square(norm(F*x - g))) with x >= p0 """

    x = Variable ((3,1),name='x')
    F = Parameter((3,3),name='F')
    g = Parameter((3,1),name='g')

    objective = square(norm( F*x - g ))

    objective = Minimize(objective)
    problem   = Problem(objective, [x >= 1])

    c = Canonicalize(problem, verbose=True)

    # Test for errors, not asserts, and for solution outcome (via ecos_solution)

    reset_symbols()
Exemplo n.º 18
0
    def __init__(self, problem, name = 'embedded', folder = None,
                                lang = 'c', verbose = False,
                                temp = 'main_set'):
        lang = lang.lower()

        self.problem = problem
        self.name = name

        if not folder:
            self.location = pathlib.Path(self.name)
        else:
            self.location = pathlib.Path(folder) / self.name

        self.set = temp  # which set of templates to use?

        self.canonical = Canonicalize(self.problem, verbose = verbose)

        if lang not in ['c']:  # Catch unimplemented languages
            raise(NotImplemented('Only C99 Code Generation Supported'))

        self.write(lang)
Exemplo n.º 19
0
def test_matrix_sq2norm_constr():
    """ Matrix Form of Minimize(square(norm(v0))) with v0 >= p0"""

    v0 = Variable(name = 'v0')
    v1 = Variable(name = 'v1')

    p0 = Parameter(name = 'p0')
    p1 = Parameter(name = 'p1')

    obj = square(norm(v0))
    con = [v0 >= p0]  # should become -v0 + p0 <= 0

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True)


    assert_c = [0.0, 0.0, 1.0, 0.0]

    assert_A = COO_to_CS({'row':[],'col':[],'val':[]}, (0,4), 'col')

    assert_G =  {'row': [0, 1, 2, 3, 4, 5], 'col': [0, 3, 0, 2, 2, 3],
                'val': [Constant(-1.0), Constant(-1.0), Constant(1.0),
                        Constant(-1.0), Constant(-1.0), Constant(2.0)]}

    assert_h = [(-1.0 * p0), Constant(0.0), Constant(0.0),
                Constant(1.0), Constant(-1.0), Constant(0.0)]

    assert_G = COO_to_CS(assert_G, (len(assert_h), len(c.c)), 'col')

    assert(c.c == assert_c)
    assert(c.A is None)
    assert(c.b is None)

    assert(c.G == assert_G)
    assert(all([c.h[n].value == t.value for n, t in enumerate(assert_h)]))

    assert(c.dims == {'q': [2, 3], 'l': 1})

    reset_symbols()
Exemplo n.º 20
0
def test_smith_sq2norm_sqcon():
    """ Smith Form : Minimize(square(norm(v0))) with v0 >= square(v1) """

    v0 = Variable(name='v0')
    v1 = Variable(name='v1')

    p0 = Parameter(name='p0')
    p1 = Parameter(name='p1')

    obj = square(norm(v0 + v1))
    con = [v0 >= square(v1)]  # should become -v0 + square(v1) <= 0

    p = Problem(Minimize(obj), con)
    c = Canonicalize(p, verbose=True, only='smith')

    assert (type(c.constraints[-1]) is le)
    assert (type(c.constraints[-1].expr) is sums.sum)
    assert (type(c.constraints[-1].expr.args[0]) is muls.smul)
    assert (type(c.constraints[-1].expr.args[1]) is muls.smul)
    assert (c.objective is not obj)
    assert ('sym0' == c.objective.name)

    string_equals = [
        """(sym2 + (-1.0 * v0) + (-1.0 * v1)) == 0""",
        """(sym1 + (-1.0 * norm2(sym2))) == 0""",
        """(sym0 + (-1.0 * square(sym1))) == 0""",
        """(sym3 + (-1.0 * square(v1))) == 0""",
        """((-1.0 * v0) + (1.0 * sym3)) <= 0""",
    ]

    for n, string in enumerate(string_equals):
        print(c.constraints[n], ' ???? ', string, end=' ')
        assert (str(c.constraints[n]) == string)
        print('... SUCCESS!')

    reset_symbols()
Exemplo n.º 21
0
def full_scale_ecos_control():

    """ Takes a long time to canonicalize, so don't run as routine test """

    import cvx_sym as cvx

    n = 8
    m = 2
    T = 50

    x = cvx.Variable((n, T+1), name='x')
    u = cvx.Variable((m, T), name='u')

    x_0 = cvx.Parameter((n,1), name='x_0')
    A = cvx.Parameter((n,n), name='A')
    B = cvx.Parameter((n,m), name='B')

    states = []
    constraints  = [ x[:,T] == 0 ]
    constraints += [ x[:,0] == x_0[:,0] ]

    for t in range(T):


        constraints += [ x[:,t+1] == A*x[:,t] + B*u[:,t] ]
        constraints += [ cvx.norm(u[:,t], kind = 'inf') <= 1 ]

        cost = cvx.sum_squares(x[:,t+1]) + cvx.sum_squares(u[:,t])
        states.append( cost )

    # sums problem objectives and concatenates constraints.
    objective = cvx.sum(states)
    objective = cvx.Minimize(objective)
    problem   = cvx.Problem(objective, constraints)

    canon = Canonicalize(problem, verbose = 1 )

    np.random.seed(1)
    alpha = 0.2
    beta = 5

    A_set = np.eye(n) + alpha*np.random.randn(n,n)
    B_set = np.random.randn(n,m)
    x_0_set = beta*np.random.randn(n,1)

    # Set values of parameters
    parameters = {
        'A' : A_set,
        'B' : B_set,
        'x_0' : x_0_set,
    }

    canon.assign_values(parameters)

    solution = cvx.solve(canon, verbose = True)

    if solution:

        obj = solution['info']['pcost']

        # Gather the OG solution variables

        v_indices = [n for n, vn in enumerate(canon.vars.keys()) if 'x' in vn]
        x_solution = [solution['x'][i] for i in v_indices]

        print('Solution obj:', obj)
        print('Solution   x:', x_solution)
        print('Solution vec:', solution['x'])

        assert( np.isclose(obj, 64470.59019495451) )

    reset_symbols()