fsolve multi variables help

I am trying to solve for angles in a system given 2 equations and 2 unknowns. First I defined ,y two functions in the form
function F=myfun(theta2, theta3, theta4)
F=[.2+.05.*cos(theta2)+.304.*cos(theta3)-.2.*cos(theta4);
.1+.05.*sin(theta2)+.304.*sin(theta3)-.2.*sin(theta4)];
end
then I attempt to solve for the unknowns using fsolve
theta3(1)=170.69;
theta4(1)=116.56;
x0=0
for theta2=-90:5:270;
options = optimset('Display','iter');
x=fsolve(@myfun,X0,options);
end
what am I doing wrong? is this even possible?

 Accepted Answer

I can’t figure out what you want to do.
The optimisation routines want the objective function argument to be a vector. The easiest way to do this with your function is to call it as:
@(b)myfun(b(1),b(2),b(3))
so:
x = fsolve(@(b)myfun(b(1),b(2),b(3)),X0,options);
with ‘X0’ now being a three-element vector.
I do not understand the loop. Because ‘X0’ never changes, the solution is the same for every iteration.

4 Comments

I'm trying to solve a system of equations. that is, solve for theta3 and theta4 given theta2 i don't have initial theta3 and 4. my function F is defined in the format F(theta)=0.... so i'm trying to solve for the array of theta3 and theta 4 such that theta2=-90:5:270 thats why the for loop is needed, to change theta2 with every iteration but when i try to run my code, it tells me it needs inputs for theta3, theta 4 to execute
F=[.2+.05.*cos(theta2)+.304.*cos(theta3)-.2.*cos(theta4);
.1+.05.*sin(theta2)+.304.*sin(theta3)-.2.*sin(theta4)];
Now I understand.
Try this:
function F=myfun(theta2, theta3, theta4)
F=[.2+.05.*cosd(theta2)+.304.*cosd(theta3)-.2.*cosd(theta4);
.1+.05.*sind(theta2)+.304.*sind(theta3)-.2.*sind(theta4)];
end
theta3 = 170.69;
theta4 = 116.56;
X0 = [theta3; theta4];
options = optimset('Display','iter');
theta2 = -90:5:270;
for k1 = 1:length(theta2)
x(:,k1)=fsolve(@(b)myfun(theta2(k1),b(1),b(2)),X0,options);
end
figure(1)
plot(theta2, x)
grid
xlabel('\theta_2')
ylabel('\theta (°)')
legend('\theta_3', '\theta_4')
I tested that code. It works. (Note that I converted the trigonometric functions to their degree equivalents, since you define ‘theta2’ and the others in degrees.)
This is virtually the same as my solution already presented below. The only difference is that I do not use a fixed initial guess theta3 = 170.69, theta4 = 116.56 for every theta2(k1). It is inadvisable to do so. Much faster convergence and much better resilience to local min can be obtained by doing a coarse initial sweep of F.
you guys just saved my project grade, thanks! I could not figure it out.

Sign in to comment.

More Answers (1)

Matt J
Matt J on 13 Dec 2017
Edited: Matt J on 14 Dec 2017
I suspect you might be after something like this. Note that I changed all of your sin() and cos() to sind() and cosd() since it looks like you are measuring angles in degrees.
Theta2=(-90:5:270); N=numel(Theta2);
[Theta3,Theta4]=ndgrid(1:2:360);
for i=N:-1:1 %Get initial guesses through coarse sampling
Error = sum(abs( myfun(Theta2(i), Theta3(:).', Theta4(:).') ));
[minval,imin]=min(Error);
X0(i,:)=[Theta3(imin), Theta4(imin)];
end
options = optimset('Display','iter');
for i=N:-1:1 %Refine the initial guesses
thisFun=@(X) myfun(Theta2(i), X(1), X(2));
x(i,:)=fsolve(thisFun,X0(i,:),options);
end
function F=myfun(theta2, theta3, theta4)
F=[.2+.05.*cosd(theta2)+.304.*cosd(theta3)-.2.*cosd(theta4);
.1+.05.*sind(theta2)+.304.*sind(theta3)-.2.*sind(theta4)];

Products

Tags

Community Treasure Hunt

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

Start Hunting!