I would like to solve a maximization problem involving a linear objective function and nonlinear constraint. In particular, my problem is:
max_x f(x) = c_1x_1
s.t. g_m(x) <= 0 for m = 1,...,M
g_m(x) = 0 for m = M+1,...,N
x in X
where X is a compact subset of a finite dimensional euclidean space. One way to solve this is to use the fmincon function in MatLab. To do this, we call
fmincon(#(x)linobj(x,c),x0,[],[],[],[],lx,ux,nonlinear_constraint,options_fmincon);
where linobj(x,c) is the linear function
function [val,gradient] = linobj(x,c)
% c is a vector with c = (c_1,0,0,...,0)'
val = dot(x,c)
if nargout > 1
gradient = [c(1) 0 0 ... 0].'
end
end
nonlinear_constraint is a function of x that computes the inequality and equality constraint values at x and the gradients, and ux and lx specifies the boundary of X.
I understand that there are fast methods of computing the argmax to a problem that has linear/quadratic objective function with linear/quadratic constraints (e.g., by using CVXGEN). So my question is this: Given the particular structure of this problem, is there a faster way of computing the argmax of this problem (relative to fmincon) in Matlab? In particular, can I use the fact that my objective function is linear to speed up computation?
Related
Working in MATLAB. I have the following equation:
S = aW + bX + cY + dZ
where S,W,X,Y, and Z are all known n x 1 vectors. I am trying to fit the data of S with a linear combination of the basis vectors W,X,Y, and Z with the constraint of the constants (a,b,c,d) being greater than 0. I have managed to do this in Excel's solver, and have attempted to figure it out on MATLAB, being directed towards functions like fmincon, but I am not overly familiar with MATLAB and feel I am misunderstanding the use of fmincon.
I am looking for help with understanding fmincon's use towards my problem, or redirection towards a more efficient method for solving.
Currently I have:
initials = [0.2 0.2 0.2 0.2];
fun = #(x)x(1)*W + x(2)*X + x(3)*Y + x(4)*Z;
lb = [0,0,0,0];
soln = fmincon(fun,initials,data,b,Aeq,beq,lb,ub);
I am receiving an error stating "A must have 4 column(s)". Where A is referring to my variable data which corresponds to my S in the above equation. I do not understand why it is expecting 4 columns. Also to note the variables that are in my above snippet that are not explicitly defined are defined as [], serving as space holders.
Using fmincon is a huge overkill in this case. It's like using big heavy microscope to crack nuts... or martian rover to tow a pushcart or... anyway :) May be it's OK if you don't have to process large sets of vectors. If you need to fit hundreds of thousands of such vectors it can take hours. But this classic solution will be faster by several orders of magnitude.
%first make a n x 4 matrix of your vectors;
P=[W,X,Y,Z];
% now your equation looks like this S = P*m where m is 4 x 1 vectro
% containing your coefficients ( m = [a,b,c,d] )
% so solution will be simply
m_1 = inv(P'*P)*P'*S;
% or you can use this form
m_2 = (P'*P)\P'*S;
% or even simpler
m_3 = (S'/P')';
% all three solutions should give exactly same resul
% third solution is the neatest but may not work in every version of matlab
% Your modeled vector will be
Sm = P*m_3; %you can use any of m_1, m_2 or m_3;
% And your residual
R = S-Sm;
If you need to procees many vectors don't use for cycle. For cycles are very slow in Matlab and you should use matrices instead, if possible. S can also be nk matrix, where k is number vectors you want to process. In this case m will be 4k matrix.
What you are trying to do is similar to the answer I gave at is there a python (or matlab) function that achieves the minimum MSE between given set of output vector and calculated set of vector?.
The procedure is similar to what you are doing in EXCEL with solver. You create an objective function that takes (a, b, c, d) as the input parameters and output a measure of fit (mse) and then use fmincon or similar solver to get the best (a, b, c, d) that minimize this mse. See the code below (no MATLAB to test it but it should work).
function [a, b, c, d] = optimize_abcd(W, X, Y, Z)
%=========================================================
%Second argument is the starting point, second to the last argument is the lower bound
%to ensure the solutions are all positive
res = fmincon(#MSE, [0,0,0,0], [], [], [], [], [0,0,0,0], []);
a=res(1);
b=res(2);
c=res(3);
d=res(4);
function mse = MSE(x_)
a_=x_(1);
b_=x_(2);
c_=x_(3);
d_=x_(4);
S_ = a_*W + b_*X + c_*Y + d_*Z
mse = norm(S_-S);
end
end
I have a complex equation involving matrices:
R = expm(X)*A + (expm(X)-I)*inv(X)*B*U;
where R, B and U are known matrices.
I is an identity matrix.
I need to solve for X. Is there any way to solve this in MATLAB?
If your equation is nonlinear and you have access to MATLAB optimization toolbox you can use the fsolve function (You can still use it for a linear equation, but it may not be the most efficient approach). You just need to reformat your equation into the form F(x) = 0, where x is a vector or a matrix. For example, if X is a vector of length 2:
Define your function to solve:
function F = YourComplexEquation(X)
Fmatrix = expm(X)*A + (expm(X)-I)*inv(X)*B*U - R
% This last line is because I think fsolve requires F to be a vector, not a matrix
F = Fmatrix(:);
Then call fsolve with an initial guess:
X = fsolve(#YourComplexEquation,[0;0]);
Suppose we have this Hamiltonian:
n = 10;
H = ones(n,n);
The density matrix is:
Ro = sym('r',[n,n]);%Density matrix
The equation of motion is:
H*Ro-Ro*H
The above equation of motion is the right hand side of the equation, the left hand side is the time derivative of density matrix.
How can I solve the equation of motion in Matlab without the symbolic math toolbox? I need to change the value of n. It can be up to 100.
In your dynamics function, reshape between vectors and matrices in order to use MATLAB's standard ode functions, which (to my knowledge) require vector inputs. Note, the symbolic toolbox isn't used anywhere in this solution. R can be any size n-by-n, within the constraints of your machine's memory.
function dR = dynfun(R,H)
%// R = n^2-by-1 vector
%// H = n-by-n matrix
n = sqrt(length(R));
R = reshape(R,[n,n]); %// reshape R to n-by-n matrix
dR = H*R-R*H;
dR = dR(:); %// reshape dR to n^2-by-1 vector
end
Call the ODE solver:
[tout,Rout] = ode45(#(t,R) dynfun(R,H), [0,T], R0(:));
where T is final time, R0 is n-by-n initial condition, tout are the output time steps, and Rout is the solution trajectory. Note due to the reshaping, Rout will be k-by-n^2, where k is the number of time steps. You'll need to reshape each row of Rout if you want to have the actual matrices over time.
My approach
fun = #(y) (1/sqrt(pi))*exp(-(y-1).^2).*log(1 + exp(-4*y))
integral(fun,-Inf,Inf)
This gives NaN.
So I tried plotting it.
y= -10:0.1:10;
plot(y,exp(-(y-1).^2).*log(1 + exp(-4*y)))
Then understood that domain (siginificant part) is from -4 to +4.
So changed the limits to
integral(fun,-10,10)
However I do not want to always plot the graph and then know its limits. So is there any way to know the integral directly from -Inf to Inf.
Discussion
If your integrals are always of the form
I would use a high-order Gauss–Hermite quadrature rule.
It's similar to the Gauss-Legendre-Kronrod rule that forms the basis for quadgk but is specifically tailored for integrals over the real line with a standard Gaussian multiplier.
Rewriting your equation with the substitution x = y-1, we get
.
The integral can then be computed using the Gauss-Hermite rule of arbitrary order (within reason):
>> order = 10;
>> [nodes,weights] = GaussHermiteRule(order);
>> f = #(x) log(1 + exp(-4*(x+1)))/sqrt(pi);
>> sum(f(nodes).*weights)
ans =
0.1933
I'd note that the function below builds a full order x order matrix to compute nodes, so it shouldn't be made too large.
There is a way to avoid this by explicitly computing the weights, but I decided to be lazy.
Besides, event at order 100, the Gaussian multiplier is about 2E-98, so the integrand's contribution is extremely minimal.
And while this isn't inherently adaptive, a high-order rule should be sufficient in most cases ... I hope.
Code
function [nodes,weights] = GaussHermiteRule(n)
% ------------------------------------------------------------------------------
% Find the nodes and weights for a Gauss-Hermite Quadrature integration.
%
if (n < 1)
error('There is no Gauss-Hermite rule of order 0.');
elseif (n < 0) || (abs(n - round(n)) > eps())
error('Given order ''n'' must be a strictly positive integer.');
else
n = round(n);
end
% Get the nodes and weights from the Golub-Welsch function
n = (0:n)' ;
b = n*0 ;
a = b + 0.5 ;
c = n ;
[nodes,weights] = GolubWelsch(a,b,c,sqrt(pi));
end
function [xk,wk] = GolubWelsch(ak,bk,ck,mu0)
%GolubWelsch
% Calculate the approximate* nodes and weights (normalized to 1) of an orthogonal
% polynomial family defined by a three-term reccurence relation of the form
% x pk(x) = ak pkp1(x) + bk pk(x) + ck pkm1(x)
%
% The weight scale factor mu0 is the integral of the weight function over the
% orthogonal domain.
%
% Calculate the terms for the orthonormal version of the polynomials
alpha = sqrt(ak(1:end-1) .* ck(2:end));
% Build the symmetric tridiagonal matrix
T = full(spdiags([[alpha;0],bk,[0;alpha]],[-1,0,+1],length(alpha),length(alpha)));
% Calculate the eigenvectors and values of the matrix
[V,xk] = eig(T,'vector');
% Calculate the weights from the eigenvectors - technically, Golub-Welsch requires
% a normalization, but since MATLAB returns unit eigenvectors, it is omitted.
wk = mu0*(V(1,:).^2)';
end
I've had success with transforming such infinite-bounded integrals using a numerical variable transformation, as explained in Numerical Recipes 3e, section 4.5.3. Basically, you substitute in y=c*tan(t)+b and then numerically integrate over t in (-pi/2,pi/2), which sweeps y from -infinity to infinity. You can tune the values of c and b to optimize the process. This approach largely dodges the question of trying to determine cutoffs in the domain, but for this to work reliably using quadrature you have to know that the integrand does not have features far from y=b.
A quick and dirty solution would be to look for a position, where your function is sufficiently small enough and then taking it as limits. This assumes that for x>0 the function fun decreases montonically and fun(x) is roughly the same size as fun(-x) for all x.
%// A small number
epsilon = eps;
%// Stepsize for searching bound
stepTest = 1;
%// Starting position for searching bound
position = 0;
%// Not yet small enough
smallEnough = false;
%// Search bound
while ~smallEnough
smallEnough = (fun(position) < eps);
position = position + stepTest;
end
%// Calculate integral
integral(fun, -position, position)
If your were happy with plotting the function, deciding by eye where you can cut, then this code will suffice, I guess.
I have output matrix Y as:
Y=E*A;
where
E=Exponential phase vectors (1xM)
A=Fixed complex numbers (MxN)
say,
M=4;N=256;
a = complex(randn(4,256),randn(4,256)); % coefficient matrix of "A"
theta=has four values
Objective:
What range of theta will minimize the peak of sum expression of a kth column
of "Y" ? i.e.,
Theta subjected to and m=1,2,...,M
for e.g.,
Min: Y(theta)=Peak{a11*exp(j*theta1)+ a21*exp(j*theta2)+ ...+aM1*exp(j*thetaM)}
My Question:
Can i use MATLAB to develop a logic to formulate such a problem and solve it ?
I think this is related to Linear Programming with constraints (??).
My approach will be to use the fmincon function from the matlab optimization toolbox.
Your theta vector would be the x vector of solutions you're looking for.
Then specify your problem by defining the objective function f(x) as the max from Yk for all K between 0 and N.
objectiveFunction = #(x) maxY(...
x,... %
A);
Express your constraint 0<=theta<2pi with the individuals constraints lb and ub (lower and upper bounds).
Then call fmincon
options = optimset('Algorithm','sqp', ...
'Display', 'iter-detailed',...
'UseParallel', 'always',...
'MaxFunEvals', 3000);
[result, ~, ~] = fmincon(objectiveFunction,x0,[],[],[],[],lb,ub,[],options);