怎么做 数值积分 (什么数值方法,以及使用什么技巧)对于无限范围内的一维积分,其中被积函数中的一个或多个函数是 一维量子谐振子 波函数。除此之外,我想计算谐振子基础上某个函数的矩阵元素:

n(x) = Nn Hn(x) 指数 (-x2/2)
其中Hn(x) 是 埃尔米特多项式

V米,n = \int_{-无穷大}^{无穷大} phi(x) V(x) phin(x) dx

同样在存在不同宽度的量子谐波波函数的情况下。

问题是波函数 phin(x) 具有振荡行为,这对于大型 n, ,以及 GSL(GNU 科学库)中的自适应 Gauss-Kronrod 求积等算法计算时间长,并且误差较大。

有帮助吗?

解决方案

一个不完整的答案,因为我现在时间有点短;如果其他人不能完成图片,我可以稍后提供更多细节。

  1. 随时随地应用波函数的正交性。这应该会显着减少计算量。

  2. 尽可能地进行分析。升力常数、按部分分割积分等等。隔离感兴趣的区域;大多数波函数都是带限的,减少感兴趣的区域将大大节省工作量。

  3. 对于求积本身,您可能希望将波函数分成三部分并分别积分:中心的振荡位加上两侧的指数衰减尾部。如果波函数是奇数,那么你很幸运,尾部会相互抵消,这意味着你只需要担心中心。对于偶数波函数,您只需对一积分并加倍(对称性万岁!)。否则,使用高阶高斯-拉盖尔求积规则对尾部进行积分。你可能需要自己计算规则;我不知道表格是否列出了好的高斯-拉盖尔规则,因为它们不经常使用。您可能还想检查规则中节点数量增加时的错误行为;我已经很久没有使用高斯-拉盖尔规则了,我不记得它们是否表现出龙格现象。使用您喜欢的任何方法整合中心部分;当然,Gauss-Kronrod 是一个可靠的选择,但还有 Fejer 求积(有时可以更好地扩展到大量节点,这可能在振荡被积函数上效果更好),甚至梯形规则(对于某些振荡函数表现出惊人的准确性) )。选择一个并尝试一下;如果结果不佳,请尝试另一种方法。

SO 有史以来最难的问题?几乎不 :)

其他提示

我会推荐一些其他的东西:

  1. 尝试将函数转换到有限域以使集成更易于管理。
  2. 尽可能使用对称性 - 将其分解为从负无穷到零和从零到无穷大的两个积分之和,并查看该函数是对称的还是反对称的。它可以让你的计算变得更容易。
  3. 调查 高斯-拉盖尔求积 看看它是否可以帮助你。

WKB近似

我不打算解释或限定,现在任何的这一权利。这段代码写成的,可能不正确。我甚至不知道这是否是我一直在寻找的代码,我只记得几年前,我做了这个问题,并在寻找我的档案,我发现这一点。您需要将自己绘制的输出,提供了一些指导。我会说,积分超过无限范围的是,我处理和在所述代码的执行它指出在“无穷大”(其数值只是意味着大)的舍入误差的问题。

// compile g++ base.cc -lm
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <math.h>

using namespace std;

int main ()
        {
        double xmax,dfx,dx,x,hbar,k,dE,E,E_0,m,psi_0,psi_1,psi_2;
        double w,num;
        int n,temp,parity,order;
        double last;
        double propogator(double E,int parity);
        double eigen(double E,int parity);
         double f(double x, double psi, double dpsi);
        double g(double x, double psi, double dpsi);
        double rk4(double x, double psi, double dpsi, double E);

        ofstream datas ("test.dat");

        E_0= 1.602189*pow(10.0,-19.0);// ev joules conversion
        dE=E_0*.001;
//w^2=k/m                 v=1/2 k x^2             V=??? = E_0/xmax   x^2      k-->
//w=sqrt( (2*E_0)/(m*xmax) );
//E=(0+.5)*hbar*w;

        cout << "Enter what energy level your looking for, as an (0,1,2...) INTEGER: ";
        cin >> order;

        E=0;
        for (n=0; n<=order; n++)
                {
                parity=0;
//if its even parity is 1 (true)
                temp=n;
                if ( (n%2)==0 ) {parity=1; }
                cout << "Energy " << n << " has these parameters: ";
                E=eigen(E,parity);
                if (n==order)
                        {
                        propogator(E,parity);
                        cout <<" The postive values of the wave function were written to sho.dat \n";
                        cout <<" In order to plot the data should be reflected about the y-axis \n";
                        cout <<"  evenly for even energy levels and oddly for odd energy levels\n";
                        }
                E=E+dE;
                }
        }

