Merge pull request #3 from embray/icomplex-polynomial-eval

Fix complex interval polynomial evaluation
This commit is contained in:
Miguel Marco 2020-02-11 14:25:08 +01:00 committed by GitHub
commit a42ea6032f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 57 additions and 12 deletions

5
.gitignore vendored
View File

@ -17,5 +17,10 @@ lib/*.la
libtool libtool
m4/ m4/
tests/.deps/ tests/.deps/
tests/.libs/
tests/*.log
tests/*.o
tests/*.trs
tests/*_test
tests/Makefile tests/Makefile
tests/Makefile.in tests/Makefile.in

17
.travis.yml Normal file
View File

@ -0,0 +1,17 @@
language: cpp
os: linux
dist: bionic
compiler:
- gcc
- clang
addons:
apt:
packages:
- libmpfr-dev
script:
- autoreconf -f -i
- ./configure
- make
- make check
after_failure:
- tail -n +1 tests/*.log 2>/dev/null

View File

@ -1,7 +1,6 @@
AC_INIT([libsirocco], [2.0], [mmarco@unizar.es]) AC_INIT([libsirocco], [2.0], [mmarco@unizar.es])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
: ${CXXFLAGS=-O0 -g}
AM_INIT_AUTOMAKE([foreign -Wall]) AM_INIT_AUTOMAKE([foreign -Wall])
AM_PROG_AR AM_PROG_AR
AC_PROG_CXX AC_PROG_CXX

View File

@ -73,7 +73,7 @@ template <class T>
std::ostream & operator<< (std::ostream &output, const Polynomial<T> &op) { std::ostream & operator<< (std::ostream &output, const Polynomial<T> &op) {
int allZero = 1; int allZero = 1;
for (int i=0; i<=op.degree; ++i) for (int i=0; i<=op.degree; ++i)
for (int j=0; j<=i; ++j){ for (int j=0; j<=i; ++j) {
if (op.coef[i*(i+1)/2 + j] == 0.0) continue; if (op.coef[i*(i+1)/2 + j] == 0.0) continue;
allZero = 0; allZero = 0;
if (op.coef[i*(i+1)/2 + j] == -1.0) if (op.coef[i*(i+1)/2 + j] == -1.0)
@ -85,20 +85,20 @@ std::ostream & operator<< (std::ostream &output, const Polynomial<T> &op) {
if (i == 0) if (i == 0)
if (op.coef[0] == T(1)) if (op.coef[0] == T(1))
output << "1"; output << "1";
if (i != 0) if (i != 0) {
if (i-j == 0) if (i-j == 0) {
if (j == 1) if (j == 1)
output << "y"; output << "y";
else else
output << "y^" << j; output << "y^" << j;
else if (i-j == 1) } else if (i-j == 1) {
if (j == 0) if (j == 0)
output << "x"; output << "x";
else if (j == 1) else if (j == 1)
output << "x*y"; output << "x*y";
else else
output << "x*y^" << j; output << "x*y^" << j;
else } else {
if (j == 0) if (j == 0)
output << "x^" << i; output << "x^" << i;
else if (j == 1) else if (j == 1)
@ -106,6 +106,8 @@ std::ostream & operator<< (std::ostream &output, const Polynomial<T> &op) {
else else
output << "x^" << (i-j) << "*y^" << j; output << "x^" << (i-j) << "*y^" << j;
} }
}
}
if (allZero) output << "0"; if (allZero) output << "0";
return output; return output;
} }
@ -230,6 +232,10 @@ T Polynomial<T>::operator() (const T &x, const T &y) const {
return this->evalPolClassic (x,y); return this->evalPolClassic (x,y);
} }
// Defined in lib/polynomial.cpp
template <> IComplex Polynomial<IComplex>::operator() (const IComplex &x, const IComplex &y) const;
template <> MPIComplex Polynomial<MPIComplex>::operator () (const MPIComplex &x, const MPIComplex &y) const;
template <class T> template <class T>
T Polynomial<T>::diffX (const T &x, const T &y) const { T Polynomial<T>::diffX (const T &x, const T &y) const {
// coef[(i*(i+1))/2 + j] is coeficient of monomial of degree 'i', // coef[(i*(i+1))/2 + j] is coeficient of monomial of degree 'i',
@ -311,6 +317,10 @@ T Polynomial<T>::diffY (const T &x, const T &y) const {
return this->evalPolYClassic (x,y); return this->evalPolYClassic (x,y);
} }
// Defined in lib/polynomial.cpp
template <> IComplex Polynomial<IComplex>::diffY (const IComplex &x, const IComplex &y) const;
template <> MPIComplex Polynomial<MPIComplex>::diffY (const MPIComplex &x, const MPIComplex &y) const;
template <class T> template <class T>
T Polynomial<T>::diffXX (const T &x, const T &y) const { T Polynomial<T>::diffXX (const T &x, const T &y) const {

View File

@ -5,7 +5,9 @@
#include <mpfr.h> #include <mpfr.h>
// ACTIVATE ROUND MODE CONTROL // ACTIVATE ROUND MODE CONTROL
#pragma STDC FENV_ACCESS on #ifndef __clang__
#pragma STDC FENV_ACCESS ON
#endif
double * homotopyPath (int degree, double *_coef, double _y0R, double _y0I); double * homotopyPath (int degree, double *_coef, double _y0R, double _y0I);

View File

@ -8,7 +8,9 @@
// ACTIVATE ROUND MODE CONTROL // ACTIVATE ROUND MODE CONTROL
#pragma STDC FENV_ACCESS on #ifndef __clang__
#pragma STDC FENV_ACCESS ON
#endif
typedef std::complex<double> Complex; typedef std::complex<double> Complex;

View File

@ -5,7 +5,9 @@
#define MIN(a,b) (((a) < (b))? (a) : (b)) #define MIN(a,b) (((a) < (b))? (a) : (b))
#define MAX(a,b) (((a) > (b))? (a) : (b)) #define MAX(a,b) (((a) > (b))? (a) : (b))
#pragma STDC FENV_ACCESS on #ifndef __clang__
#pragma STDC FENV_ACCESS ON
#endif
// CONSTRUCTORS // CONSTRUCTORS

View File

@ -5,7 +5,9 @@
// ACTIVATE ROUND MODE CONTROL // ACTIVATE ROUND MODE CONTROL
#pragma STDC FENV_ACCESS on #ifndef __clang__
#pragma STDC FENV_ACCESS ON
#endif
// MACROS FOR MIN AND MAX // MACROS FOR MIN AND MAX
#define MIN(a,b) (((a) < (b))? (a) : (b)) #define MIN(a,b) (((a) < (b))? (a) : (b))

View File

@ -80,21 +80,25 @@ MPInterval & MPInterval::operator= (const MPInterval &op) {
// UPDATE VALUES // UPDATE VALUES
mpfr_set (this->a, op.a, MPFR_RNDD); mpfr_set (this->a, op.a, MPFR_RNDD);
mpfr_set (this->b, op.b, MPFR_RNDU); mpfr_set (this->b, op.b, MPFR_RNDU);
return *this;
} }
MPInterval & MPInterval::operator= (const Interval &op) { MPInterval & MPInterval::operator= (const Interval &op) {
// UPDATE VALUES // UPDATE VALUES
mpfr_set_d (this->a, op.a, MPFR_RNDD); mpfr_set_d (this->a, op.a, MPFR_RNDD);
mpfr_set_d (this->b, op.b, MPFR_RNDU); mpfr_set_d (this->b, op.b, MPFR_RNDU);
return *this;
} }
MPInterval & MPInterval::operator= (const mpfr_t op) { MPInterval & MPInterval::operator= (const mpfr_t op) {
// UPDATE VALUES // UPDATE VALUES
mpfr_set (this->a, op, MPFR_RNDD); mpfr_set (this->a, op, MPFR_RNDD);
mpfr_set (this->b, op, MPFR_RNDU); mpfr_set (this->b, op, MPFR_RNDU);
return *this;
} }
MPInterval & MPInterval::operator= (double op) { MPInterval & MPInterval::operator= (double op) {
// UPDATE VALUES // UPDATE VALUES
mpfr_set_d (this->a, op, MPFR_RNDD); mpfr_set_d (this->a, op, MPFR_RNDD);
mpfr_set_d (this->b, op, MPFR_RNDU); mpfr_set_d (this->b, op, MPFR_RNDU);
return *this;
} }

View File

@ -17,7 +17,9 @@ using namespace std;
// z2 = t(1+0.01i) // z2 = t(1+0.01i)
******************************************/ ******************************************/
#ifndef __clang__
#pragma STDC FENV_ACCESS ON #pragma STDC FENV_ACCESS ON
#endif
// PERFORM A MINIMUM OF 5 ITERATIONS OF NEWTON METHOD TO CORRECT THE APPROXIMATION OF THE ROOT (SUPPOSED TO BE GOOD ENOUGH) // PERFORM A MINIMUM OF 5 ITERATIONS OF NEWTON METHOD TO CORRECT THE APPROXIMATION OF THE ROOT (SUPPOSED TO BE GOOD ENOUGH)
template <> template <>