Print real roots only in numpy

前端 未结 3 1454
Happy的楠姐
Happy的楠姐 2021-02-05 13:32

I have something like this:

coefs = [28, -36, 50, -22]
print(numpy.roots(coefs))

Of course the result is:

[ 0.35770550+1.117926         


        
相关标签:
3条回答
  • 2021-02-05 13:48

    I hope this help.

     roots = np.roots(coeff);
     for i in range(len(roots)):
         if np.isreal(roots[i]):
             print(np.real(roots[i]))
    
    0 讨论(0)
  • 2021-02-05 13:51

    You can do it, using iscomplex as follows:

    r = numpy.roots(coefs)
    
    In [15]: r[~numpy.iscomplex(r)]
    Out[15]: array([ 0.57030329+0.j])
    

    Also you can use isreal as pointed out in comments:

    In [17]: r[numpy.isreal(r)]
    Out[17]: array([ 0.57030329+0.j])
    
    0 讨论(0)
  • 2021-02-05 14:09

    Do NOT use .iscomplex() or .isreal(), because roots() is a numerical algorithm, and it returns the numerical approximation of the actual roots of the polynomial. This can lead to spurious imaginary parts, that are interpreted by the above methods as solutions.

    Example:

    # create a polynomial with these real-valued roots:
    p = numpy.poly([2,3,4,5,56,6,5,4,2,3,8,0,10])
    # calculate the roots from the polynomial:
    r = numpy.roots(p)
    print(r) # real-valued roots, with spurious imaginary part
    array([ 56.00000000 +0.00000000e+00j,  10.00000000 +0.00000000e+00j,
             8.00000000 +0.00000000e+00j,   6.00000000 +0.00000000e+00j,
             5.00009796 +0.00000000e+00j,   4.99990203 +0.00000000e+00j,
             4.00008066 +0.00000000e+00j,   3.99991935 +0.00000000e+00j,
             3.00000598 +0.00000000e+00j,   2.99999403 +0.00000000e+00j,
             2.00000000 +3.77612207e-06j,   2.00000000 -3.77612207e-06j,
             0.00000000 +0.00000000e+00j])
    # using isreal() fails: many correct solutions are discarded
    print(r[numpy.isreal(r)])
    [ 56.00000000+0.j  10.00000000+0.j   8.00000000+0.j   6.00000000+0.j
       5.00009796+0.j   4.99990203+0.j   4.00008066+0.j   3.99991935+0.j
       3.00000598+0.j   2.99999403+0.j   0.00000000+0.j]
    

    Use some threshold depending on your problem at hand instead. Moreover, since you're interested in the real roots, keep only the real part:

    real_valued = r.real[abs(r.imag)<1e-5] # where I chose 1-e5 as a threshold
    print(real_valued)
    
    0 讨论(0)
提交回复
热议问题