#ifndef _SIROCCO_HPP_ #define _SIROCCO_HPP_ #include #include #include #include #include // ACTIVATE ROUND MODE CONTROL #ifndef __clang__ #pragma STDC FENV_ACCESS ON #endif typedef std::complex Complex; double * homotopyPath (int degree, double *_coef, double _y0R, double _y0I); mpfr_t * homotopyPath_mp (int degree, mpfr_t *_coef, mpfr_t _y0R, mpfr_t _y0I, int prec); double * homotopyPath_comps (int degree, double *_coef, double _y0R, double _y0I, int nothercomps, int *degreescomps, double *_coefscomps); mpfr_t * homotopyPath_mp_comps (int degree, mpfr_t *_coef, mpfr_t _y0R, mpfr_t _y0I, int prec, int nothercomps, int *degreescomps, mpfr_t *_coefscomps); template // T -> Complex, IComplex, MPComplex or MPIComplex void correctRoot (const Polynomial, const T &x0, T &y0) {} template // T -> Complex or MPComplex T getA (const Polynomial f, const T &x0, const T &y0) { return -(f.diffX (x0, y0) / f.diffY (x0, y0)); } template // T -> IComplex or MPIComplex int newtonTest (const Polynomial &If, const T &Ix0, const T &Iy0, const T &IY0) { T N, aux; N = If(Ix0, Iy0); aux = If.diffY (Ix0, IY0); // check we do not perform division by an interval containing 0. // in this case, return fail the test if (aux.containsZero ()) return 0; N = Iy0 - (N / aux); if (N.subset (IY0)) return 1; return 0; } // // RETURNS WHETHER NEWTON EVALUATION N IS CONTAINED IN THE INTERVAL ENCLOSURE IY0 OF Iy0. // // BESIDES REPEATS WITH A ENCLOSURE THREE TIMES BIGER. RETURNS SUCCESS IF BOTH ARE SATISFIED template // T -> IComplex or MPIComplex int validate (const Polynomial &If, const T &Ix0, const T &Iy0, const T &IY0) { T IY1; if (!newtonTest (If, Ix0, Iy0, IY0)) return 0; // COMPUTES AN ENCLOSURE THREE TIMES BIGGER FOR N2 // CREATE A 3-TIMES BIGGER ENCLOSURE (ROUNDING TO BIGGER) IY1 = IY0 + IY0; IY1 = IY1 - IY0; if (!newtonTest (If, Ix0, Iy0, IY1)) return 0; return 1; } template int validate (const Polynomial &If, const T &Ix0, const T &Iy0, const T &IY0, int nothercomps, const Polynomial othercomps[]) { T IY1; if (!newtonTest (If, Ix0, Iy0, IY0)) return 0; // COMPUTES AN ENCLOSURE THREE TIMES BIGGER FOR N2 // CREATE A 3-TIMES BIGGER ENCLOSURE (ROUNDING TO BIGGER) IY1 = IY0 + IY0; IY1 = IY1 - IY0; if (!newtonTest (If, Ix0, Iy0, IY1)) return 0; T evalcomp; for (int i=0; i