double propogator(double E,int parity)
        {
        ofstream datas ("sho.dat") ;

        double hbar =1.054*pow(10.0,-34.0);
        double m =9.109534*pow(10.0,-31.0);
        double E_0= 1.602189*pow(10.0,-19.0);
        double dx =pow(10.0,-10);
        double xmax= 100*pow(10.0,-10.0)+dx;
        double dE=E_0*.001;
        double last=1;
        double x=dx;
        double psi_2=0.0;
        double psi_0=0.0;
        double psi_1=1.0;
//      cout <<parity << " parity passsed \n";
        psi_0=0.0;
        psi_1=1.0;
        if (parity==1)
                {
                psi_0=1.0;
                psi_1=m*(1.0/(hbar*hbar))* dx*dx*(0-E)+1 ;
                }

        do
                {
                datas << x << "\t" << psi_0 << "\n";
                psi_2=(2.0*m*(dx/hbar)*(dx/hbar)*(E_0*(x/xmax)*(x/xmax)-E)+2.0)*psi_1-psi_0;
//cout << psi_1 << "=psi_1\n";
                psi_0=psi_1;
                psi_1=psi_2;
                x=x+dx;
                } while ( x<= xmax);
//I return 666 as a dummy value sometimes to check the function has run
        return 666;
        }


   double eigen(double E,int parity)
        {
        double hbar =1.054*pow(10.0,-34.0);
        double m =9.109534*pow(10.0,-31.0);
        double E_0= 1.602189*pow(10.0,-19.0);
        double dx =pow(10.0,-10);
        double xmax= 100*pow(10.0,-10.0)+dx;
        double dE=E_0*.001;
        double last=1;
        double x=dx;
        double psi_2=0.0;
        double psi_0=0.0;
        double psi_1=1.0;
        do
                {
                psi_0=0.0;
                psi_1=1.0;

                if (parity==1)
                        {double psi_0=1.0; double psi_1=m*(1.0/(hbar*hbar))* dx*dx*(0-E)+1 ;}
                x=dx;
                do
                        {
                        psi_2=(2.0*m*(dx/hbar)*(dx/hbar)*(E_0*(x/xmax)*(x/xmax)-E)+2.0)*psi_1-psi_0;
                        psi_0=psi_1;
                        psi_1=psi_2;
                        x=x+dx;
                        } while ( x<= xmax);


                if ( sqrt(psi_2*psi_2)<=1.0*pow(10.0,-3.0))
                        {
                        cout << E << " is an eigen energy and " << psi_2 << " is psi of 'infinity'  \n";
                        return E;
                        }
                else
                        {
                        if ( (last >0.0 && psi_2<0.0) ||( psi_2>0.0 && last<0.0) )
                                {
                                E=E-dE;
                                dE=dE/10.0;
                                }
                        }
                last=psi_2;
                E=E+dE;
                } while (E<=E_0);
        }

如果这个代码似乎是正确的,错误的,有趣的或你有具体问题,问我就回答他们。

我是一名学生,主修物理,我也遇到了问题。这些天我一直在想这个问题并得到我自己的答案。我认为它可以帮助你解决这个问题。

1.In GSL,有功能可以帮助您将振荡功能 - qawo&qawf。也许你可以设置一个值,的。和积分可被分离成丝束份,[0,]和[,pos_infinity]。在第一个间隔,可以使用任何想要的GSL积分功能,并在第二时间间隔中,可以使用qawo或qawf。

2.Or可以将功能集成到一个上限值时, B'/ em>的,集成在[0, B'/ EM>]。因此,整合可以采用高斯闻名遐迩的方法来计算,这是在GSL提供。虽然有可能,如果你设置的 b中的真正价值和计算值之间存在一些差异,但的正确,差异可以忽略不计。只要差小于你想要的精确度。并使用GSL功能这种方法只调用一次,就可以多次使用,因为返回值是点与相应的权重,整合仅仅是F(十一)*无线网络,以获取更多信息,您可以搜索高斯勒的总和正交维基百科上。多个和加法操作比积分快得多。

3.有也可以计算出无穷区域整合功能 - qagi,您可以在GSL用户指南中的搜索。但是,这是每次叫你需要计算的融合,而这可能会导致某些耗时的,但我不知道多久会在你的程序中使用。

我建议NO.2选择我提供。

如果你打算用较少谐振子功能工作超过n = 100,你可能会想尝试:

http://www.mymathlib.com/quadrature/gauss_hermite.html

在程序计算通过与100点零权重(H_100的零)高斯厄米正交的积分。一旦你超过Hermite_100的积分都不够准确。

使用这种积分方法我写了一个程序计算正是你想要的计算和它的作品相当不错。此外,有可能是一种通过使用埃尔米特多项式零点的渐近形式超越N = 100,但我还没有看进去了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top