Search code examples
ccomplex-numberspolynomialsgslcoefficients

Finding roots of higher degree polynomials with complex coefficients using gsl library in C


I have a quinitc equation to solve. It is a part of a long calculation. I have a code in C and I wanted to use the gsl for doing calculations. In particular, I want to use the function gsl_complex_poly_complex_eval but I am having trouble in defining its attributes. Following is a simple code I want to use.

#include<studio.h>
#include<math.h>
#include<complex.h>
#include<gsl/gsl_poly.h>
#include<gsl/gsl_complex.h>
int
main (void)
{

double omgo,omgM,omge,omgA;
double g1,g2,g3,g4,g5,g6;

omgM = 5000;
omgo = 490;
omgA=9.97;
omge=0.00035;
g1 = 1.0;
g2 = 2*omge;
g3 = (omgA*omgA+omge*omge+2*omgM*omgM+4*omgo*omgo);
g4 = -2*omge*(omgA*omgA+omgM*omgM+4*omgo*omgo);
g5 = (cpow(omgM,4.0)+omgA*omgA(omge*omge+omgM*omgM)+4*cpow(omge,2.0)*cpow(omgo,2));
g6 = omgA*omgA*omge*omgM*omgM;
gsl_complex a[6],z;
a[0] = -I*g6;
a[1] = g5;
a[2] = -I*g4;
a[3] = -g3;
a[4] = -2*I*g2;
a[5] = g1;
gsl_complex_poly_complex_eval(a,6,z);
print("%.30lf, %.30lf\n",creal(z),cimag(z));
return 0;
}

I am getting errors like:

quintic_roots.c: In function ‘main’:
quintic_roots.c:28:7: error: incompatible types when assigning to type ‘gsl_complex {aka struct <anonymous>}’ from type ‘complex double’
  a[0] = -I*g6;
       ^
quintic_roots.c:29:7: error: incompatible types when assigning to type ‘gsl_complex {aka struct <anonymous>}’ from type ‘double’
  a[1] = g5;
       ^
quintic_roots.c:30:7: error: incompatible types when assigning to type ‘gsl_complex {aka struct <anonymous>}’ from type ‘complex double’
  a[2] = -I*g4;
       ^
quintic_roots.c:31:7: error: incompatible types when assigning to type ‘gsl_complex {aka struct <anonymous>}’ from type ‘double’
  a[3] = -g3;
       ^
quintic_roots.c:32:7: error: incompatible types when assigning to type ‘gsl_complex {aka struct <anonymous>}’ from type ‘complex double’
  a[4] = -2*I*g2;
       ^
quintic_roots.c:33:7: error: incompatible types when assigning to type ‘gsl_complex {aka struct <anonymous>}’ from type ‘double’
  a[5] = g1;
       ^
quintic_roots.c:38:36: error: incompatible type for argument 1 of ‘cimag’
  printf ("%.30lf, %.30lf\n", cimag(z),creal(z));
                                    ^
In file included from quintic_roots.c:3:0:
/usr/include/x86_64-linux-gnu/bits/cmathcalls.h:127:1: note: expected ‘complex double’ but argument is of type ‘gsl_complex {aka struct <anonymous>}’
 __MATHDECL (_Mdouble_,cimag, (_Mdouble_complex_ __z));
 ^
quintic_roots.c:38:45: error: incompatible type for argument 1 of ‘creal’
  printf ("%.30lf, %.30lf\n", cimag(z),creal(z));
                                             ^
In file included from quintic_roots.c:3:0:
/usr/include/x86_64-linux-gnu/bits/cmathcalls.h:130:1: note: expected ‘complex double’ but argument is of type ‘gsl_complex {aka struct <anonymous>}’
 __MATHDECL (_Mdouble_,creal, (_Mdouble_complex_ __z));

Solution

  • Many changes are made, all as directed by libgsl-documentation. You need to understand the power of documentation, I never used libgsl, but here I am writing code using it, all because of documentation.

    quintic_roots.c

    #include<stdio.h>
    #include<math.h>
    #include<complex.h>
    #include<gsl/gsl_poly.h>
    #include<gsl/gsl_complex.h>
    int
    main (void)
    {
    
        double omgo,omgM,omge,omgA;
        double g1,g2,g3,g4,g5,g6;
    
        omgM = 5000;
        omgo = 490;
        omgA=9.97;
        omge=0.00035;
        g1 = 1.0;
        g2 = 2*omge;
        g3 = (omgA*omgA+omge*omge+2*omgM*omgM+4*omgo*omgo);
        g4 = -2*omge*(omgA*omgA+omgM*omgM+4*omgo*omgo);
        g5 = (cpow(omgM,4.0)+omgA*omgA*(omge*omge+omgM*omgM)+4*cpow(omge,2.0)*cpow(omgo,2));
        g6 = omgA*omgA*omge*omgM*omgM;
    
        gsl_complex *a = (gsl_complex*) calloc(6, sizeof(gsl_complex));
    
        GSL_SET_IMAG(a, -g6);
        GSL_SET_REAL(a+1, g5);
        GSL_SET_IMAG(a+2, -g4);
        GSL_SET_REAL(a+3, -g3);
        GSL_SET_IMAG(a+4, -2*g2);
        GSL_SET_REAL(a+5, g1);
    
        gsl_complex z;
    
        GSL_SET_COMPLEX(&z, 1, 1);
    
        gsl_complex res = gsl_complex_poly_complex_eval(a,6,z);
    
        printf("%.15lf, %.15lf\n",GSL_REAL(res),GSL_IMAG(res));
        return 0;
    }
    

    Compilation

    gcc quintic_roots.c -lgsl  -lm 
    

    Output

    625002586907152.250000000000000, 625002382231741.375000000000000
    

    The output is for z = 1 + 1i, pls modify z according to your input.