# Numerically solving a system of nonlinear equations

The first thing I am thinking and I'm sure the first reply to this will be "the arduino is not powerful enough to do this". I agree, it will likely take a considerable amount of time to solve, but I don't think that would be an issue for this particular application.

I have the following equations:

h = 450sin(A) - 550sin(A-B)
w = 550cos(A-B) - 450cos(A)

where h and w are variables passed to function. The goal is for the function to solve for what A and B are.

Note that you can't (or at least I can't) solve for A or B in either equation, otherwise this would be simple. What are some numerical methods that could be used to solve for this? I found a ton of information on numerical calculation to solve linear equations, but not much on numerical methods to solve NONlinear equations.

Any thoughts?

Do you mean to have w = (SOME FORMULA CONTAINING H) and getting rid of A and B entirely? Because if so, that's not really a programming question, but more a calculus question. I'd be interested to hear other people's ideas on this one, but the arduino is certainly powerful enough to do this. "Powerful" in this case really only has to do with speed of the calculation (And maybe memory space, but a Mega would have insane amounts anyways)

I'm not sure that I'm entirely understanding your question about my question To reiterate, assume w and h are known. I need the arduino to find a combination of values of A and B that satisfy both equations.

If anyone is curious at all, this is what the plots look like: Graphing Calculator

I would be looking for the point of intersection closest to the origin in the first quadrant.

If you are able to isolate either a or b in either of the equations, you could plug that into the other equation to solve for the other variable.

ex:

h = a^2 + b
w = a + b

h = a^2 + b
a = w-b

h = (w - b)^2 + b
// the a in h was substituted for the equation containing w //

h = w^2 -2wb + b^2 -b
// then solve for b using the known values of h and w //

b = v
// then plug the calculated value for b back into the original equation //

w = a + (v)
// and solve for a //

Hope this helps. This is a simplified version just for explanation but it will be more difficult with the trigonometric functions.
Please let me know if you have any more questions.

Ok, so I'm gonna presume you want this SPECIFIC problem solved, and not "any equation I give the arduino", because that would require something far more advanced than even most powerful household computers could handle.

SO, again this is not an arduino coding problem, this is a rearranging problem in mathematics. And as you can see by the following maths, you can see that this problem very quickly blows into MASSIVE equations that even take my classpad (Literally built to figure these sorts of things out) several minutes to rearrange it.

B = 550cos(x-y) - 450cos(x)
A = 450sin(x) - 550sin(x-y)

