3

Given values for the variables s, v, and h, and given a library such as numeric.js how can I numerically solve the following equation for a within a given degree of accuracy?

singular transcendental trig equation

I'm wanting a JS algorithm for use in-browser.

Web_Designer
  • 64,966
  • 87
  • 197
  • 254
  • SO is not a free coding service. Please make an attempt, and if it doesn't work post what you tried, and we'll try to help you fix it. – Barmar Sep 09 '14 at 21:17
  • 2
    You should do the algebraic transformations to turn it into `a = XXX`, where `XXX` is an equation in terms of `s`, `v`, and `h`. Then it should be straightforward to calculate it using the functions in `numeric.js`. If you need help with the math, math.stackexchange.com is the place for that. – Barmar Sep 09 '14 at 21:19
  • @Barmar I have no clue how to separate `a` onto its own side of the equation. Any help would be appreciated. – Web_Designer Sep 09 '14 at 21:59
  • @Web_Designer Well that a rudimentary algebra referesher seems to to be needed. – Mike Brant Sep 09 '14 at 22:03
  • 5
    math.stackexchange.com is your first stop. – Mike Brant Sep 09 '14 at 22:05
  • I've taken algebra and a little calc, it's just that the `a` variable that needs to be isolated appears in the denominator of the value in the hyperbolic cosine function. I don't know how to get it out. – Web_Designer Sep 09 '14 at 22:10
  • Know of any trig identities that would help? – Web_Designer Sep 09 '14 at 22:10
  • 2
    @Barmar: The referenced Wikipedia article states that “This is a transcendental equation in a and must be solved numerically.” So solving for *a* algebraically very likely won't work unless Wikipedia is wrong. Which turns this into a question more about numerics, and how to implement them in JS, which imho makes this a valid post for SO. Please consider this before (or instead of) voting to close. – MvG Sep 10 '14 at 07:31
  • Once the project for which you need this has been completed and is available online, will you provide a link to it? This looks interesting. – MvG Sep 10 '14 at 14:33
  • I am voting to close this question. As the answers make abundantly clear the core of the question is not programming, it is maths. – High Performance Mark Sep 10 '14 at 16:19
  • Also see http://math.stackexchange.com/q/1000447/35416 – MvG Nov 03 '14 at 07:47

2 Answers2

3

Separating variables and parameters

You could start by substituting b = a/h. That would turn your equation into

2b*sinh(1/(2b)) = sqrt(s²-v²)/h

That way you have all the inputs on the right hand side, and the variable on the left hand side, but unfortunately still occuring in several places in a transcendental form. The benefit is that we can now treat the right-hand side as a single number in order to gain some understanding of this function.

First look at a plot

The function seems reasonably well-behaved:

Plot of the function

So you can do standard numerical root-finding methods, e.g. Newton's method, to find the position where this function takes a given value (i.e. the one you computed from the right-hand side). If you interpret root-finding as finding locations where a function is zero, then the function for which you want to find zeros is the difference, i.e.

2a*sinh(h/(2a)) - sqrt(s²-v²)

Using optimization from numeric.js

If you want to make use of numeric.js, numeric.uncmin would likely be your best bet. At least it's the best I could find in the docs so far. (Perhaps there is some bare root-finding implementation in there, but if so, I couldn't find it yet.) You'd try to find the minimum of the function

(2a*sinh(h/(2a)) - sqrt(s²-v²))²

interpreted as a function of a, and hope that that minimum is actually (close to) zero. You might get better results (i.e. faster convergence and/or lower error) by also providing the gradient (derivative) of that function as a separate argument. You can use Wolfram Alpha to find that derivative.

Further rewriting of the function

Let's define f as f(b) = 2b*sinh(1/(2b)). You are trying to find out at what position f assumes a given value. In order to make convergence faster, you can try to turn this f into a different function which will be close to linear. Toying around with plots, I've come up with this:

g(b) = (f(b) - 1)^(-1/2)

You can apply the same conversion to the right hand side to see the desired value for this function. For b > 0.06 this looks fairly linear, so it should converge really fast. Provided your parameters are expected to be in that range where it is almost linear, but even for smaller b it should be no worse than the original formulation. You could use the linear form to compute the starting position of your Newton's method, but I wouldn't bother: as long as you start with a reasonably big value, the first step of Newton's method will do just that.

Plot of g

MvG
  • 51,562
  • 13
  • 126
  • 251
2
  1. this is transcendent equation

    I assume real domain in that case you can not separate the unknown from it (in general) instead you still can solve it numerically (as you intended)

  2. I am too lazy to do proper analysis of 2a.sinh(h/2a)=sqrt(s.s-v.v)

    but if I see it right then 2a.sinh(h/2a) is monotone so let c=sqrt(s.s-v.v) for simplicity and speed up. As I see it c >= 0 so if h >= 0 then a = <0,+inf)

  3. find value crossing

    double a0,a1,da=initial accuracy step;
    for (a1=0.0;2a.sinh(h/2a)<=sqrt(s.s-v.v);a1+=da);
    

    now a1 holds approximate top bound solution

    for (a0=a1;2a.sinh(h/2a)>sqrt(s.s-v.v);a0-=da);
    

    now a0 holds approximate low bound solution

  4. find solution in desired accuracy


    if a0==a1 then you have found exact solution so stop
    if fabs(a1-a0)<=accuracy you are inside your accuracy so stop and lower the da for example da*=0.01; this will boost accuracy 100 times. Now search for solution again but only on interval <a0,a1> and repeat this until solution is found

[notes]

Another example of solution of transcendent equation is here: solving Kepler`s equation. When nothing else works you still can try this:

Spektre
  • 41,942
  • 8
  • 91
  • 312