I've been struggling with the parameterization of quadprog function in Matlab for a problem like this:
where x is a matrix of x 0 w 0 +x 1 w 1 +x 2 2 w 2 and y is the target vector containing a value for each row of x, w is the weight vector, lambda is a scalar value.
I have tried this, but I'm sure it's not correct:
N = size(x, 2);
Sigma = cov(x);
H = 2.0*Sigma;
c = zeros(N,1);
quadprog(H, c)
Could someone please guide me with what the parameters should be for the quadprog function?
This optimization problem is known as Lasso, and as you wrote it it is not formally a quadratic program. You can either convert it to a quadratic program, see this link, or you can use Matlab's builtin lasso (part of Statistics toolbox)
Related
I have such an question, And I will do it in matlab. But, I get some errors:
Find the value of x ∈ [0, 1] that minimizes the largest eigenvalue of the matrix A(x) = xM +(1−x)P, where M is a 5×5 magic square and P is a 5 × 5 Pascal matrix.
My matlab code:
%Define Matrices
M = magic(5);
P = pascal (5);
% Define the variable x
syms x
%Define the given matrix A
>> A = x*M + (1-x)*P;
%Define the eigenvalue lambda as y;
syms y
%Find determinant of |A - lambda * I|
D = det (A - y*eye(5))
%Define Objective function
objective = #(y) y
%And Define the constraint
constraint = #(x,y) (-1)*D
%initial value x0 = (0:0.001:1);
%Minimization problem solving
x = fmincon(objective, constraint, x0)
I get this error;
Error using fmincon (line 221)
FMINCON requires the following inputs to be of data type double: 'X0'.
Or If I use another function: fminsearch
x = fminsearch(objective, constraint, x0)
In this case I get the following error:
Error using fminsearch (line 96)
FMINSEARCH accepts inputs only of data type double.
How can I deal with these errors ? Where is my mistake? How can I correct them?
I guess what you are looking for might be fminbnd, which helps to
Find minimum of single-variable function on fixed interval
n = 5;
M = magic(n);
P = pascal(n);
x = fminbnd(#(x) max(eig(x*M + (1-x)*P)),0,1);
such that
>> x
x = 0.79603
I suspect you did not show us the proper code, as you have sums there. I suspect you mean syms.
fmincon only works for numeric data, not symbolic data.
I have an equation like this:
dy/dx = a(x)*y + b
where a(x) is a non-constant (a=1/x) and b is a vector (10000 rows).
How can I solve this equation?
Let me assume you would like to write a generic numerical solver for dy/dx = a(x)*y + b. Then you can pass the function a(x) as an argument to the right-hand side function of one of the ODE solvers. e.g.
a = #(x) 1/x;
xdomain = [1 10];
b = rand(10000,1);
y0 = ones(10000,1);
[x,y] = ode45(#(x,y,a,b)a(x)*y + b,xdomain,y0,[],a,b);
plot(x,y)
Here, I've specified the domain of x as xdomain, and the value of y at the bottom limit of x as y0.
From my comments, you can solve this without MATLAB. Assuming non-zero x, you can use an integrating factor to get a 10000-by-1 solution y(x)
y_i(x) = b_i*x*ln(x) + c_i*x
with 10000-by-1 vector of constants c, where y_i(x), b_i and c_i are the i-th entries of y(x), b and c respectively. The constant vector c can be determined at some point x0 as
c_i = y_i(x0)/x_0 - b_i*ln(x0)
I am trying to calculate expressions for magnetic helicity rate of change in Matlab, where the overall formula I am calculating is:
int(A * B * V,x)
(the topic itself isn't really necessary here).
B is essentially a constant multiplied by the legendre polynomials of degree 0-9 and order 0.
B is the curl of A so A is then found by Stokes' Theorem, and V is a function of x which is always the same.
When I run the script below, dH only has an explicit answer for the i=1 case, all other cases for dH are left as int(A(i)*B(i)*V,x). So my question is, are the expressions that I'm trying to integrate simply too complicated for matlab of have I done something wrong in the code? (Note, g and R are constants)
Thanks for your help!
%%Calculate B, A and dh/dt expressions for m=0 case
clear
syms x %In our case this is theta
syms R
syms g
syms a
syms b
syms c
V = a + b*cos(x)^2 + c*cos(x)^4;
for i = 1:10 %Matlab indices must start from 1
B(i) = g*legendreP(i-1,x);
A(i) = R*csc(x)*int(sin(x)*B(i),0,x);
dH(i) = int(A(i)*B(i)*V,x);
end
I have a Matlab function that returns a polynomial of the form:
poly = ax^2 + bx*y + cy^2
where a, b, and c are constants, and x and y are symbolic (class sym).
I want to get the coefficients of the polynomial in the form [a b c], but I'm running into the following problem. If the function returns poly = y^2, then coeffs(poly) = 1. I don't want this – I want it to return [0 0 1].
How can I create a function that will give me the coefficients of a symbolic polynomial in the form that I want?
You can use sym2poly if your polynomial is a function of a single variable like your example y^2:
syms y
p = 2*y^2+3*y+4;
c = sym2poly(p)
which returns
c =
2 3 4
Use fliplr(c) if you really want the coefficients in the other order. If you're going to be working with polynomials it would probably also be a good idea not to create a variable called poly, which is the name of a function you might want to use.
If you actually need to handle polynomials in multiple variables, you can use MuPAD functions from within Matlab. Here is how you can use MuPAD's coeff to get the coefficients in terms of the order of variable they precede (x or y):
syms x y
p = 2*x^2+3*x*y+4*y;
v = symvar(p);
c = eval(feval(symengine,'coeff',p,v))
If you want to extract all of the information from the polynomial, the poly2list function is quite helpful:
syms x y
p = 2*x^2+3*x*y+4*y;
v = symvar(p);
m = eval(feval(symengine,'poly2list',p,v));
c = m(:,1); % Coefficients
degs = m(:,2:end); % Degree of each variable in each term
The polynomial can then be reconstructed via:
sum(c.*prod(repmat(v,[size(m,1) 1]).^degs,2))
By the way, good choice on where you go to school. :-)
There is also an alternative to this problem. For a given degree, this function returns a polynomial of that degree and its coefficients altogether.
function [polynomial, coefficeint] = makePoly(degree)
syms x y
previous = 0 ;
for i=0:degree
current = expand((x+y)^i);
previous= current + previous ;
end
[~,poly] = coeffs(previous);
for j= 1:length(poly)
coefficeint(j) = sym(strcat('a', int2str(j)) );
end
polynomial = fliplr(coefficeint)* poly.' ;
end
Hope this helps.
Given a M x M desired covariance, R, and a desired number of sample vectors, N calculate a N x M Gaussian random vector, X in vanilla MATLAB (i.e. can't use r = mvnrnd(MU,SIGMA,cases)).
Not really sure how to tackle this, usually you need a covariance AND mean to generate a Gaussian random variable. I think sqrtm and chol could be useful.
If you have access to the MATLAB statistics toolbox you can type edit mvnrnd in MATLAB to see their solution.
[T p] = chol(sigma);
if m1 == c
mu = mu';
end
mu = mu(ones(cases,1),:);
r = randn(cases,c) * T + mu;
It feels almost like cheating to point this out, but editing MATLAB's source is very useful to understand things in general. You can also search for mvnrnd.m on google if you don't have the toolbox.
Example:
% Gaussian mean and covariance
d = 2; % number of dimensions
mu = rand(1,d);
sigma = rand(d,d); sigma = sigma*sigma';
% generate 100 samples from above distribution
num = 100;
X = mvnrnd(mu, sigma, num);
% plot samples (only for 2D case)
scatter(X(:,1), X(:,2), 'filled'), hold on
ezcontour(#(x,y) mvnpdf([x y], mu, sigma), xlim(), ylim())
title('X~N(\mu,\sigma)')
xlabel('X_1'), ylabel('X_2')
The above code uses functions from the Statistics toolbox (mvnrnd and mvnpdf). If you don't have access to it, consider these replacements (using the same concepts mentioned by others):
mvnrnd = #(mu,S,num) bsxfun(#plus, randn(num,numel(mu))*cholcov(S), mu);
mvnpdf = #(x,mu,S) exp(-0.5*(x-mu)*(S\(x-mu)')) / sqrt((2*pi)^d*det(S));