Ejemplo n.º 1
0
static cut_result_t op_test(void) {
    complex_t a = { -1, 3 };
    complex_t b = { 4, 0 };
    CUT_ASSERT_COMPLEX(3, 3, complex_add(a, b));
    CUT_ASSERT_COMPLEX(3, 3, complex_add(b, a));
    CUT_ASSERT_COMPLEX(-5, 3, complex_sub(a, b));
    CUT_ASSERT_COMPLEX(5, -3, complex_sub(b, a));
    CUT_ASSERT_COMPLEX(-4, 12, complex_mul(a, b));
    CUT_ASSERT_COMPLEX(-4, 12, complex_mul(b, a));
    CUT_ASSERT_COMPLEX(-0.25, 0.75, complex_div(a, b));
    CUT_ASSERT_COMPLEX(-0.4, -1.2, complex_div(b, a));
    CUT_TEST_PASS();
}
Ejemplo n.º 2
0
static void ifftx(complex_t data[], complex_t temp[], int n)
{
    int i;
    int h;
    int p;
    int t;
    int i2;
    complex_t wkt;

    if (n > 1)
    {
        h = n/2;
        for (i = 0;  i < h;  i++)
        {
            i2 = i*2;
            temp[i] = data[i2];         /* Even */
            temp[h + i] = data[i2 + 1]; /* Odd */
        }
        fftx(&temp[0], &data[0], h);
        fftx(&temp[h], &data[h], h);
        p = 0;
        t = MAX_FFT_LEN/n;
        for (i = 0;  i < h;  i++)
        {
            wkt = complex_mul(&icircle[p], &temp[h + i]);
            data[i] = complex_add(&temp[i], &wkt);
            data[h + i] = complex_sub(&temp[i], &wkt);
            p += t;
        }
    }
}
Ejemplo n.º 3
0
static inline void butterfly(osk_complex_t* r, const osk_complex_t* tf, int idx_a, int idx_b)
{
	osk_complex_t up = r[idx_a];
	osk_complex_t dn = r[idx_b];

	//r[idx_a] = up + tf * dn;
	//r[idx_b] = up - tf * dn;
	osk_complex_t dntf = complex_mult(&dn, tf);
	r[idx_a] = complex_add(&up, &dntf);
	r[idx_b] = complex_sub(&up, &dntf);
}
Ejemplo n.º 4
0
complex_float complex_sin(complex_float c1){
	// So... Euler said: exp(i*t) = cos(t) + i*sin(t) 
	// and then: sin(t) = (exp(i*t) - exp(-i*t)) / 2i 
	// and also: cos(t) = (exp(i*t) + exp(-i*t)) / 2  
	// Hm... I already have functions that raise complex numbers
	// to complex numbers so I'll use those for sin/code.
	complex_float exp1 = complex_pow( complex_make(exp(1)), complex_i(c1) );
	complex_float exp2 = complex_pow( complex_make(exp(1)), complex_mul(complex_make(-1.0f),complex_i(c1)) );
	complex_float diff = complex_sub(exp1,exp2);
	complex_float r = complex_div( diff, complex_i(complex_make(2.0f)) );
	return r;
}
Ejemplo n.º 5
0
complex_float complex_arccos(complex_float c1){
	// arccos(z) = (pi/2) + i * log(i*z + sqrt(1 - z*z))
	complex_float zz = complex_mul(c1,c1);
	complex_float a = complex_make(1.0f);
	a = complex_sub(a,zz);                 // 1 - z*z
	a = complex_pow(a,complex_make(0.5f)); // sqrt(...)
	complex_float iz = complex_i(c1);      // i*z
	a = complex_add(iz,a);                 // i*z + sqrt(...)
	a = complex_ln(a);                     // log(...)
	a = complex_mul(complex_i(complex_make( 1.0f )),a); // i * log(...)
	complex_float r = complex_add( complex_make(1.57079632f), a); // pi/2 + ...
	return r;
}
Ejemplo n.º 6
0
// When a root is found this function is called.
// It looks in a vector to find if the given root
// was already found, if yes it returns the position
// in the vector of the root, if not it simple adds
// the root in the first avaliable position.
int process_root(_complex z, _roots *p, double eps){
    int i;
    for(i=0;i<p->nor;i++){
        if(complex_abs(complex_sub(z,p->root[i]))<2*eps){
            return i+1;
        }
    }

    p->root[p->nor]=z;
    p->nor+=1;

    return p->nor;
}
Ejemplo n.º 7
0
complex_float complex_arcsin(complex_float c1){
	// Hopefully I got this right, from a paper called:
	// "Implementing the Complex Arcsine and Arccosine Functions Using Exception Handling"
	// arcsin(z) = -i* log(i*z + sqrt(1 - z*z))
	complex_float zz = complex_mul(c1,c1);
	complex_float a = complex_make(1.0f);
	a = complex_sub(a,zz);                 // 1 - z*z
	a = complex_pow(a,complex_make(0.5f)); // sqrt(...)
	complex_float iz = complex_i(c1);      // i*z
	a = complex_add(iz,a);                 // i*z + sqrt(...)
	a = complex_ln(a);                     // log(...)
	complex_float r = complex_mul(complex_i(complex_make( -1.0f )),a); // -i * log(...)
	return r;
}
Ejemplo n.º 8
0
void test_complex()
{
  complexFloat c = complex_new(1,2);
  CU_ASSERT(c.real==1);
  CU_ASSERT(c.imag==2);
  complexFloat d = complex_add(c,complex_zero());
  CU_ASSERT(d.real==1);
  CU_ASSERT(d.imag==2);
  d = complex_sub(c,complex_new(-1,-2));
  CU_ASSERT(d.real==2);
  CU_ASSERT(d.imag==4);
  CU_ASSERT(within_tol(complex_amp(c),sqrt(5)));
  CU_ASSERT(within_tol(complex_amp(d),sqrt(20)));
  CU_ASSERT(within_tol(complex_amp_sqr(c),5));
  CU_ASSERT(within_tol(complex_amp_sqr(d),20));
  CU_ASSERT(within_tol(complex_amp(complex_scale(d,.5)),sqrt(5)));
  d = complex_conj(c);
  CU_ASSERT(d.real==1);
  CU_ASSERT(d.imag==-2);
  complexFloat e = complex_conj(complex_add(d,complex_conj(c)));
  CU_ASSERT(e.real==2);
  CU_ASSERT(e.imag==4);
  complexVector v = complex_vector_new(c,d,e);
  CU_ASSERT(v.A.real==1);
  CU_ASSERT(v.A.imag==2);
  CU_ASSERT(v.B.real==1);
  CU_ASSERT(v.B.imag==-2);
  CU_ASSERT(v.C.real==2);
  CU_ASSERT(v.C.imag==4);
  complexVector vc = complex_vector_conj(v);
  CU_ASSERT(vc.A.real==1);
  CU_ASSERT(vc.A.imag==-2);
  CU_ASSERT(vc.B.real==1);
  CU_ASSERT(vc.B.imag==2);
  CU_ASSERT(vc.C.real==2);
  CU_ASSERT(vc.C.imag==-4);
}
Ejemplo n.º 9
0
void dwf_deriv( char *name)
{
  /*
   * This marks the argument registers as defined by ABI as off limits
   * to us until they are freed by "getarg()";
   */
  int dum = defargcount(1);
  int retno;

  /*
   * S=phi^dag (MdagM)^-1 phi
   * 
   * dS = phi^dag (MdagM)^-1 [ dMdag M + Mdag dM ] (MdagM)^-1 phi
   *
   * Let X = (MdagM)^-1 phi
   *     Y = M X = M^-dag phi
   *
   * Want terms:    Ydag dM X
   *                Xdag dMdag Y 
   * 
   * Take Xdag 1-gamma Y
   *
   * Still a bit confused about the 1+g 1-g terms; but this may be simply a factor of two as we add +h.c.
   * Will continue to follow Chroma's routine
   */
  reg_array_2d(Y,Cregs,4,3);  // 4 spinor - 24 regs 
  reg_array_2d(X,Cregs,4,3);  // 4 spinor - 12 regs 
  reg_array_1d(F,Cregs,3);    // Force
  alreg(Z,Cregs);             // Zero
  alreg(creg,Cregs);             // Zero

  offset_3d(CHIIMM,FourSpinType,2,3,2*nsimd());
  offset_3d(PSIIMM,FourSpinType,4,3,2*nsimd());
  offset_3d(GIMM  ,GaugeType, 3, 3 ,2*nsimd() );

  def_off( GAUGE_SITE_IMM, FourSpinType,4*18*nsimd());
  def_off( MAT_IMM  , GaugeType,18*nsimd());
  def_off( PSI_IMM  , FourSpinType,24*nsimd());
  def_off( CHI_IMM  , FourSpinType,12*nsimd());
  def_off( CONST_ZERO_OFFSET,Double,2*2*nsimd());

  /*
   * Integer registers
   */
  alreg(F_p,Iregs);  /*Pointer to the current cpt of force field    */
  alreg(F_p_s,Iregs);
  alreg(Y_mu,Iregs);  
  alreg(Y_p,Iregs);  
  alreg(X_p,Iregs);  

  alreg(length,Iregs);   /*number of sites*/
  alreg(tab,Iregs);      /*Pointer to current entry in offset table*/
  alreg(Complex_i,Iregs);/*Point to (0,1)x Nsimd*/
  alreg(Ls,Iregs);        
  alreg(s,Iregs);        

  alreg(recbuf_base,Iregs);
  alreg(args,Iregs);        
  alreg(s_offset,Iregs);        
  /*Useful integer immediate constants, in units of Fsize*/
  def_off( ZERO_IMM,Byte,0);
  def_off( minusone,Byte,-1);
  def_off( one,Byte,1);

  // Mask bits for predicating directions
  def_off( mask_0,Byte,1);
  def_off( mask_1,Byte,2);
  def_off( mask_2,Byte,4);
  def_off( mask_3,Byte,8);
  def_off( mask_4,Byte,16);
  def_off( mask_5,Byte,32);
  def_off( mask_6,Byte,64);
  def_off( mask_7,Byte,128);
  int mask_imm[8] = { 
    mask_0,
    mask_1,
    mask_2,
    mask_3,
    mask_4,
    mask_5,
    mask_6,
    mask_7
  };
  alreg(mask ,Iregs);

  offset_1d(TAB_IMM,TableType,17);

  // Integer sizes
  int Isize      = def_offset(PROC->I_size,Byte,"Isize");
  int ISsize     = def_offset(PROC->IS_size,Byte,"ISsize");
  int i,j,co,sp;

  /*********************************************************************/

  make_inst(DIRECTIVE,Enter_Routine,name);
  grab_stack(0);
  save_regs();

  /*********************************************
   * our arguments 
   *********************************************
   */
  getarg(args); /*Pointer to arg list*/

  queue_iload(X_p, ZERO_IMM,args);   queue_load_addr(args,Isize,args);   //0
  queue_iload(Y_p, ZERO_IMM,args);   queue_load_addr(args,Isize,args);   //1
  queue_iload(F_p,   ZERO_IMM,args);   queue_load_addr(args,Isize,args);   //2
  queue_iload(length,ZERO_IMM,args);   queue_load_addr(args,Isize,args);   //3
  queue_iload(Ls,    ZERO_IMM,args);   queue_load_addr(args,Isize,args);   //4
  queue_iload(tab,   ZERO_IMM,args);   queue_load_addr(args,Isize,args);   //5
  queue_iload(Complex_i,ZERO_IMM,args);queue_load_addr(args,Isize,args);   //6
                                       queue_load_addr(args,Isize,args);   //7  
  queue_iload(recbuf_base,ZERO_IMM,args);queue_load_addr(args,Isize,args); //8  

  /**************************************************
   * Load common constants into Iregs
   **************************************************
   */
  for (int i =0; i<12; i++ ) { 
    need_constant(i*2*SizeofDatum(FourSpinType)*nsimd());
  }
  for (int i =0; i<9; i++ ) { 
    need_constant(i*2*SizeofDatum(GaugeType)*nsimd());
  }
  complex_constants_prepare(creg,Complex_i);
  complex_load(Z,CONST_ZERO_OFFSET,Complex_i,Double);

  // Site loop 
  retno = get_target_label(); 
  check_iterations(length,retno); 
  int branchsite = start_loop(length);
  
  // S loop
  queue_iload_short(mask,TAB_IMM[10],tab);
  queue_iadd_imm (s,Ls,ZERO_IMM);
  queue_iload_imm(s_offset,ZERO_IMM);        
  int branchls   = start_loop(s); 
  queue_iadd_imm(F_p_s,F_p,ZERO_IMM);
  //  debugI(s);

  // Loop over directions
  for ( int mu=0;mu<4;mu++ ) {

    int dir = mu*2+1;  // Always in forward dir

     // Complex branch structure for interior/exterior neighbours
     int lab_proj_mu     = get_target_label(); 
     int lab_continue    = get_target_label(); 
     queue_iand_imm  (Y_mu,mask,mask_imm[dir]); // non-zero if exterior
     check_iterations(Y_mu,lab_proj_mu);

     // Exterior points are already projected. Just load.
       queue_iload_short(Y_mu,TAB_IMM[dir],tab);  
       queue_iadd       (Y_mu,Y_mu,recbuf_base);  
       //       debugI(Y_mu);
       //debugI(recbuf_base);
       queue_iadd       (Y_mu,Y_mu,s_offset); 
       for(int sp=0;sp<2;sp++){
	 for(int co=0;co<3;co++){
	   complex_load(Y[sp][co],PSIIMM[sp][co][0],Y_mu,FourSpinType);
	 }
       }

  jump(lab_continue);
  make_inst(DIRECTIVE,Target,lab_proj_mu); 

      // Interior points are not already projected.
      // * Spin project 4 spinor                                        

     queue_iload_short(Y_mu,TAB_IMM[dir],tab);  
     //     debugI(tab);
     //     debugI(Y_mu);
     queue_iadd       (Y_mu,Y_mu,Y_p);    
     queue_iadd       (Y_mu,Y_mu,s_offset); // offset for this "s"
     queue_iadd       (Y_mu,Y_mu,s_offset); // offset for this "s"

     for(int sp=0;sp<4;sp++){
       for(int co=0;co<3;co++){
	 complex_load(X[sp][co],PSIIMM[sp][co][0],Y_mu,FourSpinType);
	 //	 debugC(X[sp][co]);
       }
     }

    int pm = 1;       // pm=0 == 1+gamma, pm=1 => 1-gamma
    if ( dagger ) pm = 0;

     if ( mu == 0 ) {
	 if ( pm ==0 ) {
	   for(co=0;co<3;co++) complex_ApiB(Y[0][co],X[0][co],X[3][co]);
	   for(co=0;co<3;co++) complex_ApiB(Y[1][co],X[1][co],X[2][co]);
	 } else {
	   for(co=0;co<3;co++) complex_AmiB(Y[0][co],X[0][co],X[3][co]);
	   for(co=0;co<3;co++) complex_AmiB(Y[1][co],X[1][co],X[2][co]);
	 }
       } else if ( mu == 1 ) {
	 if ( pm ==0 ) {
	   for(co=0;co<3;co++) complex_sub(Y[0][co],X[0][co],X[3][co]);
	   for(co=0;co<3;co++) complex_add(Y[1][co],X[1][co],X[2][co]);
	 } else {
	   for(co=0;co<3;co++) complex_add(Y[0][co],X[0][co],X[3][co]);
	   for(co=0;co<3;co++) complex_sub(Y[1][co],X[1][co],X[2][co]);
	 }
       } else if ( mu == 2 ) {
	 if ( pm ==0 ) {
	   for(co=0;co<3;co++) complex_ApiB(Y[0][co],X[0][co],X[2][co]);
	   for(co=0;co<3;co++) complex_AmiB(Y[1][co],X[1][co],X[3][co]);
	 } else {
	   for(co=0;co<3;co++) complex_AmiB(Y[0][co],X[0][co],X[2][co]);
	   for(co=0;co<3;co++) complex_ApiB(Y[1][co],X[1][co],X[3][co]);
	 }
       } else if ( mu == 3 ) {
	 if ( pm ==0 ) {
	   for(co=0;co<3;co++) complex_add(Y[0][co],X[0][co],X[2][co]);
	   for(co=0;co<3;co++) complex_add(Y[1][co],X[1][co],X[3][co]);
	 } else {
	   for(co=0;co<3;co++) complex_sub(Y[0][co],X[0][co],X[2][co]); 
	   for(co=0;co<3;co++) complex_sub(Y[1][co],X[1][co],X[3][co]);
	 }
     }

  make_inst(DIRECTIVE,Target,lab_continue);

       ///////////////////////////////////////////////////////////////
       // Y contains spin projection of forward neighbour in mu direction
       // Repromote to Y to 4 spinor
       ///////////////////////////////////////////////////////////////
       for(int co_y=0;co_y<3;co_y++){
	 
	 if ( (mu==0) && (pm==0) )  complex_AmiB(Y[2][co_y],Z,Y[1][co_y]);
	 if ( (mu==0) && (pm==1) )  complex_ApiB(Y[2][co_y],Z,Y[1][co_y]);
	 if ( (mu==1) && (pm==0) )  complex_add (Y[2][co_y],Z,Y[1][co_y]);
	 if ( (mu==1) && (pm==1) )  complex_sub (Y[2][co_y],Z,Y[1][co_y]);
	 if ( (mu==2) && (pm==0) )  complex_AmiB(Y[2][co_y],Z,Y[0][co_y]);
	 if ( (mu==2) && (pm==1) )  complex_ApiB(Y[2][co_y],Z,Y[0][co_y]);
	 if ( (mu==3) && (pm==0) )  complex_add (Y[2][co_y],Z,Y[0][co_y]);
	 if ( (mu==3) && (pm==1) )  complex_sub (Y[2][co_y],Z,Y[0][co_y]);

	 if ( (mu==0) && (pm==0) ) complex_AmiB(Y[3][co_y],Z,Y[0][co_y]);
	 if ( (mu==0) && (pm==1) ) complex_ApiB(Y[3][co_y],Z,Y[0][co_y]);
	 if ( (mu==1) && (pm==0) ) complex_sub (Y[3][co_y],Z,Y[0][co_y]);
	 if ( (mu==1) && (pm==1) ) complex_add (Y[3][co_y],Z,Y[0][co_y]);
	 if ( (mu==2) && (pm==0) ) complex_ApiB(Y[3][co_y],Z,Y[1][co_y]);
	 if ( (mu==2) && (pm==1) ) complex_AmiB(Y[3][co_y],Z,Y[1][co_y]);
	 if ( (mu==3) && (pm==0) ) complex_add (Y[3][co_y],Z,Y[1][co_y]);
	 if ( (mu==3) && (pm==1) ) complex_sub (Y[3][co_y],Z,Y[1][co_y]);

       }

       ///////////////////////////////////////////////////////////////
       // Load X
       ///////////////////////////////////////////////////////////////
       for(int co_x=0;co_x<3;co_x++){
	 for(int sp=0;sp<4;sp++) {
	   complex_load(X[sp][co_x],PSIIMM[sp][co_x][0],X_p,FourSpinType);
	 }
       }

       ///////////////////////////////////////////////////////////////
       // Spin trace tensor product
       ///////////////////////////////////////////////////////////////
       for(int co_x=0;co_x<3;co_x++){
	 // Spin trace outer product
	 for ( int co_y=0;co_y<3;co_y++) complex_load (F[co_y],GIMM[co_y][co_x][0],F_p_s);  
	 for ( int co_y=0;co_y<3;co_y++) complex_conjmadd(F[co_y],X[0][co_x],Y[0][co_y]);  
	 for ( int co_y=0;co_y<3;co_y++) complex_conjmadd(F[co_y],X[1][co_x],Y[1][co_y]);  
	 for ( int co_y=0;co_y<3;co_y++) complex_conjmadd(F[co_y],X[2][co_x],Y[2][co_y]);  
	 for ( int co_y=0;co_y<3;co_y++) complex_conjmadd(F[co_y],X[3][co_x],Y[3][co_y]);  
	 
	 for ( int co_y=0;co_y<3;co_y++) complex_store(F[co_y],GIMM[co_y][co_x][0],F_p_s);  
	 
       }

     queue_load_addr(F_p_s,MAT_IMM,F_p_s); 

  }
  queue_iadd_imm(X_p,X_p,PSI_IMM);
  queue_iadd_imm(s_offset,s_offset,CHI_IMM);
  stop_loop(branchls,s); 
  queue_iadd_imm(F_p,F_p_s,ZERO_IMM);
  queue_load_addr(tab,TAB_IMM[16],tab);
  stop_loop(branchsite,length);
  make_inst(DIRECTIVE,Target,retno);

                  /*
		   *
		   * EPILOGUE
		   *
		   */

  restore_regs();
  free_stack();
  make_inst(DIRECTIVE,Exit_Routine,name);

  return;
}
Ejemplo n.º 10
0
struct signal* fft(struct signal* p_signal)
{
	struct signal*  p_input_signal = \
	(struct signal*) malloc(sizeof(struct complex_number)*(p_signal->size) + sizeof(p_signal->size));

