matlabFunction, using symbolic variables and if statements

10 views (last 30 days)
Hello everybody,
I use the matlabFunction in order to generate a function handle which contains symbolic variables. My problem is that this function handle contains an if- statement, but when generating the function handle and executing it, it gives a wrong result (just 0 or 1 for true or false), is this a bug or what can I do about it?
My function looks like:
if true
% code
end
function [theta] = inverse_kin(l1,l2,pos)
nom = pos(1,:).^2 + pos(2,:).^2 - l1^2 - l2^2;
denom = 2*l1*l2;
theta2 = acos(nom./denom);
alpha = atan2(pos(2,:),pos(1,:));
alpha = (alpha + (alpha<0)*2*pi);
% I could also add an if statement instead like if alpha < 0 then ... else ... but this doesn't work either
nom = pos(1,:).^2 + pos(2,:).^2 + l1^2 - l2^2;
denom = 2*l1*sqrt(pos(1,:).^2 + pos(2,:).^2);
beta = acos(nom./denom);
theta1 = alpha - beta;
theta = [theta1; theta2];
end
pos is a symbolic, and after I do th_fnc = matlabFunction(inverse_kin);
But when executing th_fnc I get wrong results.
Thanks you and best Pascale

Accepted Answer

Bruno Pop-Stefanov
Bruno Pop-Stefanov on 6 Oct 2014
Hi Pascale,
The matlabFunction function should be used on a symbolic expression or function. For example:
syms x y
f = x^2 + y^2;
f is a symbolic function in the above.
I suppose that you are executing something like:
>> syms x y
>> pos = [x;y];
>> l1 = 1;
>> l2 = 1;
>> th_fnc = matlabFunction(inverse_kin(l1,l2,pos))
th_fnc =
@(x,y)[(angle(x+y.*1i)-acos(sqrt(x.^2+y.^2).*(1.0./2.0))+pi.*angle(x+y.*1i).*2.0<angle(x+y.*1i)-acos(sqrt(x.^2+y.^2).*(1.0./2.0)));acos(x.^2.*(1.0./2.0)+y.^2.*(1.0./2.0)-1.0)]
When I do the above and then try on very simple inputs, I get the same output:
1. Try the original function:
>> x = sym('2');
>> y = sym('2');
>> inverse_kin(1,1,[x;y])
ans =
pi/4 - acos(2^(1/2)) + pi^2/2 < pi/4 - acos(2^(1/2))
acos(3)
2. Try the generated symbolic function:
>> th_fnc(x,y)
ans =
pi/4 - acos(2^(1/2)) + pi^2/2 < pi/4 - acos(2^(1/2))
acos(3)
Therefore, can you give me an example for which you do not get the same output? What were you expecting to see?
You should make sure that the inputs to the symbolic function are symbolic as well. For example, th_fnc(2,2) is not the same as th_fnc(x,y) with x and y being symbolic variables containing the numeric value 2. You might see differences if the inputs are not symbolic. For example:
>> inverse_kin(1,1,[2;2])
ans =
0.7854 - 0.8814i
0.0000 + 1.7627i
>> th_fnc(2,2)
ans =
0.0000 + 0.0000i
0.0000 + 1.7627i
  3 Comments
Bruno Pop-Stefanov
Bruno Pop-Stefanov on 6 Oct 2014
The problem is coming from the < in the function. When converting it to an anonymous function, MATLAB is confused. I slightly changed the the inverse_kin function to show that.
If you write:
temp = alpha<0;
alpha(temp) = alpha(temp) + 2*pi;
This should rectify the alpha values so that they are between 0 and 2pi. However, this throws an error:
Unable to prove 'atan2(y, x) < 0' literally. To test the statement
mathematically, use isAlways.
Using the isAlways function solves the problem:
temp = isAlways(alpha<0);
alpha(temp) = alpha(temp) + 2*pi;
Then:
>> th_fnc2 = matlabFunction(inverse_kin(1,1,[x;y]))
th_fnc2 =
@(x,y)[angle(x+y.*1i)-acos(sqrt(x.^2+y.^2).*(1.0./2.0));acos(x.^2.*(1.0./2.0)+y.^2.*(1.0./2.0)-1.0)]
First, you can notice that there is no more logical expression in the symbolic function if you use symbolic inputs:
>> syms x y
>> th_fnc2(x,y)
ans =
atan2(y, x) - acos((x^2 + y^2)^(1/2)/2)
acos(x^2/2 + y^2/2 - 1)
Then, I tried with a few couples of values and it seems to be giving the same results:
>> th_fnc2(2,2)
ans =
0.7854 - 0.8814i
0.0000 + 1.7627i
>> inverse_kin(1,1,[2;2])
ans =
0.7854 - 0.8814i
0.0000 + 1.7627i
>> th_fnc2(1,1)
ans =
0
1.5708
>> inverse_kin(1,1,[1;1])
ans =
-0.0000
1.5708
>> th_fnc2(1,2)
ans =
1.1071 - 0.4812i
0.0000 + 0.9624i
>> inverse_kin(1,1,[1;2])
ans =
1.1071 - 0.4812i
0.0000 + 0.9624i
>> th_fnc2(1.5,2)
ans =
0.9273 - 0.6931i
0.0000 + 1.3863i
>> inverse_kin(1,1,[1.5;2])
ans =
0.9273 - 0.6931i
0.0000 + 1.3863i
Pascale
Pascale on 7 Oct 2014
Hi Bruno,
Great, that did the job :) Thanks a lot!
best, Pascale

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!