/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2012 by M. Ferrero, O. Parcollet, I. Krivenko
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see .
*
******************************************************************************/
#ifndef TRIQS_UTILITY_PADE_APPROXIMANTS_H
#define TRIQS_UTILITY_PADE_APPROXIMANTS_H
#include "pade_approximants.hpp"
#include
#include
namespace triqs { namespace utility {
typedef std::complex dcomplex;
// This implementation is based on a Fortran code written by
// A. Poteryaev
//
// The original algorithm is described in
// H. J. Vidberg, J. W. Serene. J. Low Temp. Phys. 29, 3-4, 179 (1977)
struct gmp_complex {
mpf_class re, im;
gmp_complex operator* (const gmp_complex &rhs){ return { rhs.re*re-rhs.im*im, rhs.re*im+rhs.im*re }; }
friend gmp_complex inverse (const gmp_complex &rhs){ mpf_class d=rhs.re*rhs.re + rhs.im*rhs.im; return { rhs.re/d, -rhs.im/d}; }
gmp_complex operator/ (const gmp_complex &rhs){ return (*this)*inverse(rhs); }
gmp_complex operator+ (const gmp_complex &rhs){ return { rhs.re + re, rhs.im + im }; }
gmp_complex operator- (const gmp_complex &rhs){ return { re - rhs.re, im - rhs.im }; }
friend mpf_class real(const gmp_complex &rhs) { return rhs.re; }
friend mpf_class imag(const gmp_complex &rhs) { return rhs.im; }
gmp_complex& operator= (const std::complex &rhs) { re = real(rhs); im = imag(rhs); return *this; }
friend std::ostream & operator << (std::ostream & out,gmp_complex const & r) { return out << " gmp_complex("< z_in; // Input complex frequency points
arrays::vector a; // Pade coefficients
public:
static const int GMP_default_prec = 256; // Precision of GMP floats to use during a Pade coefficients calculation.
pade_approximant(const arrays::vector & z_in_, const arrays::vector & u_in):
z_in(z_in_), a(z_in.size()) {
int N = z_in.size();
// Change the default precision of GMP floats.
unsigned long old_prec = mpf_get_default_prec();
mpf_set_default_prec(GMP_default_prec); // How do we determine it?
arrays::array g(N,N);
gmp_complex MP_0 = {0.0, 0.0};
g() = MP_0;
for (int f = 0; f