Your problem is solved exactly because you don't have any constraint. I skipped the function to make you a shorter script.

import numpy as np
import cvxpy as cp
pts = np.array([(-2, 3), (-3, 5), (-1, 4), (-3, 7), (0, 3),
                (-2, -2), (-3, 8), (3, 1), (1, -2), (2, 6),
                (-2, 6), (-2, 5), (-4, 3), (-4, 6), (-3, 10),
                (2, -3)])

n = pts.shape[0]
x = cp.Variable((n, 2))
objective = cp.Minimize(cp.sum(cp.norm(pts - x, 2, axis=1)))
prob = cp.Problem(objective)
prob.solve()

print(x.value)
# result
# [[-2.  3.]
#  [-3.  5.]
#  [-1.  4.]
#  [-3.  7.]
#  [ 0.  3.]
#  [-2. -2.]
#  [-3.  8.]
#  [ 3.  1.]
#  [ 1. -2.]
#  [ 2.  6.]
#  [-2.  6.]
#  [-2.  5.]
#  [-4.  3.]
#  [-4.  6.]
#  [-3. 10.]
#  [ 2. -3.]]


P.S. maybe this is not your correct answer. The problem is that from what I see in your equation. I'm not able to differentiate the parameters and your values.

Does it mean that you have two functions to minimize? one approaching the points and the other one approaching all the previous points to the current one?

If that's the case, you can replace the code with:

cost1 = cp.sum(cp.norm(pts - x, 2, axis=1))
cost2 = cp.sum([cp.norm(x[j] - x[i],2) for i in range(1, n) for j in range(0, i)])
objective = cp.Minimize(cost1+cost2)
prob = cp.Problem(objective)
prob.solve()
print(x.value)
#result
# [[-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]]


But as you can see, the result is not that interesting.

