I've been trying to pass some code from Matlab to Python. I have the same convex optimization problem working on Matlab but I'm having problems passing it to either CVXPY or CVXOPT.
n = 1000;
i = 20;
y = rand(n,1);
A = rand(n,i);
cvx_begin
variable x(n);
variable lambda(i);
minimize(sum_square(x-y));
subject to
x == A*lambda;
lambda >= zeros(i,1);
lambda'*ones(i,1) == 1;
cvx_end
This is what I tried with Python and CVXPY.
import numpy as np
from cvxpy import *
# Problem data.
n = 100
i = 20
np.random.seed(1)
y = np.random.randn(n)
A = np.random.randn(n, i)
# Construct the problem.
x = Variable(n)
lmbd = Variable(i)
objective = Minimize(sum_squares(x - y))
constraints = [x == np.dot(A, lmbd),
lmbd <= np.zeros(itr),
np.sum(lmbd) == 1]
prob = Problem(objective, constraints)
print("status:", prob.status)
print("optimal value", prob.value)
Nonetheless, it's not working. Does any of you have any idea how to make it work? I'm pretty sure my problem is in the constraints. And also it would be nice to have it with CVXOPT.
I think I got it, I had one of the constraints wrong =), I added a random seed number in order to compare the results and check that are in fact the same in both languages. I leave the data here so maybe this is useful for somebody someday ;)
Matlab
rand('twister', 0);
n = 100;
i = 20;
y = rand(n,1);
A = rand(n,i);
cvx_begin
variable x(n);
variable lmbd(i);
minimize(sum_square(x-y));
subject to
x == A*lmbd;
lmbd >= zeros(i,1);
lmbd'*ones(i,1) == 1;
cvx_end
CVXPY
import numpy as np
import cvxpy as cp
# random seed
np.random.seed(0)
# Problem data.
n = 100
i = 20
y = np.random.rand(n)
# A = np.random.rand(n, i) # normal
A = np.random.rand(i, n).T # in this order to test random numbers
# Construct the problem.
x = cp.Variable(n)
lmbd = cp.Variable(i)
objective = cp.Minimize(cp.sum_squares(x - y))
constraints = [x == A*lmbd,
lmbd >= np.zeros(i),
cp.sum(lmbd) == 1]
prob = cp.Problem(objective, constraints)
result = prob.solve(verbose=True)
CVXOPT is pending.....
Related
I am trying to work on an optimization problem using python and I started working on GEKKO since it solves nonlinear programs. I have written a simple model in LINGO to check the answer which didn't have the same value as the answer I got from GEKKO (same model).
Python Code:-
from gekko import GEKKO
# Initialize Model
smplmdl = GEKKO()
# Create Variables
x = smplmdl.Array(smplmdl.Var, 3, lb = 0)
a = smplmdl.Array(smplmdl.Var, 3, lb = 0)
Constant_Val = [10, 15, 20]
for i in range(3):
smplmdl.Equation(x[i]*(sum(a[j] for j in range(3))) == Constant_Val[i])
# Objective Function
smplmdl.Obj(sum(x[i] for i in range(3)))
smplmdl.options.IMODE = 3
smplmdl.solve()
smplmdl.options.OBJFCNVAL
print('x:', x)
print('a:', a)
print(smplmdl.options.OBJFCNVAL)
LINGO Code:-
Min = x1 + x2 + x3;
x1*(a1 + a2 + a3) = 10;
x2*(a1 + a2 + a3) = 15;
x3*(a1 + a2 + a3) = 20;
It is possible to simply the model.
from gekko import GEKKO
# Initialize Model
smplmdl = GEKKO(remote=False)
# Create Variables
x = smplmdl.Array(smplmdl.Var, 3, lb = 0)
a = smplmdl.Array(smplmdl.Var, 3, lb = 0)
Constant_Val = [10, 15, 20]
for i in range(3):
smplmdl.Equation(x[i]*sum(a) == Constant_Val[i])
# Objective Function
smplmdl.Minimize(sum(x))
# Solve and print solution
smplmdl.solve()
print('x:', x)
print('a:', a)
print(smplmdl.options.OBJFCNVAL)
This gives the solution:
x: [[5.7995291433e-05] [8.699293715e-05] [0.00011599058287]]
a: [[57475.93038] [57475.930412] [57475.930377]]
Objective: 0.00026097881145
The objective is to minimize the summation of x and the objective function obtained by IPOPT is 2.6e-4. If LINGO gave a different solution, there are likely solver tolerances that can be adjusted to achieve better agreement. Try adjusting m.options.RTOL and m.options.OTOL for the residual and objective function tolerances. For non-convex problems, a multi-start method or a global solver may be better suited to this problem.
If the purpose is to compare LINGO and GEKKO, perhaps try a simple convex optimization problem such as:
from gekko import GEKKO
import numpy as np
m = GEKKO()
x = m.Array(m.Var,4,value=1,lb=1,ub=5)
x1,x2,x3,x4 = x
# change initial values
x2.value = 5; x3.value = 5
m.Equation(x1*x2*x3*x4>=25)
m.Equation(x1**2+x2**2+x3**2+x4**2==40)
m.Minimize(x1*x4*(x1+x2+x3)+x3)
m.solve()
print(x,m.options.OBJFCNVAL)
I am using cvxpy to solve a second order cone program. I have used the boilerplate code as mentioned in the cvxpy website - cvxpy SOCP webpage. I do not know how to obtain the variable value after each iteration...
Code from the link:
# Import packages.
import cvxpy as cp
import numpy as np
# Generate a random feasible SOCP.
m = 3
n = 10
p = 5
n_i = 5
f = np.random.randn(n)
A = []
b = []
c = []
d = []
x0 = np.random.randn(n)
for i in range(m):
A.append(np.random.randn(n_i, n))
b.append(np.random.randn(n_i))
c.append(np.random.randn(n))
d.append(np.linalg.norm(A[i] # x0 + b, 2) - c[i].T # x0)
# Define and solve the CVXPY problem.
x = cp.Variable(n)
# We use cp.SOC(t, x) to create the SOC constraint ||x||_2 <= t.
soc_constraints = [
cp.SOC(c[i].T # x + d[i], A[i] # x + b[i]) for i in range(m)
]
prob = cp.Problem(cp.Minimize(f.T#x), soc_constraints)
prob.solve()
# Print result.
print("The optimal value is", prob.value)
print("A solution x is")
print(x.value)
x.value here only gives the variable value after all the iterations are done. I want x.value after each iteration.
I noticed that if you add to your target something multiplied by zero it will affect the solution significantly. I found this bug when using cvxpy on my dataset which I cant upload of course. But here is an example from their official resource: https://www.cvxpy.org/examples/basic/sdp.html
import cvxpy as cp
import numpy as np
# Generate a random SDP.
n = 3
p = 3
np.random.seed(1)
C = np.random.randn(n, n)
A = []
b = []
for i in range(p):
A.append(np.random.randn(n, n))
b.append(np.random.randn())
# Define and solve the CVXPY problem.
# Create a symmetric matrix variable.
X = cp.Variable((n,n), symmetric=True)
# The operator >> denotes matrix inequality.
constraints = [X >> 0]
constraints += [
cp.trace(A[i] # X) == b[i] for i in range(p)]
prob = cp.Problem(cp.Minimize(cp.trace(C # X)),
constraints)
prob.solve()
# Print result.
print("The optimal value is", prob.value)
print("A solution X is")
print(X.value)
Now do the same but change
prob = cp.Problem(cp.Minimize(cp.trace(C # X) + 0*cp.trace(C # X)**9),
constraints)
You will see that value of X will change.
I am trying to implement a finite difference approximation to solve the Heat Equation, u_t = k * u_{xx}, in Python using NumPy.
Here is a copy of the code I am running:
## This program is to implement a Finite Difference method approximation
## to solve the Heat Equation, u_t = k * u_xx,
## in 1D w/out sources & on a finite interval 0 < x < L. The PDE
## is subject to B.C: u(0,t) = u(L,t) = 0,
## and the I.C: u(x,0) = f(x).
import numpy as np
import matplotlib.pyplot as plt
# parameters
L = 1 # legnth of the rod
T = 10 # terminal time
N = 10
M = 100
s = 0.25
# uniform mesh
x_init = 0
x_end = L
dx = float(x_end - x_init) / N
x = np.arange(x_init, x_end, dx)
x[0] = x_init
# time discretization
t_init = 0
t_end = T
dt = float(t_end - t_init) / M
t = np.arange(t_init, t_end, dt)
t[0] = t_init
# Boundary Conditions
for m in xrange(0, M):
t[m] = m * dt
# Initial Conditions
for j in xrange(0, N):
x[j] = j * dx
# definition of solution u(x,t) to u_t = k * u_xx
u = np.zeros((N, M+1)) # array to store values of the solution
# Finite Difference Scheme:
u[:,0] = x**2 #initial condition
for m in xrange(0, M):
for j in xrange(1, N-1):
if j == 1:
u[j-1,m] = 0 # Boundary condition
elif j == N-1:
u[j+1,m] = 0
else:
u[j,m+1] = u[j,m] + s * ( u[j+1,m] -
2 * u[j,m] + u[j-1,m] )
print u, #t, x
plt.plot(u, t)
#plt.show()
I think my code is working properly and it is producing an output. I want to plot the output of the solution u versus t (my time vector). If I can plot the graph then I am able to check if my numerical approximation agrees with the expected phenomena for the Heat Equation. However, I am getting the error that "x and y must have same first dimension". How can I correct this issue?
An additional question: Am I better off attempting to make an animation with matplotlib.animation instead of using matplotlib.plyplot ???
Thanks so much for any and all help! It is very greatly appreciated!
Okay so I had a "brain dump" and tried plotting u vs. t sort of forgetting that u, being the solution to the Heat Equation (u_t = k * u_{xx}), is defined as u(x,t) so it has values for time. I made the following correction to my code:
print u #t, x
plt.plot(u)
plt.show()
And now my programming is finally displaying an image. And here it is:
It is absolutely beautiful, isn't it?
I need to solve an optimization problem with CVXOPT or CVXPY in Python and I have run into difficulties. The objective function is
Minimize Sum(a*x^2+b/x)
subject to the following constraints
5 <= x < 40;
sum(v/d)<=T
where vector x is the optimization variable, vectors a and b are given, and T is a given scalar.
The following code solves the problem in CVXPY. I assumed that you meant sum(x/d) <= T.
# Replace these with your values.
n = 2
a = 2
b = 2
d = 2
T = 1000
import cvxpy as cvx
x = cvx.Variable(n)
obj = cvx.sum_entries(a*x**2 + b*cvx.inv_pos(x))
constr = [5 <= x,
x <= 40,
cvx.sum_entries(x/d) <= T]
prob = cvx.Problem(cvx.Minimize(obj), constr)
prob.solve()