BookmarkSubscribe
Choose Language Hide Translation Bar
MHz
MHz
Community Trekker

Real roots of degree 3 Polynomial

Hello everyone,

 

Does anyone know how to calculate real roots of degree 3 polynomial with JMP scripting ? 

 

I have the coefficients of the equation :  0 = A + B.X + C.X² + DX^3. What I need is the real solutions.

I started to create a new data table with lots of rows in order to get as close as possible to the desired value, but it takes too much time.

 

Thanks,

 

0 Kudos
1 ACCEPTED SOLUTION

Accepted Solutions
Craige_Hales
Staff (Retired)

Re: Real roots of degree 3 Polynomial

(Not a mathematician, I'm sure this has some flaws...) Similar to your original idea, but make JSL do the work. I'm pretty sure Minimize has seen some improvements since JMP 10. https://community.jmp.com/t5/JMPer-Cable/Minimize-and-Maximize-Functions-in-JSL/ba-p/36355/jump-to/f...

a = -2;
b = -3;
c = 5;
d = 1;

f = Function( {x},
    a + b * x + c * x * x + d * x * x * x
);

lo = -1e99;
hi = 1e99;
vlo = f( lo );
vhi = f( hi );
v = 1;
nn=0;
While( (abs(v)>1e-15)  ,
    test = (lo + hi) / 2;
    v = f( test );

    If( v > 0,
        If(
            vhi > 0, hi = test,
            vlo > 0, lo = test
        ),
        If(
            vhi < 0, hi = test,
            vlo < 0, lo = test
        )

    );
);


New Window( "Example",
    Graph Box(
        X Scale( -10, 10 ),
        Y Scale( -30, 30 ),
        Pen Color( "red" );
        Y Function( f(x), x );
        pencolor("black");
        V Line( test );
        hline(0);
    )
);

Capture.PNGFound a zero

If the coefficients on the ^2 and ^3 terms are too big, you'll need to make the -1e99 to 1e99 interval smaller.

Craige
8 REPLIES 8
Highlighted

Re: Real roots of degree 3 Polynomial

You can use this formula to get the first root, substitute that x value into the expression to reduce the polyomial orrder to 2, and the use the quadratic soltution to obtain the remaining roots.

Learn it once, use it forever!
MHz
MHz
Community Trekker

Re: Real roots of degree 3 Polynomial

Thank you for this answer.

It's indeed a way of doing, but I'm affraid that won't work everytime I will use the script : the square root of a negative number is the reason why.

 

In Excel I'm able to do it, but not on JMP, and I rather prefer not to use two softwares for one script.

 

Does anyone have another way of doing it?

0 Kudos
XanGregg
Staff

Re: Real roots of degree 3 Polynomial

Maybe the Minimize() function can help.Since it find the minimum, rather than the zero, you have to transform your cubic so the zero is at the minimum. Presumably squaring is better than absolute value because the Minimum function says it will take derivatives.

 

f = Expr( Power( -2 - 3 * x + 5 * Power( x, 2 ) + Power( x, 3 ), 2 ) );
x = -100;
minFromLeft = Minimize( Name Expr( f ), {x} );
xFromLeft = x;
x = 100;
minFromRight = Minimize( Name Expr( f ), {x} );
xFromRight = x;
show(xFromLeft, minFromLeft, xFromRight, minFromRight);

// result:
xFromLeft = -5.5995441248061;
minFromLeft = 1.07130883787516e-10;
xFromRight = 0.276987650239635;
minFromRight = 2.4771578468284;

Searching from the left and the right if you know such bounds should find at least one real root, and with that the problem becomes quadratic.

MHz
MHz
Community Trekker

Re: Real roots of degree 3 Polynomial

The minimize function seems a good way of doing it, but I cannot make it work :

I've tried your script, but at the row 3 (   minFromLeft = Minimize( Name Expr( f ), {x} );   ) 

I get the following alert :

"Optimization failed: Failed: Cannot Decrease Objective Function"

 

I've the JMP version 10.0.0. 

 

Does it have anything to do with that?

0 Kudos
XanGregg
Staff

Re: Real roots of degree 3 Polynomial

Likely there have been improvements since JMP 10. You might try experimenting with the parameters, such as the tolerance.
Craige_Hales
Staff (Retired)

Re: Real roots of degree 3 Polynomial

(Not a mathematician, I'm sure this has some flaws...) Similar to your original idea, but make JSL do the work. I'm pretty sure Minimize has seen some improvements since JMP 10. https://community.jmp.com/t5/JMPer-Cable/Minimize-and-Maximize-Functions-in-JSL/ba-p/36355/jump-to/f...

a = -2;
b = -3;
c = 5;
d = 1;

f = Function( {x},
    a + b * x + c * x * x + d * x * x * x
);

lo = -1e99;
hi = 1e99;
vlo = f( lo );
vhi = f( hi );
v = 1;
nn=0;
While( (abs(v)>1e-15)  ,
    test = (lo + hi) / 2;
    v = f( test );

    If( v > 0,
        If(
            vhi > 0, hi = test,
            vlo > 0, lo = test
        ),
        If(
            vhi < 0, hi = test,
            vlo < 0, lo = test
        )

    );
);


New Window( "Example",
    Graph Box(
        X Scale( -10, 10 ),
        Y Scale( -30, 30 ),
        Pen Color( "red" );
        Y Function( f(x), x );
        pencolor("black");
        V Line( test );
        hline(0);
    )
);

Capture.PNGFound a zero

If the coefficients on the ^2 and ^3 terms are too big, you'll need to make the -1e99 to 1e99 interval smaller.

Craige
MHz
MHz
Community Trekker

Re: Real roots of degree 3 Polynomial

I've selected the answer that works for me with my JMP version. 

Thank you all for your help!

 

 

0 Kudos
ms
Super User ms
Super User

Re: Real roots of degree 3 Polynomial

I tried both Minimize() and the Nonlinear platform. Both works well to solve polynomials, but it's easy to miss one or more roots because of a bad initial value. Looking at the graph helps.

 

If you have R installed you could try this JSL function:

Names Default To Here(1);
// Function calling R, returns real roots of polynomials
// Input: a matrix of coefficients [x^0 ... x^n] 
realroots = Function({p},
    R Init();
    R Send(p);
    R Submit("roots=polyroot(p); real=Re(roots[which(round(Im(roots),12)==0)])");
    real = R Get(real);
    R Term();
    real;
);

// Try it!
p1 = [-4 0 1];  // two real roots: ±2^2=4  
p2 = [-27 0 0 1];  // one real root: 3^3=27  
p3 = [7 -8 4 1]; // one real root
p4 = [1 -3 1 1]; // three real roots
ex1 = realroots(p1);
ex2 = realroots(p2);
ex3 = realroots(p3);
ex4 = realroots(p4);
Show(ex1, ex2, ex3, ex4);