5

私はコードを書きました:

const double PI = 3.141592653589793;

namespace 
{
    const int N = 8;
    const double points[8] = {-0.9602898564975363, -0.7966664774136267, -0.5255324099163290, -0.1834346424956498,
        0.1834346424956498, 0.5255324099163290, 0.7966664774136267, 0.9602898564975363};
    const double weights[8] = {0.1012285362903706, 0.2223810344533744, 0.3137066458778874, 0.3626837833783621, 0.3626837833783621,
        0.3137066458778874, 0.2223810344533744, 0.1012285362903706};
    const double error = 1e-10;

    template <class TFunction, class TNumber>
    class ChangeOfVariables
    {
        TFunction f;
    public:
        ChangeOfVariables(TFunction f) : f(f){}
        TNumber operator() (TNumber x) { TNumber c=std::cos(x); return f(std::tan(x))/(c*c); } 
    };
}


class Quadrature
{
public:
    Quadrature(void) {};
    ~Quadrature(void) {};

    template <class TFunction, class TNumber>
    TNumber integrate(TFunction f, TNumber a, TNumber b) 
    {
        TNumber result = 0.0;
        for(int i=0; i<N; i++) 
        {
            result+= weights[i]*f(0.5*((b-a)*points[i]+(a+b)));
        }
        return 0.5*(b-a)*result;
    }

    template <class TFunction, class TNumber>
    TNumber integrateToInfty(TFunction f, TNumber a)
    {
        using std::atan; 
        return integrate<ChangeOfVariables<TFunction,TNumber>, TNumber>(ChangeOfVariables<TFunction,TNumber>(f), atan(a), PI/2); 
    }
};

ここで使用されます:

double dampendedExp(double x) {return std::exp(-2.0*x);}
int main()
{
    Quadrature quadrature;
    cout<<"e^(-2x)="<<quadrature.integrateToInfty(dampendedExp, 0)<<endl;
}

しかし、コンパイラは文句を言います:

Error   1   error C2668: 'atan' : ambiguous call to overloaded function c:\users\ga1009\documents\dev\fouriertransform\fouriertransform\quadrature.h    48

アイデアは、atanが定義されているさまざまな数のタイプ(たとえばdouble、および)で機能するようにすることでした。complex<double>どうすれば修正できますか?

4

2 に答える 2

3

Visual Studio は整数として解釈し、整数をキャストする浮動小数点型 ( 、、 )がわからないため0、 の呼び出しで失敗します。std::atanfloatdoublelong double

~\documents\visual studio 2010\projects\so-atan\so-atan\quadrature.h(44): エラー C2668: 'atan': オーバーロードされた関数のあいまいな呼び出し
          c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(553): 'long double atan(long double)' にすることができます
          c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(505): または "float atan(float)"
          c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(108): または "double atan(double)"          
          ~\documents\visual studio 2010\projects\so-atan\so-atan\main.cpp(12):
          [...] "TNumber Quadrature::integrateToInfty(TFunction,TNumber)" で。
          と
          [
              TNumber=int,
              TFunction=double (__cdecl *)(double)
          ]

この動作は、非常に簡単に自分で再現できます。

#include <iostream>

float f(float x){return x;}
double f(double x){return x;}
long double f(long double x){return x;}

int main()
{
    std::cout << f(0) << std::endl;
}

これにより、まったく同じエラーが発生します。これを取り除くには、特定のバージョンの を使用するstd::atan必要std::cosstd::tanありstatic_cast<double>ますstatic_cast<long double>

template <class TFunction, class TNumber>
    TNumber integrateToInfty(TFunction f, TNumber a)
    {
        using std::atan; 
        return integrate<ChangeOfVariables<TFunction,TNumber>, TNumber>
         (ChangeOfVariables<TFunction,TNumber>(f),
              atan(static_cast<long double>(a)), PI/2); 
              /*   ^^^^^^^^^^^^^^^^^^^^^^^^^^^       */          
    }

または、呼び出しで整数の代わりに浮動小数点数を使用します (これははるかに簡単です):

cout<<"e^(-2x)="<<quadrature.integrateToInfty(dampendedExp, 0.0)<<endl;
// cout<<"e^(-2x)="<<quadrature.integrateToInfty(dampendedExp, static_cast<double>(x))<<endl;
于 2012-06-07T15:48:13.013 に答える
-1

正規のソリューションはusing std::atan; return integrate(atan(a), PI/2);です。これにより、の名前空間で引数依存のルックアップが得られますTFunction

于 2012-06-07T14:42:47.820 に答える