y = x - inverseCos((4.5/5.5)cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2Pi * constn(1)
y = x + inverseCos((4.5/5.5)cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2Pi * constn(2)

x = -2inverseTan((550cos(y))/(550sin(y))-((302500(cos(y))^2 + 302500*(sin(y)^2)-a^2-495000cos(y)+202500)^0.5)/(550sin(y)+a)-450/(550*sin(y+a)))

By putting the formulas together, you get 2 equations:

1. `x = -2*atan((550*cos(x + acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(2)))/(550*sin(x + acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(2)))-((302500*(cos(x + acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(2)))^2 + 302500*(sin(x + acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(2))^2)-A^2-495000*cos(x + acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(2))+202500)^0.5)/(550*sin(x + acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(2))+A)-450/(550*sin(x + acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(2)+A)))`

2. `x = -2*atan((550*cos(x - acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(1)))/(550*sin(x - acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(1)))-((302500*(cos(x - acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(1)))^2 + 302500*(sin(x - acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(1))^2)-a^2-495000*cos(x - acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(1))+202500)^0.5)/(550*sin(x - acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(1))+A)-450/(550*sin(x - acos((4.5/5.5)*cos(x) + (1 + 4.5/5.5) * (10 ^ (-3)) * B) - 2*Pi * constn(1)+A)))`

hence giving you the two points of intersect. Now it's just a case of simplifying the equations so that "x" is the result. Once you have A, B, and X, you can easily find Y

^ If you want me to, I can solve the last step for you, but it's gonna take a couple hours

Unfortunately,

"If you are able to isolate either a or b in either of the equations, you could plug that into the other equation to solve for the other variable."

Is not something I was able to do by hand. I didn't actually try solving this using additional tools like Technokid2000 did - but this is certainly a solid option.

I think I will try running this through with Matlab's symbolic math library to try and solve for a or b. If I can't figure it out, I may ask for help again with this. I'll post my Matlab code later if this works out in case anyone stumbles across this thread in the future and needs it!

Unfortunately,

If you are able to isolate either a or b in either of the equations, you could plug that into the other equation to solve for the other variable.

is not something I was able to do by hand. I didn't actually try solving this using additional tools like Technokid2000 did - but this is certainly a solid option.

I think I will try running this through with Matlab's symbolic math library to try and solve for a or b. If I can't figure it out, I may ask for help again with this. I'll post my Matlab code later if this works out in case anyone stumbles across this thread in the future and needs it!

I certainly could not do this by hand, and I was in one of the highest ATAR maths groups my school could offer. No, for something like this, you put it into a classpad and let it figure it out for you. Sorry I didn't solve it for you, I promize I'll do it tomorrow. I have to go to bed and I got completely sidetracked by other things (Long story, wont' elaborate here).

But effectively don't even try by hand. Just put one of the formulas into a classpad, set it to solve for x, then let it calculate it all for you. Once you have calculated X, you have the values X, A, and B, making the calculation for Y super easy

More generally, sometimes successive approximation can be used to get very close to a solution. So for example, if a function crosses the X axis, you can calculate Y for two X's that are close together, calculate the slope of the line connecting the two Y values, and take the point where that line crosses X as your next guess. Then you have to determine how close you need to get as a final solution since no exact answer is forthcoming (unless you get lucky). This method worked for me to find when the sun would pass behind a communications satellite. But you have to be able to tell, for any guess, in which direction you are off. And having two input variables I think would complicate things.

This is a simple simultaneous equation question. The problem that makes this equation so massive is that the two functions are INSIDE trigonometric functions that cannot be easily pulled out due to the two functions being different

not much on numerical methods to solve NONlinear equations.

You must be joking.

There are countless books (top 100 ranked), college math courses and a bunch of web sites covering this extremely important topic. Google "methods to solve nonlinear equations" to turn up 70 million hits.

Nonlinear Equations: Numerical Methods for Solving is a popular book, buy it from Amazon for \$5.99

There are infinitely many solutions to your particular problem, due to the cyclic nature of the trig functions.

Alright everyone, here's where I'm at.

eq1: h = 450sin(A) - 550sin(A-B)
eq2: w = 550cos(A-B) - 450cos(A)

I got matlab to spit out the following:

450sin(A) + 550(1 - (w/550 + (9cos(A))/11)^2)^(1/2) == h
450
sin(A) - 550*(1 - (w/550 + (9*cos(A))/11)^2)^(1/2) == h

To reiterate, h and w are known. The above was produced by solving eq2 for B and then plugging that into eq1.

Here is what the graph looks like

On this plot, finding the point at which the function passes the X axis will be the answer for A (of course there are infinite answers given the cyclic nature of trig).

This is where I am getting stuck now. Since these are two separate functions (which makes sense and cannot be made into a single function), I am having trouble implementing this to solve numerically. I was trying to use the bisection method.

The problem you are having now is why my formulas blew up so insanely. This is not an entry high-school math problem. This is a uni level-issue, hence why people are telling you to research online, and hence is why I'm calculating it on my classpad as we speak.

That's also why I've scrapped my initial idea to do it all step by step and am now just plugging it into the classpad and letting it rearrange it all for me.

UPDATE: It's been several minutes and the classpad is still thinking. That's probably telling how complex the problem is. Started the calculation 12:05 AWST (4:05 by the time this site uses), I'll update again when it's done...

After half an hour, my classpad finally spat out "No solution"

SOLUTION

Thanks for all the help anyway Technokid2000! I added some karma for ya I actually found a very elegant solution - it takes a mega just 20 ms (3 iterations to get within +/- 0.01) from when the function is called to when it comes up with an answer. I implemented something called the Newton method.

The actual proof behind this is a little bit tricky, but certainly a good read! I think you can still implement it without a full understanding of the inner workings though!

Some useful resources:
Paper

This requires a super basic understanding of partial derivatives and matrix algebra. Hopefully anyone else with a similar problem can benefit from this!

jremington - I am fully aware that this can be solved using other tools. I was specifically trying to get it to work on the Arduino because it is part of a much larger sketch where h and w are generated THEN this system needs to be solved. Doing this problem externally as you have done is not useful in this case.

If you want your work to be useful to anyone, post the code.

But Newton's method is around 400 years old, so no one should have significant difficulty reproducing it.

Sure, here is the code.

``````void sys(float h, float w){
int iterations = 3; //more iterations means more accurate answer
float A = 1.57; //current best guess
float B = 1.57;
float J11; //inverse Jacobian matrix values
float J12;
float J21;
float J22;
float F1; //solution to functions
float F2;

for(int i = 0; i < iterations; i++){
J11 =  sin(A - B)/(450*(cos(A)*sin(A - B) - cos(A - B)*sin(A))); //Populate jacobian matrix
J12 = -cos(A - B)/(450*(cos(A)*sin(A - B) - cos(A - B)*sin(A)));
J21 = -(9*sin(A) - 11*sin(A - B))/(4950*(cos(A)*sin(A - B) - cos(A - B)*sin(A)));
J22 = (9*cos(A) - 11*cos(A - B))/(4950*(cos(A)*sin(A - B) - cos(A - B)*sin(A)));
F1 = 450*sin(A) - 550*sin(A - B) - h;
F2 = 550*cos(A - B) - 450*cos(A) - w;
A = A - (J11*F1 + J12*F2);
B = B - (J21*F1 + J12*F2);
}
}
``````

It is clear that you know a lot more than others here, but your comments so far have been extremely sarcastic and condescending - there is no need for that. That being said, I would still like to thank you for looking into this and running the code in mathematica.