Using GSLMultiRootFinder

I’d like to use GSLMultiRootFinder to solve the following system of non-linear equations:

Where the unknowns are “x” and “y”.

Based on this tutorial: https://root.cern.ch/doc/master/exampleMultiRoot_8C.html, this is what I have so far:

    ROOT::Math::MultiRootFinder rootFinder(0);

    TF2 *f1 = new TF2("f1", "sqrt((x-[0])^2 + (y-[1])^2) - sqrt((x-[2])^2 + (y-[3])^2) + [4]*([5]-[6])");
    TF2 *f2 = new TF2("f2", "sqrt((x-[0])^2 + (y-[1])^2) - sqrt((x-[2])^2 + (y-[3])^2) + [4]*([5]-[6])");
    TF2 *f3 = new TF2("f3", "sqrt((x-[0])^2 + (y-[1])^2) - sqrt((x-[2])^2 + (y-[3])^2) + [4]*([5]-[6])");

   //Here I'll set the parameters
 
    ROOT::Math::WrappedMultiTF1 g1(*f1,2);
    ROOT::Math::WrappedMultiTF1 g2(*f2,2);
    ROOT::Math::WrappedMultiTF1 g3(*f3,2);

    rootFinder.AddFunction(g1);
    rootFinder.AddFunction(g2);
    rootFinder.AddFunction(g3);

    r.Solve(//startingpoint);
    

Firstly, I haven’t done anything stupid, right?

My question, however, is: how do I determine the starting point? Forgive me, for this is well outside my area of expertise. Not entirely sure if this is a ROOT question or a mathematical question, however some people seem to think this is a ROOT question.

Thank you!


Please read tips for efficient and successful posting and posting code

ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Hi Keith,

Well, you have

TF2 *fX = new TH2(...);

– this is wrong, it should be

TF2 *fX = new TF2(...);

everywhere.

I think you also have to change the first parameter of the TF2 ctors to something unique instead of having f1 written everywhere.

Finally, according to your code, x1=x2=x3=[0], y1=y2=y3=[1], x2=x3=x1=[2], y2=y3=y1=[3], t2=t3=[5], and t1=t2=[6] – I’m afraid this does not make any sense to me. You have to have 10 parameters for such system, you only have seven.

I’m sorry this is far from the answer you are hoping for, but I’m no expert in the MultiRootFinder.

1 Like

Oh, yes, whoops. Instead of copying and pasting, as I should have, I typed this up in a hurry and made some really stupid mistakes, it seems (including, as you pointed out, changing the first parameter of the TF2’s… you’re absolutely correct here, they should be unique). These aren’t, of course, present in the actual code.

What I need is probably in the ROOT docs, but unfortunately I’m unable to access those right now for some reason… All I have is the bookmarked tutorial above.

For anyone who may be having the same issue:

As it seems, the solution (or a solution, anyhow) is to convert the equations in to polynomials (which is a trivial task, of course), and then to rescale the domain such that both unknowns necessarily lie in [0,1].

Now, we express these polynomials as linear combinations of Bernstein basis polynomials. This is useful as we can now use the convexitivity property of Bernstein polynomials to rule out entire “regions” of the range, getting effectively an arbitrarily close estimate of the roots.

An alternative, simpler solution is to begin with a (very) rough estimate given by the center of the circle circumscribed by the the three coordinates [x_i,y_i]. It isn’t immediately clear to me how this is effective, as opposed to the above solution, however it seems that it works.

In the end, any estimate will work provided enough iterations, however some will be a lot slower than others.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.