	struct signal*  p_out_put_signal = \
 	(struct signal*)malloc(sizeof(struct complex_number)*(p_signal->size) + sizeof(p_signal->size));

	*p_input_signal   = *p_signal;
	*p_out_put_signal = *p_signal;

	int tmp   = 0;
	int index = 0;
	int bits  = 0;

	int layyer= 0;
	int selected_point = 0;
	int pre_half	   = 0;	

	int    r  = 0;
	double x  = 0;
	struct complex_number W_rN ;
	struct complex_number complex_tmp ;

	/*
	**	We caculate how many bits should be used to 
	** represent the size of the number of input signal.
	*/
	for(tmp = p_signal->size-1;tmp > 0;tmp>>=1)
	{
		bits++;
	}

	/*
	**	We should re-sequence the input signal
	** by bit-reverse.
	*/
	for(tmp = 0;tmp < p_signal->size;tmp++)
	{
		index = reverse_bits(tmp,bits);
		p_input_signal->points[tmp] = p_signal->points[index];
#ifdef DEBUG
		printf(" tmp:%5d index:%5d  ",tmp,index);
		show_complex_number(&p_signal->points[index]);
#endif
	}

	for(layyer = 1;layyer <= bits;layyer++)
	{

		
		#ifdef DEBUG
			printf("layyer %d input\n",layyer);
			show_signal(p_input_signal);
		#endif

		for(selected_point = 0;selected_point < p_signal->size;selected_point += 1<<(layyer))
		{
			for(pre_half = selected_point,r = 0,x = 0;
			    pre_half < (selected_point + (1<<(layyer-1)));
			    pre_half++)
			{
				r = get_r_in_Wn(pre_half,layyer,bits);

				#ifdef DEBUG
					printf("r: %d\n",r);
				#endif
	
				x = -2*PI*r/((double)(p_input_signal->size));
				W_rN.real    = cos(x);
				W_rN.imagine = sin(x);

				complex_tmp = complex_mul(&W_rN , &(p_input_signal->points[pre_half + (1<<(layyer-1))])  );

				#ifdef DEBUG
					show_complex_number(&complex_tmp);
				#endif

				p_out_put_signal->points[pre_half] = \
				complex_add(&p_input_signal->points[pre_half],&complex_tmp);

				p_out_put_signal->points[pre_half + (1<<(layyer-1))] = \
				complex_sub(&p_input_signal->points[pre_half],&complex_tmp);

			}
			
		}

		#ifdef DEBUG
			printf("layyer%d output\n",layyer);
			show_signal(p_out_put_signal);
		#endif

		for(tmp = 0;tmp < p_out_put_signal->size;tmp++)
		{
			p_input_signal->points[tmp] = p_out_put_signal->points[tmp];
		}

	}

