Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从0到无穷大的数值积分_C_Gcc_Ubuntu 12.04_Numerical Integration - Fatal编程技术网

C 从0到无穷大的数值积分

C 从0到无穷大的数值积分,c,gcc,ubuntu-12.04,numerical-integration,C,Gcc,Ubuntu 12.04,Numerical Integration,我的目标是用C语言计算电子到氢原子核距离的概率分布函数(PDF)的数值积分。我已经编写了一个示例代码,但是它无法正确地找到数值,因为我无法按照我的意见尽可能地增加限制。我还包括了该库,但我不能使用以下帖子中所述的值作为积分边界:。在这种情况下有什么补救办法?也许应该换成另一种编程语言?任何帮助和建议都将不胜感激,提前感谢 编辑:在一些值之后,我得到了错误分段错误。我已经用Wolframalpha检查了积分的实际结果为0.0372193。除此之外,如果我以较小的量增加k,我得到零,这就是我定义r[

我的目标是用C语言计算电子到氢原子核距离的概率分布函数(PDF)的数值积分。我已经编写了一个示例代码,但是它无法正确地找到数值,因为我无法按照我的意见尽可能地增加限制。我还包括了该库,但我不能使用以下帖子中所述的值作为积分边界:。在这种情况下有什么补救办法?也许应该换成另一种编程语言?任何帮助和建议都将不胜感激,提前感谢

编辑:在一些值之后,我得到了错误分段错误。我已经用Wolframalpha检查了积分的实际结果为0.0372193。除此之外,如果我以较小的量增加k,我得到零,这就是我定义r[k]=k的原因,我知道它应该更小,以提高精度

#include <stdio.h>
#include <math.h>
#include <limits.h>
#define a0 0.53 
int N = 200000;
// This value of N is the highest possible number in long double
// data format. Change its value  to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[], long double f[]) {
  int i;
  long double dx = x[1]-x[0];
  long double sum = 0.5*(f[0]+f[N]);

    for (i = 1; i <  N; i++) 
        sum+=f[i];
  return sum*dx;  
}
main() {

    long double P[N], r[N], a;
    // Declare and initialize the loop variable
    int k = 0;
    for (k = 0; k <  N; k++)
    {
        r[k] = k ;
        P[k] = r[k] * r[k] * exp( -2*r[k] / a0);
        //printf("%.20Lf \n", r[k]);
        //printf("%.20Lf \n", P[k]);
    }
    a = trapezoid(r, P);    
    printf("%.20Lf \n", a);
}
#包括
#包括
#包括
#定义a0 0.53
int N=200000;
//N的这个值是长双精度中可能的最高值
//数据格式。更改其值以调整积分精度
//和计算时间。
//离散积分可定义如下:
长双梯形(长双x[],长双f[]){
int i;
长双dx=x[1]-x[0];
长双和=0.5*(f[0]+f[N]);
对于(i=1;i
最后代码:

#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define a0 0.53 
#define N LLONG_MAX
// This value of N is the highest possible number in long double
// data format. Change its value  to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[],long double f[]) {
  int i;
  long double dx = x[1]-x[0];
  long double sum = 0.5*(f[0]+f[N]);

    for (i = 1; i <  N; i++) 
        sum+=f[i];
  return sum*dx;  
}
main() {
    printf("%Ld", LLONG_MAX);
    long double * P = malloc(N * sizeof(long double));
    long double * r = malloc(N * sizeof(long double));
    // Declare and initialize the loop variable
    int k = 0;
    long double integral;
    for (k = 1; k <  N; k++)
        {
        P[k] = r[k] * r[k] * expl( -2*r[k] / a0);
        }
    integral = trapezoid(r, P);
    printf("%Lf", integral);

}
#包括
#包括
#包括
#包括
#定义a0 0.53
#定义N LLONG_MAX
//N的这个值是长双精度中可能的最高值
//数据格式。更改其值以调整积分精度
//和计算时间。
//离散积分可定义如下:
长双梯形(长双x[],长双f[]){
int i;
长双dx=x[1]-x[0];
长双和=0.5*(f[0]+f[N]);
对于(i=1;i
编辑上一个工作代码:

#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define a0 0.53 
#define N LONG_MAX/100
// This value of N is the highest possible number in long double
// data format. Change its value  to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[],long double f[]) {
  int i;
  long double dx = x[1]-x[0];
  long double sum = 0.5*(f[0]+f[N]);

    for (i = 1; i <  N; i++) 
        sum+=f[i];
  return sum*dx;  
}
main() {
    printf("%Ld \n", LLONG_MAX);
    long double * P = malloc(N * sizeof(long double));
    long double * r = malloc(N * sizeof(long double));
    // Declare and initialize the loop variable
    int k = 0;
    long double integral;
    for (k = 1; k <  N; k++)
        {
        r[k] = k / 100000.0;
        P[k] = r[k] * r[k] * expl( -2*r[k] / a0);
        }
    integral = trapezoid(r, P);
    printf("%.15Lf \n", integral);
    free((void *)P);
    free((void *)r);
}
#包括
#包括
#包括
#包括
#定义a0 0.53
#定义N长\u最大值/100
//N的这个值是长双精度中可能的最高值
//数据格式。更改其值以调整积分精度
//和计算时间。
//离散积分可定义如下:
长双梯形(长双x[],长双f[]){
int i;
长双dx=x[1]-x[0];
长双和=0.5*(f[0]+f[N]);
对于(i=1;i
特别是,我已经通过在除法运算中使用浮点数修改了r[k]的定义,从而得到了一个长双精度的结果,而且正如我在上一篇评论中所说的,我不能使用大于long_MAX/100的Ns,我认为我应该进一步研究代码和malloc来解决这个问题。我已经找到了精确的值,它是通过取极限解析得到的;我已经用TI-89钛和Wolframalpha(数值和分析)证实了结果,除了我自己。当区间大小减小时,梯形法则运行得很好。非常感谢这里所有的海报为他们的想法。对于2147483647 LONG_MAX的值,顺便说一句,如果限制不在10到308次方的范围内,那么它并没有我预期的那么大。

从数值的角度来看 通常的梯形方法不适用于不适当的积分。因此,高斯求积规则更好,因为它们不仅提供2n-1精度(即,对于2n-1次多项式,它们将返回正确的解),而且还通过使用正确的权重函数来管理不正确的积分

如果两边的积分都不正确,则应尝试,否则使用

“溢出”错误
p
的大小约为3MB,
r
也是如此。记忆太多了。改为分配内存:

long double * P = malloc(N * sizeof(long double));
long double * r = malloc(N * sizeof(long double));
如果您不再需要
p
r
,请不要忘记包含
,并在
p
r
上使用
free
。此外,您可能无法访问第N个条目,因此
f[N]
是错误的

利用高斯-拉盖尔求积 现在Gauss Laguerre使用
exp(-x)
作为权重函数。如果您不熟悉高斯求积:
E(f)
的结果是
w*f
的积分,其中
w
是权函数

您的
f
如下所示:

f x = x^2 * exp (-2 * x / a)
等一下
f
已经包含
exp(-term)
,因此我们可以用
t=x*a/2
替换x,并得到

f' x = (t * a/2)^2 * exp(-t) * a/2
由于
exp(-t)
已经是我们权重函数的一部分,因此您的函数现在完全适合高斯-拉盖尔求积。结果
f' x = (t * a/2)^2 * exp(-t) * a/2
#include <stdio.h>
#include <math.h>

/* x[] and a[] taken from 
 * https://de.wikipedia.org/wiki/Gau%C3%9F-Quadratur#Gau.C3.9F-Laguerre-Integration
 * Calculating them by hand is a little bit cumbersome
*/
const int gauss_rule_length = 3;
const double gauss_x[] = {0.415774556783, 2.29428036028, 6.28994508294};
const double gauss_a[] = {0.711093009929, 0.278517733569, 0.0103892565016};

double f(double x){
    return x *.53/2 * x *.53/2 * .53/2;
}

int main(){
    int i;
    double sum = 0;
    for(i = 0; i < gauss_rule_length; ++i){
        sum += gauss_a[i] * f(gauss_x[i]);
    }
    printf("%.10lf\n",sum); /* 0.0372192500 */
    return 0;
}