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.
Related
What is wrong with the following code?
clear all
syms x y a ;
u=2*x*y;
v=a^2+x^2-y^2;
diff=diff(u,'x',1)+diff(v,'y',1);
if diff==0
disp('Liquid motion is possible.')
disp('Stream function exists.')
else
disp('Liquid motion is not possible.')
disp('Stream function does not exist.')
end
diff2=diff(v,'x',1)-diff(u,'y',1);
if diff2==0
disp('Velocity potential exists.')
else
disp('Velocity potential does not exist.')
end
This comes in the command window when I run the above.
Liquid motion is possible.
Stream function exists.
Error using sym/subsindex (line 672)
Invalid indexing or function definition. When defining a function, ensure that the body of the function is a SYM
object. When indexing, the input must be numeric, logical or ':'.
Error in sym>privformat (line 1502)
x = subsindex(x)+1;
Error in sym/subsref (line 694)
[inds{k},refs{k}] = privformat(inds{k});
Error in q7 (line 17)
diff2=diff(v,'x',1)-diff(u,'y',1);
But if I rewrite(redefine) the symbolic variables after the first if construct, it runs fine. Also if I cancel the first if construct, it runs.
I would avoid to overwrite a reserved name, so instead of
diff=diff(u,'x',1)+diff(v,'y',1);
I would suggest
derFcn = diff(u,'x',1)+diff(v,'y',1);
This triggers the second error;
diff2=diff(v,'x',1)-diff(u,'y',1);
at this point diff is your diff value (which, incidentally is 0) so it is equivalent to write
0(v,'x',1)
which, of course, will not compile and it is not what you meant.
So, please, make the substitution (and update your if statements accordingly).
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.
Today I tried to run a MATLAB m-file that someone gave me. It works fine for him, but I encountered a warning and errors (below). I am using a Mac with OS X Yosemite (10.10.5) and a new version of MATLAB (R2015b). The person who prepared the m-file would have used an older one and Windows.
From a blog at Mathworks and posts online/here, the error seems to be due to a MATLAB update--a change from using numeric values to point towards graphics objects to using objects themselves. I understand this in theory, but don't know how to fix my code (it has been years since I used MATLAB regularly, so I'm pretty lost).
Warning: Text handle output is not supported when a contour handle
argument is supplied and label placement is automatic.
In clabel (line 214)
In control_volume_20150706>plot_xxx (line 733)
In control_volume_20150706 (line 104)
In run (line 96)
Error using sprintf
Function is not defined for
'matlab.graphics.GraphicsPlaceholder' inputs.
Error in control_volume_20150706>plot_xxx (line 734)
sprintf('%10.4f \n',text_handle);
Error in control_volume_20150706 (line 104) plot_xxx (nr,
xwidevec, yhighvec, omegamat, psimat, umat, vmat, ...
Error in run (line 96) evalin('caller', [script ';']);
This is what the code looks like in the vicinity of line 733:
Line 731 contourlevels = omegamat(1, :) ;
Line 732 [C,h] = contour(X,
Y, flipud(omegamat), contourlevels, 'LineWidth', 2 );
Line 733
text_handle = clabel(C,h);
Line 734 sprintf('%10.4f \n',text_handle);
I would be very grateful for any hints about how to deal with this.
If h is a handle which refers to some object, then in R2015a and later this is the object itself, while in previous versions it's a double which points to an object (as you noted in the question). You can use h.double in R2015a and later to get what would previously be h. E.g., pre-R2015a h = figure(999) would set h to 999, a double; with R2015a and later h is an object and h.double is 999.
I am trying to make my own function in matlab to solve for a system of two nonlinear equations, while using a nested function to share some some parameters, here is a sample code:
function y=solve(a,x0)
a;
y=fsolve(nle,x0); % this is line 3
function f=nle(x)
f(1)=x(1)-a*x(1)^2-x(1)*x(2); % this is line 6
f(2)=2*x(2)-x(2)+3*x(1)*x(2);
end
end
Here a is the parameter I want to pass from command line to the function, and x0 is the start point for the fsolve.
However, when I call the function in malab after specifying a=4 and x0=[1 1]', it gave me the following error:
Error using solve/nle (line 6)
Not enough input arguments.
Error in solve (line 3)
y=fsolve(nle,x0);
I'm quite a newbie for matlab, can anybody tell me where I am doing wrong?
Thanks in advance.
EDIT:
I tried substituting the nle with a function handle #nle, but seems something else went wrong:
Undefined function 'fsolve' for input arguments of type 'function_handle'.
Error in solve (line 3)
y=fsolve(#nle,x0);
Doesn't seem to make sense since I checked the documentation for fsolve, and it says it should indeed use a function handle there...
You miss the '#' in front of nle, i.e.
y = fsolve(#nle,x0);
should work.
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?