	free(p_input_signal);
	return p_out_put_signal;
}
Ejemplo n.º 11
0
int main(){
    int     ix,iy,radius,i,tries,nit;
    double	zx,zy,zxn,zyn,cx,cy,theta,
            x,y,eps,
            poly[MAX_ROOTS+1];
    _roots roots;
    _complex z,w,fz,dfz;

    root_init(&roots);

    // Number of iteration for each pointer.
    // The bigger, the less prone to error the program will be.
    nit=100;

    // The radius where the points will be looked for.
    radius=6;

    // Precision for the roots
    eps=1E-10;

    scanf("%d",&roots.grad);

    for(i=roots.grad;i>=0;i--){
        scanf("%lf",&poly[i]);
    }

    printf("Coefficients:\n");
    for(i=roots.grad;i>=0;i--){
        printf(" a%d=%+.2f\n",i,poly[i]);
    }

    printf("\n f(0+0i)=");
    complex_print(f(complex_init(0,0),roots.grad, poly));
    printf("df(0+0i)=");
    complex_print(df(complex_init(0,0),roots.grad, poly));

    tries=0;

    do{
        tries++;
        theta=drand48()*2*M_PI;

        x=radius*cos(theta);
        y=radius*sin(theta);

        z=complex_init(x,y);
        for(i=0;i<=nit;i++){
            fz = f(z,roots.grad,poly);
            dfz=df(z,roots.grad,poly);
            if(complex_abs(dfz)<ee){
                break;
            }
            w=z;
            z=complex_sub(z,complex_div(fz,dfz));
            if(complex_abs(complex_sub(z,w))<=eps){
                process_root(z,&roots,eps);
                break;
            }
        }
    }while(roots.nor<roots.grad);

    printf("\nTook %d tries to get all %d roots\n",tries,roots.grad);

    printf("\nZeroes and their images:\n\n");
    for(i=0;i<roots.grad;i++){
        printf("Root Z%d=%+lf %+lfi \tf(z%d)=",i+1,roots.root[i].x,roots.root[i].y,i+1);
            complex_print(f(roots.root[i],roots.grad, poly));
    }

    return EXIT_SUCCESS;
}