Error using fmincon, hack fixes it but I'm uneasy about it - matlab

I'm having a strange error when using fmincon. The details about the objective function and the nonlinear constraint functions are many, so I'm going to try to ask this question without describing those if possible.
The minimization requires a single input. For some but not all inputs, I get the following error:
Subscript indices must either be real positive integers or logicals.
Error in qpsub>eqnsolv (line 888)
ACTSET = A(ACTIND,:);
Error in qpsub (line 157)
[Q,R,A,B,X,Z,how,ACTSET,ACTIND,ACTCNT,aix,eqix,neqcstr,ncstr, ...
Error in nlconst (line 619)
[SD,lambda,exitflagqp,outputqp,howqp,ACTIND] ...
Error in fmincon (line 794)
[X,FVAL,LAMBDA,EXITFLAG,OUTPUT,GRAD,HESSIAN]=...
Error in PauliApproximate2.unitalChannelApproximate (line 170)
[pc, distance] = fmincon(#objective,x0, A, b, Aeq, beq,lb,ub, #constraint,
options);
When I check to see the value of ACTIND, the error is thrown when it equals [0], hence the indexing error. Similar to the hack that the OP of this thread used, before the line (in qpsub)
ACTSET = A(ACTIND,:);
I put the if statement:
if max(ACTIND) < 1
ACTIND = [1];
end
From preliminary testing this seems to "Fix" the problem. It is giving sensible results for inputs that used to throw the error (in that it is returning a good minimum value and the constraints are satisfied to within tolerance), and is returning the same results it always did for inputs that didn't have the error (obviously, as the if statement won't be invoked). So my question is, for people that know the inner workings of these functions, how bad is this? Am I sidestepping a horrible issue that results in ACTIND being [0] that I shouldn't be?

Related

"Too Many Input Arguments" [duplicate]

