Using Fsolve interatively with changing constants?

10 views (last 30 days)
I'm trying to use Fsolve to convert 5 data inputs into 5 data outputs. I've tried the pen-and-paper method, and it's beyond my meager abilities to derive explicit formulae, so I need MATLAB to do it for me.
Basically, I have 5 equations, 5 outputs, and 5 sensor inputs that would serve as constants, repeated up to 400 time points. If inputs are x and outputs y, general format would be:
X1=Y2*X3+Y4*X5
X2=Y1-Y3*X1
etc.
Or, rearranged:
0=Y2*X3+Y4*X5-X1
0=Y1-Y3*X1-X2
etc.
So for each timepoint, I would like to use actual sensor readings to put real numbers in for X1 through X5, then find the values for Y1 through Y5 with fsolve inside a For loop.
Problem is, I can't figure out how the inputs and such would work, and how to handle "constants that vary within a loop" (I'm sure there's a real term I don't know). I know fsolve wants me to write a function, but if I feed that function all 10 inputs, how will Fsolve know which ones to solve for and which ones need to remain constant? I have no code to post because I am completely flumoxed - I can't even begin to think of how to do this.
Short version: I need fsolve to solve a system of 5 equations over and over again with 5 different constants each time. I know fsolve wants me to write a function, but if I give that function all 10 inputs (guesses + constants), how will Fsolve know which ones to solve for and which ones need to remain constant?
  1 Comment
Walter Roberson
Walter Roberson on 29 Dec 2012
Do you have access to the symbolic math toolbox? If so then you might want to use it's solve() to find the Y in terms of X.

Sign in to comment.

Answers (2)

Matt J
Matt J on 29 Dec 2012
Edited: Matt J on 29 Dec 2012
See here,
However, it doesn't look like FSOLVE is the appropriate tool here. Your equalities are all linear in Y, so the solution space should be given by A\b where the matrix A and vector b are derived from the Xi
  3 Comments
Henry Astley
Henry Astley on 30 Dec 2012
Edited: Matt J on 6 Nov 2013
Sorry, I need more help with this.
I can't use a matrix method because the formulae contain instances where two inputs or two outputs are multiplied together.
I can't figure out how to get solve to give me anything useful. I enter is as so:
[Fx,Fy,xoff,yoff,Tz]=solve('Fx-Tz*yoff-Fsx=0','Fy-Tz*xoff-Fsy=0','Fy*zoff-Fz*yoff-Msx=0','Fz*xoff-Fx*zoff-Msy=0','Fx*yoff-Fy*xoff-Msz=0');
...and while it gives me answers, it doesn't give me ones that are useful - all the answers still have outputs defined by other outputs.
I tried anonymizing with fsolve, and it gave me errors. Here's my code for the function (the last 6 are my sensor readings (anything with an 's' in it), the first six are values I want):
function fcns = Tzfcns(Fx,Fy,Fz,xoff,yoff,Tz,Fsx,Fsy,Fsz,Msx,Msy,Msz)
fcns(1)=Fx-Tz*yoff-Fsx;
fcns(2)=Fy-Tz*xoff-Fsy;
fcns(3)=Fz-Fsz;
fcns(4)=Fy*(-0.018)-Fz*yoff-Msx;
fcns(5)=Fz*xoff-Fx*(-0.018)-Msy;
fcns(6)=Fx*yoff-Fy*xoff-Msz;
end
And my script, after getting the sensor inputs from a file, is:
for i=1:len
f = @(Fx,Fy,Fz,xoff,yoff,Tz)Tzfcns(Fx,Fy,Fz,xoff,yoff,Tz,Fsx(i),Fsy(i),Fsz(i),Msx(i),Msy(i),Msz(i));
g=[1,1,1,1,1,1];
x=fsolve(f,g);
end
which gives me an error
??? Input argument "Fy" is undefined.
Error in ==> @(Fx,Fy,Fz,xoff,yoff,Tz)Tzfcns(Fx,Fy,Fz,xoff,yoff,Tz,Fsx(i),Fsy(i),Fsz(i),Msx(i),Msy(i),Msz(i))
Error in ==> fsolve at 254
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot continue.
I still can't figure out what I'm doing wrong. I assume I did something wrong with the anonymizing, but the example text given only has one variable. Can it only work with one variable? Or am I just formatting it incorrectly?
Matt J
Matt J on 6 Nov 2013
I assume I did something wrong with the anonymizing, but the example text given only has one variable.
No, the example has 2 unknowns x(1) and x(2). The thing you're doing wrong is that you are passing all 6 unknowns as separate arguments to Tzfcns, whereas you should be bundling them all into a single unknown vector:
function fcns = Tzfcns(unknowns,knowns)
unknowns=num2cell(unknowns);
[Fx,Fy,Fz,xoff,yoff,Tz] = deal(unknowns{:});
knowns=num2cell(knowns);
[Fsx,Fsy,Fsz,Msx,Msy,Msz] = deal(knowns{:});
fcns(1)=Fx-Tz*yoff-Fsx;
fcns(2)=Fy-Tz*xoff-Fsy;
fcns(3)=Fz-Fsz;
fcns(4)=Fy*(-0.018)-Fz*yoff-Msx;
fcns(5)=Fz*xoff-Fx*(-0.018)-Msy;
fcns(6)=Fx*yoff-Fy*xoff-Msz;
end
and then
g=[1,1,1,1,1,1];
for i=1:len
knowns=[Fsx(i),Fsy(i),Fsz(i),Msx(i),Msy(i),Msz(i)];
f = @(unknowns) Tzfcns(unknowns,knowns);
x=fsolve(f,g);
end

Sign in to comment.


Walter Roberson
Walter Roberson on 30 Dec 2012
You did not specify which variables to solve for, so solve() used its own ideas about which to use and those did not match your expectations. Specify the variables yourself:
syms Fsx, Fsy, Fx, Fy, Fz, Msx, Msy, Msz, Tz, xoff, yoff, zoff
[Fx,Fy,xoff,yoff,Tz] = solve(Fx-Tz*yoff-Fsx, Fy-Tz*xoff-Fsy, Fy*zoff-Fz*yoff-Msx, Fz*xoff-Fx*zoff-Msy, Fx*yoff-Fy*xoff-Msz, Fx, Fy, xoff, yoff, Tz);
You might find that the solutions are all expressed as multiples of an expression involving a RootOf() term. That RootOf() term will be a way of expressing that at that point you should substitute the two solutions to a quadratic function,
RootOf(Msz*zoff^2*Z^2+(-Msx*zoff*Fsy-zoff*Fsx*Msy-Msy^2+Msx^2)*Z-Fsy*Fz*Msy-Fsx*Fz*Msx-Msz*Fz^2, Z)
The RootOf() represents the roots, the set of values of Z such that the expression in the first term becomes 0. There is, of course, an analytic form of that, but it would be messy to write.
If you extract the RootOf() term using op(), then you can subs() another variable name (e.g., "R") for the expression in each of the formulas you got, in order to give you pretty compact representations of those formulas. That is not necessary, but it can make things much easier to understand. But from there through the rest of your program you need to keep in mind that each of the variables you calculated has two values, one corresponding to each of the two roots.

Community Treasure Hunt

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

Start Hunting!