About symbolic MATLAB - matlab

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).

Related

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.

Using fzero to solve eqn in MatLab

I hope this is the right area. I'm trying to get this code to work in MatLab.
function y=test(x)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
I then jump to the command value and type this:
B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;
I then try to find the zeros of the first equation by typing this and I get errors:
solution=fzero(#test,5000000)
I'm getting the following error:
Error: File: test.m Line: 5 Column: 1 This statement is not
inside any function. (It follows the END that terminates the
definition of the function "test".)
New error
Error using fzero (line 289)
FZERO cannot continue because user supplied function_handle ==> #(x)
(test(x,B,b,a,r,p))
failed with the error below.
Subscript indices must either be real positive integers or logicals.
I would guess that this is a problem of scoping, you are defining variables (B, b, etc...) in the command line but trying to use them inside your test function where they are out of scope. You should alter your test function to take these in as parameters and then use an anonymous function so that your call to test in fsolve still only takes a single parameter:
function y=test(x, B, b, r, a, p)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
and
B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;
solution=fzero(#(x)(test(x,B,b,a,r,p)),5000000)
As an aside, unless you really do mean matrix multiplication, I would suggest that you replace all your *s and /s in test with the element-wise operators .* and ./. If you are dealing with scalars, it doesn't matter now, but it makes a big difference if you later want to scale your project and need a vectorized solution.
Regarding the errors you have added to your question:
You can't put code after the end in your function file. (With the exception of local functions). Your objective function should be an .m-file containing the code for one single function.
This is because in your test function you have ...b((1-(b/x)^(B-1))... which in MATLAB means you are trying to index the variable b in which case the value of (1-(b/x)^(B-1) has to be a positive integer. I'm guess you are missing a *
Your
function y=test(x)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
cannot access variables in your workspace. You need to pass the values in somehow. You could do something like:
function y=test(x,B,b,a,r,p)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
and then you can create an implicit wrapper function:
B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;
solution = fzero(#(x) test(x,B,b,a,r,p),5000000)
I haven't tested whether fzero returns sensible results, but this code shouldn't give an error.

??? Input argument "x" is undefined

I enter:
EDU>> %using the temporary variable levels
EDU>> levels=range/quantise_range;
levels=round(levels);
quantisation_bits=log2(levels)
NB. There is no x variable anywhere
My error is:
??? Input argument "x" is undefined.
Error in ==> range at 18
y = max(x) - min(x);
EDU>> %combining above process into one statement
quantisation_bits=log2(round(range/quantise_range));
??? Input argument "x" is undefined.
Error in ==> range at 18
y = max(x) - min(x);
Would someone care to explain thie issue? I am beginner into programming and I really don't understand how to read the error hint.
Thanks.
Additionally, in what may be due to whatever the same principle misunderstanding on my part is, I am finding trouble here with this code, with error also included:
%Trying to create my own function, I’m pressing shift+enter at the end of lines for neatness:
EDU>> function what_am_i()
disp 'I am a function'
??? function what_am_i()
|
Error: Function definitions are not
permitted in this context.
EDU>>
function what_am_i()
disp' I am a function'
??? function what_am_i()
|
Error: Function definitions are not
permitted in this context.
EDU>> end
??? end
|
Error: Illegal use of reserved keyword
"end".
You may be confusing the "Command Window" with the "Editor".
In the "Command Window" you can enter some lines of code, but can't create functions. It acts more like a calculator.
If you create and save files, then you open them in the "Editor" and that's when Matlab begins behaving more like a programming language. It saves .m files that can have functions or algorithms written in them.
Matlab has lots of help available. I recommend visiting their website and searching around a bit. (or just google "intro to matlab")
In addition to #user1860611's answer regarding function definitions in the command window, the other problem you have has to do with range, which is a built-in function. It appears you are trying to use range it as a variable name, but didn't actually initialize it to a value, so it is still a function.
In the line here:
levels=range/quantise_range;
you are essentially calling the range function, but without passing it an argument.
Error in ==> range at 18
y = max(x) - min(x);
The error message is telling you that a function called range has generated an error. It doesn't matter that you don't have a variable named x, because the function has one internally.

Using MATLAB svmtrain

This is my first Matlab program.
I'm trying to use svmtrain and svmclassify with custom kernel.
Assume my kernel is regular inner product.
How should I write it?
I did:
function [K] = mykernel(U, V)
for i=size(U,1)
for j=size(V,1)
K(i,j) = dot(U(i,:),V(j,:));
end
end
return
end
and then in the command window:
x=randn(1000,10);
w=rand(1,10);
y=sign(x*w');
a=svmtrain(x,y,'kernel_function',mykernel);
and I get:
Error using mykernel (line 2)
Not enough input arguments.
Maybe one has a trick to do it without loops, something like U*V', it'll be nice to know this
trick, but i need to do it in loop, since i'm going to change the inner product to some more complicated stuff.
I also didn't really understand what are those U,V, and I didn't really get what this function
should return (is it the Gram matrix?)
Thanks for your help!!
--- EDIT:
I did the following:
function [K] = mink(U, V)
for i=1:size(U,1)
for j=1:size(V,1)
K(i,j) = min(exp(-dot(U(i,:),U(j,:))),exp(-dot(V(i,:),V(j,:))));
end
end
return
end
>>x=randn(100,10);
>>w=rand(1,10);
>>y=sign(x*w');
>>a=svmtrain(x,y,'kernel_function',#mink);
>>svmclassify(a, x)
Error using svmclassify (line 114)
An error was encountered during classification.
Attempted to access U(89,:); index out of bounds because size(U)=[88,10].
so now svmtrain works but svmclassify complains about size mismath (how did it get 88??)
In order to pass a function, you need to use the # symbol. This is shown in the docs, which quote:
#kfun — Function handle to a kernel function. A kernel function must be of the form
Bottom line, this will work.
a=svmtrain(x,y,'kernel_function',#mykernel);