필터 지우기
필터 지우기

matlabFunction, using symbolic variables and if statements

조회 수: 8 (최근 30일)
Pascale
Pascale 2014년 10월 3일
댓글: Pascale 2014년 10월 7일
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

채택된 답변

Bruno Pop-Stefanov
Bruno Pop-Stefanov 2014년 10월 6일
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
Bruno Pop-Stefanov
Bruno Pop-Stefanov 2014년 10월 6일
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 2014년 10월 7일
Hi Bruno,
Great, that did the job :) Thanks a lot!
best, Pascale

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Assumptions에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by