I have a code that I used to run without any problem in MATLAB 2012.
But when I switched to MATLAB 2013 my code doesn't work anymore and I get the following error:
CHOLINC has been removed. Use ICHOL instead.
I'm using this line of code which is in cvx package and specifically in quad_form.m file:
[ R, p ] = chol( Q );
And so I'm wondering how can I replace chol by ichol.
First of all you should read the documentation, it can be found by typing help ichol or doc ichol. Here is a copy as well: http://www.mathworks.nl/help/matlab/ref/ichol.html
I am not 100% sure, but my first try would be to check whether changing chol to ichol will do the trick.
If the problem is that the function call is made in code that you cannot alter, then (after you figure out what the call should be) you can create your own chol function that calls ichol.
As #Dan suggested, matlab's chol is probably being "overridden" by a user- or toolbox-defined chol which internally calls cholinc (now ichol).
But more importantly, you should understand what is going on in your problem. Cholesky facotrizations (chol) only work if your matrix Q is Hermitian and positive-semidefinite.
Probably, somebody wrote their own chol which attempts a Cholesky factorization, and if it fails, does an incomplete Cholesky factorization (ichol / cholinc) instead.
You could just implement that yourself, e.g. assuming the matrix Q is real-valued:
%untested.
R = [];
p = [];
if Q==Q' && all(eig(Q) >= 0)
[R,p] = chol(Q);
else
[R,p] = ichol(Q);
end
addition
You may want to use try & catch instead of if & else, if you want to be completely sure that no hidden warnings/error messages cause your program to bail.
edit
Changed condition on Q to actually checking for positive semi-definiteness. Thanks for pointing that out #woodchips.
Related
The following command
syms x real;
f = #(x) log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);
and
solve(fpp(x)>0,x,'Real',true)
return the result
solve([0.0 < (8.0*exp(-1.0/x^2))/x^4 - (2.0*exp(-1.0/x^2))/x^2 -
(6.0*log(x^2)*exp(-1.0/x^2))/x^4 + (4.0*log(x^2)*exp(-1.0/x^2))/x^6],
[x == RD_NINF..RD_INF])
which is not what I expect.
The first question: Is it possible to force Matlab's solve to return the set of all solutions?
(This is related to this question.) Moreover, when I try to solve the equation
solve(fpp(x)==0,x,'Real',true)
which returns
ans =
-1.5056100417680902125994180096313
I am not satisfied since all solutions are not returned (they are approximately -1.5056, 1.5056, -0.5663 and 0.5663 obtained from WolframAlpha).
I know that vpasolve with some initial guess can handle this. But, I have no idea how I can generally find initial guessed values to obtain all solutions, which is my second question.
Other solutions or suggestions for solving these problems are welcomed.
As I indicated in my comment above, sym/solve is primarily meant to solve for analytic solutions of equations. When this fails, it tries to find a numeric solution. Some equations can have an infinite number of numeric solutions (e.g., periodic equations), and thus, as per the documentation: "The numeric solver does not try to find all numeric solutions for [the] equation. Instead, it returns only the first solution that it finds."
However, one can access the features of MuPAD from within Matlab. MuPAD's numeric::solve function has several additional capabilities. In particular is the 'AllRealRoots' option. In your case:
syms x real;
f = #(x)log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);
s = feval(symengine,'numeric::solve',fpp(x)==0,x,'AllRealRoots')
which returns
s =
[ -1.5056102995536617698689500437312, -0.56633904710786569620564475006904, 0.56633904710786569620564475006904, 1.5056102995536617698689500437312]
as well as a warning message.
My answer to this question provides other way that various MuPAD solvers can be used, particularly if you can isolate and bracket your roots.
The above is not going to directly help with your inequalities other than telling you where the function changes sign. For those you could try:
s = feval(symengine,'solve',fpp(x)>0,x,'Real')
which returns
s =
(Dom::Interval(0, Inf) union Dom::Interval(-Inf, 0)) intersect solve(0 < 2*log(x^2) - 3*x^2*log(x^2) + 4*x^2 - x^4, x, Real)
Try plotting this function along with fpp.
While this is not a bug per se, The MathWorks still might be interested in this difference in behavior and poor performance of sym/solve (and the underlying symobj::solvefull) relative to MuPAD's solve. File a bug report if you like. For the life of me I don't understand why they can't better unify these parts of Matlab. The separation makes not sense from the perspective of a user.
In my project I need a function which returns the index of the largest element of a given vector. Just like max. For more than one entry with the same maximum value (which occurs frequently) the function should choose one randomly. Unlike max.
The function is a subfunction in a MATLAB Function Block in Simulink. And the whole Simulink model is compiled.
My basic idea was:
function ind = findOpt(vector)
index_max = find(vector == max(vector));
random = randi([1,length(index_max)],1);
ind = index_max(random);
end
But I got problems with the comparison in find and with randi.
I found out about safe comparison here: Problem using the find function in MATLAB. Also I found a way to replace randi([1,imax],1): Implement 'randi' using 'rand' in MATLAB.
My Code now looks like this:
function ind = findOpt(vector)
tolerance = 0.00001;
index_max = find(abs(vector - max(vector)) < tolerance);
random = ceil(length(index_max)*rand(1));
ind = index_max(random);
end
Still doesn't work. I understand that the length of index_max is unclear and causes problems. But I can not think of any way to know it before. Any ideas how to solve this?
Also, I'm shocked that ceil doesn't work when the code gets executed?? In debug mode there is no change to the input visible.
I thought about creating an array like: index_max = abs(vector - max(vector)) < tolerance; But not sure how that could help. Also, it doesn't solve my problem with the random selection.
Hopefully somebody has more ideas or at least could give me some hints!
I am using MATLAB R2012b (32bit) on a Windows7-64bit PC, with the Lcc-win32 C 2.4.1 compiler.
Edit:
Vector usually is of size 5x1 and contains values between -2000 and zero which are of type double, e.g. vector = [-1000 -1200 -1000 -1100 -1550]'. But I think such a simple function should work with any kind of input vector.
The call of length(index_max) causes an system error in MATLAB and forces me to shut it down. I guess this is due to the strange return I get from find. For a vector with all the same values the return from find is something like [1.000 2.000 1.000 2.000 0.000]' which doesn't make any sense to me at all.
function v= findOpt(v)
if isempty(v)
return;
end
v = find((max(v) - v) < 0.00001);
v = v(ceil(rand(1)*end));
end
I was indeed overloading, just like user664303 suggested! Since I can not use objects in my project, I wanted an function that behaves similar, so I wrote:
function varargout = table(mode, varargin)
persistent table;
if isempty(table) && ~strcmp(mode,'writeTable')
error(...)
end
switch mode
case 'getValue'
...
case 'writeTable'
table = ...
...
end
end
Wanted to avoid passing the dimensions for the table in every call and thought it would be enough if the first call initializes the Table with mode='writeTable'. Looks like this caused my problem.
No problems after changing to:
if isempty(table)
table = zeros(dim1,dim2,...)
end
I'm having a problem trying to use YALMIP; I suspect I'm doing something silly and I would greatly appreciate if someone pointed out what it is.
I'm trying to solve some SDPs. When I don't define an objective, YALMIP returns a solution (implying that the problem is feasible). However, when I attach an objective to it, YALMIP returns that the problem is infeasible, which has left me a bit perplexed.
Here's the code for the simplest SDP I could cook up in which the above happens. Declaring the variables and setting the constraints is as follows:
y = sdpvar(6,1);
M = sdpvar(3,3);
C = [0,0,0,0,0,0; 0,0,0,0,0,0; -2,0,1.8,0,2,1; 0,0,0,0,0,0; 1,0,-1,0,-1.2,0;
0,0,0,0,0,0;];
F = [C*y==0, y(6) == 1, M>=0];
F = [F,M(1,1) == y(1), M(2,1) == y(2), M(3,1) == y(3),...
M(2,2) == y(4), M(3,2) == y(5), M(3,3) == y(6)];
Now if I merely ask YALMIP to find a feasible solution with
solvesdp(F)
it returns
info: 'Successfully solved (LMILAB)'
problem: 0
and some feasible M and y (I've checked that they indeed are). However, if I append the objective "minimise y(3)" (or indeed any linear combination of the entries of y) with
solvesdp(F,y(3))
it returns that the problem is infeasible:
info: 'Infeasible problem (LMILAB)'
problem: 1
and y and M are full of "NaN" tokens.
Many thanks in advance.
LMILAB should not be used together with YALMIP.
http://users.isy.liu.se/johanl/yalmip/pmwiki.php?n=Solvers.LMILAB
The solver in LMILAB has many deficiencies, and one which becomes crucial here is the fact that the solver lacks support for inequalities. To circumvent this, YALMIP adds double-sided inequalities, which completely destroys the numerical procedures of LMILAB.
Install a more general (and modern) solver such as SeDuMi, SDPT3, or Mosek
http://users.isy.liu.se/johanl/yalmip/pmwiki.php?n=Category.SemidefiniteProgrammingSolver
BTW, you are redundantly defining additional variables y. No reason to have them as separate decision variables and then encode how they relate to M. Simply extract them
y = M(find(tril(ones(3))));
I am using MATLAB's PCG subroutine to solve a system of linear equations. However, I don't want it to solve exactly. I want it to run for only 20 iterations and if it doesn't converge, I want it to return the value at the 20th iteration.
What MATLAB (My version is the latest one) is doing however is returning a zero vector if it doesn't find an acceptable solution by 20 iterations. Is there any way to override this without changing the source code of pcg.m?
I have a code which I wrote which does that (I just copied from Wikipedia) but obviously, it is not close to how robust MATLAB's version is.
function [x] = conjgrad(A,b,x)
r=b-A*x;
p=r;
rsold=r'*r;
for i=1:20
Ap=A*p;
alpha=rsold/(p'*Ap);
x=x+alpha*p;
r=r-alpha*Ap;
rsnew=r'*r;
if sqrt(rsnew)<1e-10
break;
end
p=r+rsnew/rsold*p;
rsold=rsnew;
end
This link shows that there is a kronecker delta function in matlab. However:
>> help kroneckerDelta
kroneckerDelta not found
I am using R2011b, so maybe this wasn't programmed into the toolkit yet?
EDIT:: It works in MuPad, just not in matlab...
.
The Kronecker delta returns 1 if j==k...
So you could simplify the expression with:
function d=kronDel(j,k)
d=j==k
end
Luckily, MATLAB represents booleans as (0,1)
I don't see it in my R2012b so perhaps not. Unless you need the symbolic math, you could always write your own. Something as simple as
function d = kronDel(j,k)
if j == k
d = 1;
else
d = 0;
end
You can also do this inline, like
( a == b )
However, using an anonymous function is a nice way to convert a one liner like this into something that is more readable
kronDel = #(j, k) j==k ;
kronDel( 2, 1 )
kronDel( 2, 2 )
Your link to is to the MuPAD function kroneckerDelta -note the URL and the funky typography of the examples. You won't see it in any version of Matlab because it's only available through MuPAD (type mupad in your command window and try in the window that launches). I have no idea when it was added to MuPAD, I know that it's at least in R2012b. You may have it even if the help command returns nothing.
If you have kroneckerDelta in R2011b, you won't be able to run it from the regular command window or Editor in the normal fashion.
evalin(symengine,'kroneckerDelta(1,1)')
or the more flexible
feval(symengine,'kroneckerDelta',1,1)
See more here. However, if you're not working with symbolic math, there's really no reason to use this function that I can see -it's not even vectorized! I'd go with a solution that fully emulates kroneckerDelta's behavior in double precision:
function d=kronDel(m,n)
if nargin == 1
d = double(m==0);
else
d = double(m==n);
end