This question already exists:
Error using symengine>#()0.0 Too many input arguments
Closed 3 years ago.
Exact error is:
Error using symengine>#()0.0
Too many input arguments.
Error in bdipuniodefun (line 18)
bdip = [s(4); s(5); s(6); (q/m_e)*(Ex(s(1),s(2),s(3)) + s(5)*Bz(s(1),s(2),s(3)) - s(6)*By(s(1),s(2),s(3))); (q/m_e)*(Ey(s(1),s(2),s(3)) +
s(6)*Bx(s(1),s(2),s(3)) - s(4)*Bz(s(1),s(2),s(3))); (q/m_e)*(Ez(s(1),s(2),s(3)) + s(4)*By(s(1),s(2),s(3)) - s(5)*Bx(s(1),s(2),s(3)))];
Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode15s (line 150)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in collisions6 (line 219)
[T,S] = ode15s(#bdipuniodefun, tspan, icv);
So we know where the error occurs, but I have been unable to resolve it nonetheless. This is an error that has also been inconsistent too. It does not always appear when I run the main script "collisions.m" but happens only when certain things get altered. Some examples: I start with too many electrons/particles, usually 1000+. Or I try to input a non-zero electric field. The electric field function is still being referenced but it is zero (Here comes the strange part). The reason I did this is because although the error goes away, the ode solver does not compute even close to the correct solutions I am looking for. I know for a fact that the results are wrong due to my knowledge of physics. However, when it does this, it does not give an error.
A Matlab staff member suggested that it may have something to due with my persistent variable definition but that is the only possible lead I have.
Troubleshooting methods I have already been through:
First if you look at the documentation from Matlab, it shows a specific syntax example to define the set of ODEs. In Matlab's syntax, they define each equation individually and then the vector of equations using the definitions. When I tried this syntax, the solver either did not solve the equations correctly, or it gave me the "too many input arguments" error. The way I made it run at all was to define every equation outright on a single line in "bdipodefun.m". Only that syntax worked and there is no good reason in my mind why this is the case because the definition that is used in one of the input arguments for the solver is the same. Using the Matlab recommended syntax even in simpler code, makes the ode solution incorrect.
I tried all ode solvers Matlab has to offer. The same issues persist or it cannot solve the equations at all.
I tried re-coding the entire simulation from scratch. I have found that this error still occurs even in more simpler codes.
Equation solver will also not solve the system correctly if there is no E-field. I found that if I create an E-field function and even just define it as zero within the file, the system solves correctly. It absolutely makes no sense as to why this is occurring.
Here is a description of what each file does in the code:
"collisionsmain.m" = Main script that references other files
"B_test.m" = B field function file referenced by collisionsmain
"E_test.m" = E field function file referenced by collisionsmain
"engen.m" = Generates energies for electrons based on a Maxwellian probability distribution curve
"maxdis.m" = Maxwellian distribution function used by engen
"engen.m" = Generates energies for electrons based on a Maxwellian
"posgen.m" = Generates a random, initial position on a sphere "bdipodefun.m" = ODE function set referenced by ODE solver in collisionsmain
Link to files: https://drive.google.com/drive/folders/19eJrgWYL4LQFwTY-VwguCCkta-pimZlL?usp=sharing
I didn't understand the code because it is complicated and big. Anyway, I tracked the error and find the source of the issue. The error comes from the number of parameters that have been sent to Ex, Ey, Ez in bdipuniodefun.m function. Ex, Ey, Ez functions receives 3 parameters while they can handle one parameter only.
The following code didn't send error and it shows the results.
bdip_r1 = [s(4); s(5); s(6)];
bdip_r2 = (q/m_e) * (Ex(s(1)) + s(5)*Bz(s(1),s(2),s(3))- s(6)*By(s(1),s(2),s(3)));
bdip_r3 = (q/m_e)*(Ey(s(1)) + s(6)*Bx(s(1),s(2),s(3)) - s(4)*Bz(s(1),s(2),s(3)));
bdip_r4 = (q/m_e)*(Ez(s(1)) + s(4)*By(s(1),s(2),s(3)) - s(5)*Bx(s(1),s(2),s(3)));
bdip =[bdip_r1;bdip_r2;bdip_r3;bdip_r4];

Error using strcmp within fittype

I just received a script from a colleague whose first line is this:
VonMisesModel=fittype(#(A,k,base,peakloc,x) (base + A*exp(k*cos((pi/180)*(x-peakloc)))/(2*besseli(0,k)*pi)),'independent','x');
He's done a good deal of processing with this script, so I'd imagine this line of code works for him.
However, when I call it, I get the following error:
>> VonMisesModel=fittype(#(A,k,base,peakloc,x) (base + A*exp(k*cos((pi/180)*(x-peakloc)))/(2*besseli(0,k)*pi)),'independent','x');
Error using strcmp
The number of rows of the string matrix must match the number of elements in the cell.
Error in cell/ismember (line 38)
match = strcmp(a,b);
Error in fittype>iTestAnonymousFunctionArgumentOrder (line 786)
[~, coefficientLocations] = ismember( obj.coeff, arguments );
Error in fittype>iCreateFromAnonymousFunction (line 533)
iTestAnonymousFunctionArgumentOrder( obj, theFcn )
Error in fittype>iCreateFittype (line 355)
obj = iCreateFromAnonymousFunction( obj, varargin{:} );
Error in fittype (line 328)
obj = iCreateFittype( obj, varargin{:} );
I'd like to reiterate that this is the first line in a stand-alone script. No processing is meant to occur before this line is called.
The error does not seem intuitive to me at all. My guesses at what might have caused it have not turned up a solution. Does anyone know why this error was raised?
Edit
The definition of the fittype function appears to have changed over time.
The error in the question is raised when I use versions of Matlab newer than matlab-2012a.
However, the error is not raised when I use matlab-2012a.
My pre-2012 matlab distributions do not contain the function fittype at all.
In order for other functions in this script to work, I need to get this call to fittype to work with new(er) versions of Matlab. If you can, please let me know how to rearrange the call to prevent the error.

MatLab GUI Troubles: Calculating an Integral

I have created a matlab GUI in which a user selects a variable to integrate with respect to, inputs the equation, and lower and upper limits. When my code goes to calculate the integral on pushbutton Callback, I get an error I don't understand.
This is the line of code causing the error:
i1 = int( eval(get(handles.edit1,'string')),
(handles.respectvar),
get(handles.edit3),
get(handles.edit2)
);
%respactvar is the user-selected variable, and edit3 and edit2 are the lower and upper limits.
And this is the error message:
Error using sym>tomupad (line 1135)
Conversion to 'sym' from 'struct' is not possible.
Error in sym (line 151)
S.s = tomupad(x);
Error in sym/int (line 142)
b = sym(b);
Error in projectCALC>pushbutton1_Callback (line 376)
i1=int(eval(get(handles.edit1,'string')),(handles.respectvar),get(handles.edit3),get(handles.edit2));
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in projectCALC (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in #(hObject,eventdata)projectCALC('pushbutton1_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
Thank you!
There are multiple problems with your code.
The first problem, as #excaza noted, is that you forgot to get the string property of the last two edit boxes, while you did this for the first one.
The second problem is that eval is very inefficient, and, in your case, very unsafe. What if somebody wrote a system() call into the editbox, erasing your hard drive?
The third problem is that even with eval or str2func, int requires its first argument to be a symbolic expression. This is a good thing: you don't actually have to use eval, you just have to convert your first string to a sym.
The fourth problem is that handles.respectvar also seems to be a GUI object, so you might need to get() some property for it in order to be able to use it as an integration variable.
Assuming that my suspicion is correct, and your edit1 contains a string like '3*x+y', edit2 and edit3 are limits such as '1' and '3', and handles.respectvar has a property that evaluates to 'x', then you should be calling
formula = sym(get(handles.edit1,'string'));
variable = handles.respectvar; %// more likely: get(handles.respectvar,...)
lim1 = str2double(get(handles.edit3,'string'));
lim2 = str2double(get(handles.edit2,'string'));
i1 = int(formula,variable,lim1,lim2);
A few notes:
Don't be afraid of using temporary variables where it helps in readability.
I converted the formula from sym to string, otherwise you get a warning or an error (depending on MATLAB version)
I left the order of lim1 <-> edit3, lim2 <-> edit2. Make sure this is indeed what you want, and orders are not reversed.
I converted the integration limits to double, but it seems that sym/int will also accept string input as the limit variables, so this is mostly for clarity.

Bug in Matlab implementation of Porter Stemmer

I use the Matlab implementation of the Porter Stemming algorithm published here. When I use it on a large portion of text, I get an error message when the string "ies" is passed in.
>> porterStemmer('ies')
I get the error message:
Subscript indices must either be real positive integers or
logicals.
Error in porterStemmer>step2 (line 274)
switch b(k-1)
Error in porterStemmer (line 42)
x = step2(x{1}, x{2}, k0);
I suppose it might be, because "ies"is a common word ending and also appears in the script on line 223 as elseif ends('ies', b, k).
I was expecting the program to be robust to cases like this. Was I wrong to think that or this is a bug?
For the time being, I've resorted to using the Porter Stemmer 2 (here), which doesn't throw an error and stems "ies" to "ie". Stemming "ies" is a bit pointless obviously, but I'd rather not have it throw errors in edge cases like this.

getting complex-valued Jacobian Matrix using NonLinearModel.fit in matlab

I am trying to use the NonLinearModel.fit() function in Matlab to regress two variables. However, I am getting the following error:
Error using internal.stats.getscheffeparam>ValidateParameters
(line 182)
If non-empty, JW must be a numeric, real matrix.
Error in internal.stats.getscheffeparam (line 110)
[J,VF,VP,JW,Intopt,TolSVD,TolE,VQ,usingJ] =
ValidateParameters(J,VF,VP,JW,Intopt,TolSVD,TolE,VQ,allowedIntopt);
Error in nlinfit (line 340)
sch =
internal.stats.getscheffeparam('WeightedJacobian',J(~nans,:),'Intopt','observation','VQ',VQ);
Error in NonLinearModel/fitter (line 1121)
[model.Coefs,~,J_r,model.CoefficientCovariance,model.MSE,model.ErrorModelInfo,~]
= ...
Error in classreg.regr.FitObject/doFit (line 219)
model = fitter(model);
Error in NonLinearModel.fit (line 1484)
model = doFit(model);
Error in getMatrix (line 101)
nlm =
NonLinearModel.fit(regressorMatrix',temp2',modelfun,beta0);
My regressorMatrix is 2-by-N (so the transpose is N-by-2), temp2' is N-by-1, and beta0 and model are given by:
model =#(b,x)b(1).*x(:,1).*x(:,2).^b(2);
beta0=[.14 .6];
nlm = NonLinearModel.fit(regressorMatrix',temp2',model,beta0);
Could someone please help me in figuring out what is causing this error?
EDIT: ok, no help so far so I will try to be more specific. I know that this error is referring to the weighted Jacobian matrix. I am just not sure why this Jacobian would not be real-valued.
Here are the first few rows of my regressor matrix:
regressorMatrix =
1.0e+07 *
0.000000000776613 3.762601240855837
0.000000001683014 3.762601240855837
0.000000001496807 3.762601240855837
0.000000000753495 3.762601240855837
and my response matrix:
temp2 =
-0.011811061934317
0.987582922964869
0.010621342764736
0.135001167018444
0.091950680609212
I can see that something is wrong here (the orders of magnitude in col2 of my regressor matrix are off. I will fix this and get back with an explanation if it turns out to the the cause. I am also working on printing out J. and JW
EDIT2:
I was able to print out JW before the error occurs and discovered that JW is a Nx2 complex matrix. So the specific reason the error is occurring is that the weighted Jacobian matrix is not real valued. Not sure why...
After a lot of digging, I found that the answer to this problem is quite obvious. I didn't realize that some of the values for one of my regressor variables was going negative sometimes. This lead (jumping a few steps ahead) to a complex Jacobian.