TLDR
I wrote a code to solve a SDP problem. I used subs to change syms into numerical value before cvx content and I did see the numerical value after I printed out the variables. But whos() did show that the variable is still syms type which I think might be the key point where I went wrong. The error message shows like this:
Unable to convert 'cvx' to 'sym'.
It went wrong at the line trace(rhot*X_ele(:,:,i)) == value(i); where rhot is symbolic instead of numeric.
Details
I'm trying to write a SDP problem as follows:
function [res] = NH_SDP(rhot,p,value,t)
dim = size(rhot,1);
for i = 1:p
drhot(:,:,i) = diff(rhot,t(i));
end
drhot = subs(drhot,t,value);
rhot = subs(rhot,t,value);
rhott = kron(eye(p),rhot);
% cvx process
cvx_begin sdp
% cvx part
variable L_ele(dim,dim,(1+p)*p/2) hermitian;
variable X_ele(dim,dim,p) hermitian;
cnt = 1;
for i = 1:p
for j = i:p
if i == j
L((i-1)*dim+1:i*dim,(j-1)*dim+1:j*dim) = L_ele(:,:,cnt);
cnt = cnt + 1;
else
L((i-1)*dim+1:i*dim,(j-1)*dim+1:j*dim) = L_ele(:,:,cnt);
L((j-1)*dim+1:j*dim,(i-1)*dim+1:i*dim) = L_ele(:,:,cnt);
cnt = cnt + 1;
end
end
end
for i = 1:p
X((i-1)*dim+1:i*dim,1:dim) = X_ele(:,:,i);
end
for i = 1:p
X2(1:dim,(i-1)*dim+1:i*dim) = X_ele(:,:,i);
end
% rhott = [[0, 0, 0, 0, 0, 0, 0, 0]
% [0, 1/2, 7/20, 0, 0, 0, 0, 0]
% [0, 7/20, 1/2, 0, 0, 0, 0, 0]
% [0, 0, 0, 0, 0, 0, 0, 0]
% [0, 0, 0, 0, 0, 0, 0, 0]
% [0, 0, 0, 0, 0, 1/2, 7/20, 0]
% [0, 0, 0, 0, 0, 7/20, 1/2, 0]
% [0, 0, 0, 0, 0, 0, 0, 0]];
rhott = double(rhott);
rhot = double(rhot);
drhot = double(drhot);
minimize(trace(rhott*L));
subject to
% rhot = [0 0 0 0;0 1/2 7/20 0;0 7/20 1/2 0;0 0 0 0];
% drhot
for i =1:p
trace(rhot*X_ele(:,:,i)) == value(i);
end
for i = 1:p
for j = 1:p
if i == j
trace(drhot(:,:,i)*X_ele(:,:,j)) == 1;
else
trace(drhot(:,:,i)*X_ele(:,:,j)) == 0;
end
end
end
% semidefinit constraint.
[L X; X2 eye(dim)] >= 0;
cvx_end
res = cvx_optval;
X_ele
end
There are three line in the above code:
rhott = double(rhott);
rhot = double(rhot);
drhot = double(drhot);
If I delete those three lines, there will be error Unable to convert 'cvx' to 'sym'. while my rhot have already changed into numerical value by subs function and I print it out to see numerical numbers even though whos function show that the type of rhot is still syms.
To cite the documentation on subs():
snew = subs(s,old,new) returns a copy of s, replacing all occurrences
of old with new, and then evaluates s. Here, s is an expression of
symbolic scalar variables or a symbolic function, and old specifies
the symbolic scalar variables or symbolic function to be substituted.
emphasis mine. In other words: subs() changes your symbolic expression to a new symbolic expression.
double() on the other hand, converts whatever you feed it to a type double, i.e. a numeric value. rhott thus initially contains a symbolic value, even if that is a number. double(rhott) then evaluates it to a numeric number, rather than a symbolic one.
I presume the problem is here
drhot = subs(drhot,t,value);
rhot = subs(rhot,t,value);
rhott = kron(eye(p),rhot);
You're substituting all occurrences of t within drhot with value, and then again on rhot. if drhot is already symbolic, i.e. if the inputs rhot, value, t are symbolic, this makes sense and indeed a double call will make your system numeric, rather than symbolic. If, on the other hand, all inputs are numeric, subs() unnecessarily converts everything to symbolic variables, slowing execution speed.
I created a function file on Octave like this,
function y = sum_odd(n)
if rem(n,2) ==1
sum_odd = sum(n)
endif
endfunction
and I want to make the function evaluate the sum of odd numbers in every vectors.
But when I tried sum_odd([1 2 3]), it didn't calculate for me.
Any ideas how to fix this problem?
You can simply use logical indexing:
function y = sum_odd(n)
y = sum(n(rem(n,2)==1))
end
rem([1 2 3],2)==1) returns logical array: [1 0 1].
n(logical([1 0 1])) returns[1 3]`.
sum(n(rem([1 2 3], 2) == 1)) returns sum of [1 3].
I have a binary vector, if I find a 0 in the vector I want to make the adjacent elements 0 if they are not already.
For example if input = [1 1 0 1 1] I want to get output = [1 0 0 0 1]
I tried the following but it's messy and surely there is a neater way:
output=input;
for i = 1:length(input)
if(input(i) == 0)
output(i-1)=0;
output(i+1)=0;
end
end
In = [1, 1, 0, 1, 1]; % note that input is a MATLAB function already and thus a bad choice for a variable name
Find the zeros:
ind_zeros = ~In; % or In == 0 if you want to be more explicit
now find the indicies before and after
ind_zeros_dilated = ind_zeros | [ind_zeros(2:end), false] | [false, ind_zeros(1:end-1)]
Finally set the neighbours to zero:
Out = In;
Out(ind_zeros_dilated) = 0
For fun, an alternative way to calculate ind_zeros_dilated is to use convolution:
ind_zeros_dilated = conv(ind_zeros*1, [1,1,1],'same') > 0 %// the `*1` is just a lazy way to cast the logical vector ind_zeros to be of type float
I have a symbolic vector y which I know contains linear expressions of the variables contained in a symbolic vector theta. Is there a way to compute the symbolic expression of A, where y = A * theta? I tried y*pinv(theta) but it doesn't seem to work.
Example:
syms a b real
theta = [a;b];
y = [2*a;2*b];
y*pinv(theta) gives
ans = [ (2*a^2)/(a^2 + b^2), (2*a*b)/(a^2 + b^2)]
[ (2*a*b)/(a^2 + b^2), (2*b^2)/(a^2 + b^2)]
and
y/theta gives
ans = [ 2, 0]
[ (2*b)/a, 0]
along with a warning that the solution is not unique.
I want to eradicate the symbolic variables from my result i.e. I want
ans = [ 2, 0]
[ 0, 2]
The equationsToMatrix function seems to be doing the job!
Try equationsToMatrix(y,theta)
When using equationsToMatrix you solve a set of linear equations as in the example (the solution is included)
syms x y z;
[A, b] = equationsToMatrix([x + y - 2*z == 0, x + y + z == 1, 2*y - z + 5 == 0], [x, y, z])
%solution of the equation set
A =
[ 1, 1, -2]
[ 1, 1, 1]
[ 0, 2, -1]
b =
0
1
-5
The vector b returns the values of the variables at issue: x,y, and z. However if I type x then MATLAB returns x and not 0, which is the solution of the equation in this case. This also occurs without adding the syms option.
The other problem is that if I type b(1) or b(2), I don't get any value: I would expect b to contain the values of x,y and z.
What I would need is to get something like this in the end
b(1) = 0
or
x = 0
What should I do to get the values of x,y,z by just typing x,y,z?
What you have is a way of converting symbolic linear equations into a numeric system by extracting the coefficient matrices. To solve the system you need to do
sol = A\b;
and now you can use the values in another expression with
subst(expr, {x,y,z}, {sol(1),sol(2),sol(3));
for example
A =
1 1 -2
1 1 1
0 2 -1
b =
0
1
-5
>> A\b
ans =
3.0000
-2.3333
0.3333