首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在c++11编译器上计算comp_ellint_1(0)

如何在c++11编译器上计算comp_ellint_1(0)
EN

Stack Overflow用户
提问于 2017-11-22 07:13:28
回答 2查看 342关注 0票数 0

我很抱歉,如果这是一个非常愚蠢的问题,但我真的需要这个作为我的硕士论文,我只是找不到一个方法。我需要用eclipse3.8计算第一类完整的椭圆积分。在Ubuntu笔记本电脑上。我的编译器设置为-c -fmessage-length=0 -std=c++11

至于ubuntu版本,它是

@laptop:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:    14.04
Codename:   trusty

而对于gcc编译器来说,它是

laptop:~$ gcc --version 
gcc (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我在mathematical special functions下发现有一个函数double comp_ellint_1( float arg )可以完成这项工作,但据我所知,它只包含在C++ 17中,我还没有安装它,在那里我找不到如何安装它的信息。但是显然有可能在没有C++17的情况下计算函数?因为上面写着:

作为所有特殊函数,只有在实现将comp_ellint_1定义为至少201003L的值,并且用户在包括任何标准库头文件之前定义了__STDCPP_WANT_MATH_SPEC_FUNCS__时,才能保证__STDCPP_MATH_SPEC_FUNCS__<cmath>中可用。

但是他们的示例代码

#define __STDCPP_WANT_MATH_SPEC_FUNCS__ 1
#include <cmath>
#include <iostream>


int main(){

double integral= std::comp_ellint_1(0);
return 0;
}

不起作用,错误为15:22:错误:‘comp_ellint_1’不是‘std’的成员。我也试过

#define _STDCPP_MATH_SPEC_FUNCS__201003L
#define __STDCPP_WANT_MATH_SPEC_FUNCS__ 1
#include <cmath>
#include <iostream>

int main(){

double integral= std::comp_ellint_1(0);
return 0;
}

这会导致相同的错误。它没有说明我是否需要安装某些包来使其工作(如果我确实需要,它们是什么,以及我如何安装它们)。或者我犯了一个不同的错误?

我将非常感谢任何想法如何解决这个问题,所以非常感谢你提前!

EN

回答 2

Stack Overflow用户

发布于 2017-11-23 01:20:20

您的gcc 4.8.5就有这个std::tr1::comp_ellint_1的功能。您将需要#include <tr1/cmath>

在其C++17版本的in首选项页面中提到了这一点

票数 1
EN

Stack Overflow用户

发布于 2018-11-20 15:57:27

如果它不工作或想要在旧版本上运行,您也可以包含boost。要在Visual Studio中做到这一点,您应该包括:

#define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE
#include <boost/lambda/lambda.hpp>
#include <boost/math/special_functions/ellint_1.hpp>  
#include <boost/math/special_functions/ellint_2.hpp>  
#include <boost/math/special_functions/ellint_3.hpp>

然后:

using namespace boost::math;
double Kk = ellint_1(k);
double Ek1 = ellint_2(k) / (q - 4.*al);

要做到这一点,您应该在硬盘上编写一份boost的副本,如C:\boost_1_66_所示

然后,通过编辑项目属性,您应该添加以下链接:

C/C++ Directories->additional include directories: C:\boost_1_66_0
C/C++->Precompiled headers->Precompiled header-> Not use precompiled headers
Linker->general->Additional Library Directories->C:\boost_1_66_0\libs;

另一种方法是包含以下两种计算函数:第一类和第二类完全积分。我使用一个在线工具和ellint_1和2对它进行了测试,效果很好:

    void Complete_Elliptic_Integrals(double x, double* Fk, double* Ek)
    {
        const double PI_2 = 1.5707963267948966192313216916397514; // pi/2
        const double PI_4 = 0.7853981633974483096156608458198757; // pi/4
        double k;      // modulus
        double m;      // the parameter of the elliptic function m = modulus^2
        double a;      // arithmetic mean
        double g;      // geometric mean
        double a_old;  // previous arithmetic mean
        double g_old;  // previous geometric mean
        double two_n;  // power of 2
        double sum;

       if ( x == 0.0 ) {       *Fk = M_PI_2;      *Ek = M_PI_2;       return;    }
       k = fabs(x);
       m = k * k;
       if ( m == 1.0 ) {       *Fk = DBL_MAX;      *Ek = 1.0;       return;    }

       a = 1.0;
       g = sqrt(1.0 - m);
       two_n = 1.0;
       sum = 2.0 - m;
       for (int i=0;i<100;i++) 
       {
          g_old = g;
          a_old = a;
          a = 0.5 * (g_old + a_old);
          g = g_old * a_old;
          two_n += two_n;
          sum -= two_n * (a * a - g);
          if ( fabs(a_old - g_old) <= (a_old * DBL_EPSILON) ) break;
          g = sqrt(g);
       } 
       *Fk = (double) (PI_2 / a);
       *Ek = (double) ((PI_4 / a) * sum);
       return;
    }

不幸的是,它的持续时间是执行ellint_1和ellint_2的两倍

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47424281

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档