Answer from silgon on Stack Overflow
🌐
Cvxpy
cvxpy.org › tutorial › functions › index.html
Atomic Functions -
The functions max and min give ... and minimum to find the max or min of a list of scalar expressions. The CVXPY function sum sums all the entries in a single expression....
🌐
Cvxpy
cvxpy.org › _modules › cvxpy › atoms › norm.html
cvxpy.atoms.norm -
""" x = Expression.cast_to_const(x) # matrix norms take precedence num_nontrivial_idxs = sum([d > 1 for d in x.shape]) if axis is None and x.ndim == 2: if p == 1: # matrix 1-norm return cvxpy.atoms.max(norm1(x, axis=0)) # Frobenius norm elif p == 'fro' or (p == 2 and num_nontrivial_idxs == 1): return pnorm(vec(x, order='F'), 2) elif p == 2: # matrix 2-norm is largest singular value return sigma_max(x) elif p == 'nuc': # the nuclear norm (sum of singular values) return normNuc(x) elif p in [np.inf, "inf", "Inf"]: # the matrix infinity-norm return cvxpy.atoms.max(norm1(x, axis=1)) else: raise RuntimeError('Unsupported matrix norm.') else: if p == 1 or x.is_scalar(): return norm1(x, axis=axis, keepdims=keepdims) elif str(p).lower() == "inf": return norm_inf(x, axis=axis, keepdims=keepdims) elif str(p).lower() == "fro": # TODO should not work for vectors.
Discussions

python - norm of differences of variables in cvxpy - Stack Overflow
How can I take the following norm in cvxpy sum(norm(x[i] - x[j], p=2), i=1, j>i, i, j = n) where x is (n, 2) variable matrix defined by x = cp.Variable((n, 2)). For the problem, I am taking n=... More on stackoverflow.com
🌐 stackoverflow.com
Infinity norm for matrices different than convention
According to the documentation, the function norm(X, 'inf') when X is a matrix computes \sum_{i,j}|X_{i,j}|, which is different than the convention, \max_i \sum_j |a_{i,j}|. This could lead to some confusion · source: http://mathworld.wolfram.com/MatrixNorm.html More on github.com
🌐 github.com
4
February 23, 2018
python - Why is CVXPY throwing a DCP error with cp.sqrt but no error with cp.norm - Computational Science Stack Exchange
Based on your experience, one of (ignoring the subscripts) h or p must be a variable. Therefore h'*p is affine. After introducing subscripts, you can form the norm of the vector of these individual affine terms in compliance with CVXPY's DCP rules, because the argument of norm is affine (vector). More on scicomp.stackexchange.com
🌐 scicomp.stackexchange.com
January 21, 2021
CVXPY: Why Norm constraint is not DCP?
Hello OP, were you able to solve this? I have a similar problem for my Financial Engineering homework and my problem also prompts out the "DCPError: Problem does not follow DCP rules. " More on reddit.com
🌐 r/optimization
7
3
October 12, 2023
🌐
Cvxpy
cvxpy.org › _modules › cvxpy › atoms › pnorm.html
cvxpy.atoms.pnorm -
[docs] def pnorm(x, p: Union[int, str] = 2, axis=None, keepdims: bool = False, max_denom: int = 1024, approx: bool = True): """Factory function for a mathematical p-norm. Parameters ---------- p : numeric type or string The type of norm to construct; set this to np.inf or 'inf' to construct an infinity norm.
🌐
Cvxpy
cvxpy.org › api_reference › cvxpy.atoms.other_atoms.html
Other Atoms -
An Expression representing the mixed norm. Return type:¶ · Expression · cvxpy.atoms.norm.norm(x, p: int | str = 2, axis=None, keepdims: bool = False)[source]¶ · Wrapper on the different norm atoms. Parameters:¶ · x : Expression or numeric constant¶ ·
🌐
Readthedocs
ajfriendcvxpy.readthedocs.io › en › latest › tutorial › functions › pnorm.html
p-norm — CVXPY 0.2.25 documentation - Read the Docs
If given a matrix variable, pnorm will treat it as a vector, and compute the p-norm of the concatenated columns.
🌐
Cvxpy
cvxpy.org › version › 1.2 › _modules › cvxpy › atoms › norm.html
cvxpy.atoms.norm — CVXPY 1.2 documentation
Parameters ---------- x : Expression or numeric constant The value to take the norm of. If `x` is 2D and `axis` is None, this function constructs a matrix norm. Returns ------- Expression An Expression representing the norm. """ return norm(x, p=2, axis=axis) Install · User Guide · Examples · API Documentation · FAQ · Citing CVXPY ·
🌐
Cvxpy
cvxpy.org › _modules › cvxpy › atoms › norm1.html
cvxpy.atoms.norm1 -
""" if self.axis is None: values = np.array(values[0]).flatten() else: values = np.array(values[0]) return np.linalg.norm(values, 1, axis=self.axis, keepdims=self.keepdims) def sign_from_args(self) -> Tuple[bool, bool]: """Returns sign (is positive, is negative) of the expression.
🌐
Cvxpy
cvxpy.org › examples › basic › least_squares.html
Least-squares -
# Import packages. import cvxpy as cp import numpy as np # Generate data. m = 20 n = 15 np.random.seed(1) A = np.random.randn(m, n) b = np.random.randn(m) # Define and solve the CVXPY problem. x = cp.Variable(n) cost = cp.sum_squares(A @ x - b) prob = cp.Problem(cp.Minimize(cost)) prob.solve() # Print result. print("\nThe optimal value is", prob.value) print("The optimal x is") print(x.value) print("The norm of the residual is ", cp.norm(A @ x - b, p=2).value) The optimal value is 7.005909828287484 The optimal x is [ 0.17492418 -0.38102551 0.34732251 0.0173098 -0.0845784 -0.08134019 0.293119 0.27019762 0.17493179 -0.23953449 0.64097935 -0.41633637 0.12799688 0.1063942 -0.32158411] The norm of the residual is 2.6468679280023557 Back to top
Find elsewhere
Top answer
1 of 1
2

Your problem is solved exactly because you don't have any constraint. I skipped the function to make you a shorter script.

import numpy as np
import cvxpy as cp
pts = np.array([(-2, 3), (-3, 5), (-1, 4), (-3, 7), (0, 3),
                (-2, -2), (-3, 8), (3, 1), (1, -2), (2, 6),
                (-2, 6), (-2, 5), (-4, 3), (-4, 6), (-3, 10),
                (2, -3)])

n = pts.shape[0]
x = cp.Variable((n, 2))
objective = cp.Minimize(cp.sum(cp.norm(pts - x, 2, axis=1)))
prob = cp.Problem(objective)
prob.solve()

print(x.value)
# result
# [[-2.  3.]
#  [-3.  5.]
#  [-1.  4.]
#  [-3.  7.]
#  [ 0.  3.]
#  [-2. -2.]
#  [-3.  8.]
#  [ 3.  1.]
#  [ 1. -2.]
#  [ 2.  6.]
#  [-2.  6.]
#  [-2.  5.]
#  [-4.  3.]
#  [-4.  6.]
#  [-3. 10.]
#  [ 2. -3.]]


P.S. maybe this is not your correct answer. The problem is that from what I see in your equation. I'm not able to differentiate the parameters and your values.

Does it mean that you have two functions to minimize? one approaching the points and the other one approaching all the previous points to the current one?

If that's the case, you can replace the code with:

cost1 = cp.sum(cp.norm(pts - x, 2, axis=1))
cost2 = cp.sum([cp.norm(x[j] - x[i],2) for i in range(1, n) for j in range(0, i)])
objective = cp.Minimize(cost1+cost2)
prob = cp.Problem(objective)
prob.solve()
print(x.value)
#result
# [[-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]
#  [-1.7909687  4.4720621]]


But as you can see, the result is not that interesting.

🌐
Readthedocs
ajfriendcvxpy.readthedocs.io › en › latest › tutorial › functions
Functions — CVXPY 0.2.25 documentation - Read the Docs
This section of the tutorial describes the functions that can be applied to CVXPY expressions.
🌐
Snyk
snyk.io › advisor › cvxpy › functions › cvxpy.norm
How to use the cvxpy.norm function in cvxpy | Snyk
def accelerate(self): """ Perform acceleration """ print("Accelerating...") import cvxpy as cvx a = cvx.Variable() constraints = [cvx.sum(a) == 1, a >= 0] objective = cvx.norm(self.work.acceleration.F * a) problem = cvx.Problem(cvx.Minimize(objective), constraints) problem.solve() u = self.work.acceleration.G * a.value print("u = ", u) print("Updating work variables...") x = u[:self.work.data.n] v = u[self.work.data.n:] z = self.project(v) y = self.work.rho_vec * (v - z) self.work.x = x self.work.z = z self.work.y = y
🌐
Cvxpy
cvxpy.org › api_reference › cvxpy.atoms.html
Atoms -
cvxpy.atoms.min.min · mixed_norm · cvxpy.atoms.mixed_norm.mixed_norm · Parameters · X · p · q · Returns · Return type · norm · cvxpy.atoms.norm.norm · Parameters · x · p · axis · keepdims · Returns · Return type · norm1 · cvxpy.atoms.norm1.norm1 ·
🌐
Byu
labs.acme.byu.edu › Volume2 › CVXPY_Intro › CVXPY_Intro.html
Intro to CVXPY — ACME Labs
To specify a norm in CVXPY, use the syntax cp.norm(x, a) where \(a\) represents your choice of norm (1 in this case).
🌐
GitHub
github.com › cvxpy › cvxpy › issues › 443
Infinity norm for matrices different than convention · Issue #443 · cvxpy/cvxpy
February 23, 2018 - According to the documentation, the function norm(X, 'inf') when X is a matrix computes \sum_{i,j}|X_{i,j}|, which is different than the convention, \max_i \sum_j |a_{i,j}|. This could lead to some confusion · source: http://mathworld.wolfram.com/MatrixNorm.html
Author   sbarratt
🌐
Ee227c
ee227c.github.io › code › lecture22.html
Non-convex constraints part 2: projected gradient descent
def l1min(y, A): x_hat = cvxpy.Variable(A.shape[1]) objective = cvxpy.Minimize(cvxpy.norm(x_hat, 1)) constraints = [A * x_hat == y] prob = cvxpy.Problem(objective, constraints) prob.solve() return np.squeeze(np.array(x_hat.value)), (prob.value, prob.status) Let's see if we get an accurate solution, e.g., in terms of relative error.
🌐
Cvxpy
cvxpy.org › examples › applications › sparse_solution.html
Computing a sparse solution of a set of linear inequalities -
# Create variable. x_l1 = cp.Variable(shape=n) # Create constraint. constraints = [A*x_l1 <= b] # Form objective. obj = cp.Minimize(cp.norm(x_l1, 1)) # Form and solve problem. prob = cp.Problem(obj, constraints) prob.solve() print("status: {}".format(prob.status)) # Number of nonzero elements in the solution (its cardinality or diversity).
🌐
Reddit
reddit.com › r/optimization › cvxpy: why norm constraint is not dcp?
r/optimization on Reddit: CVXPY: Why Norm constraint is not DCP?
October 12, 2023 -

`cp.norm(weights, 1).is_dcp()` returns true. Then why this code works:

import numpy as np
import cvxpy as cp

inputs = np.random.normal(0, 1, (100, 300))
inputs_mean = inputs.mean(axis=1) # shape (features,)
inputs_cov = np.asmatrix(np.cov(inputs)) # shape (features, features)

weights = cp.Variable(len(inputs))
risk = cp.quad_form(weights, inputs_cov)

constraints = [
# cp.norm(weights, 1) == 1.,
cp.sum(weights) == 1.,
]
problem = cp.Problem(cp.Minimize(risk), constraints)
problem.solve(verbose=True)
weights.value

But if you use the first constraint (`cp.norm`) instead of the second, it does not:

DCPError: Problem does not follow DCP rules. Specifically:
The following constraints are not DCP:
norm1(var456) == 1.0 , because the following subexpressions are not:
|--  norm1(var456) == 1.0

Why is it not DCP-compliant? How can I troubleshoot it? Is there an alternative way to solve the problem of requiring the sum of abs weights to be 1? Thanks.