00001 #include "SundanceGauss1D.hpp"
00002 #ifdef _MSC_VER
00003 # include "winmath.h"
00004 #endif
00005
00006 using namespace Sundance;
00007 using namespace Sundance;
00008 using namespace Sundance;
00009 using namespace Sundance;
00010 using namespace Sundance;
00011 using namespace Teuchos;
00012
00013 Gauss1D::Gauss1D(int n)
00014 : nodes_(n), weights_(n)
00015 {
00016 computeWeights(n, -1.0, 1.0);
00017 }
00018
00019 Gauss1D::Gauss1D(int n, double a, double b)
00020 : nodes_(n), weights_(n)
00021 {
00022 computeWeights(n, a, b);
00023 }
00024
00025
00026
00027 void Gauss1D::computeWeights(int n, double a, double b)
00028 {
00029 int m = (n+1)/2;
00030
00031 double xMid = (b+a)/2.0;
00032 double halfWidth = (b-a)/2.0;
00033
00034 for (int i=0; i<m; i++)
00035 {
00036
00037 double z = cos(M_PI*(i+0.75)/(n+0.5));
00038 double dP;
00039 double zOld;
00040 double tol = 1.0e-14;
00041
00042 do
00043 {
00044 double p1 = 1.0;
00045 double p2 = 0.0;
00046 for (int j=1; j<=n; j++)
00047 {
00048 double p3 = p2;
00049 p2 = p1;
00050 p1 = ((2.0*j-1.0)*z*p2 - (j-1.0)*p3)/j;
00051 }
00052 dP = n*(z*p1-p2)/(z*z-1.0);
00053 zOld =z;
00054 z = zOld - p1/dP;
00055 }
00056 while ( fabs(z-zOld) > tol );
00057 nodes_[i] = xMid - halfWidth*z;
00058 nodes_[n-i-1] = xMid + halfWidth*z;
00059 weights_[i] = 2.0*halfWidth/((1.0-z*z)*dP*dP);
00060 weights_[n-i-1] = weights_[i];
00061 }
00062 }
00063
00064
00065 bool Gauss1D::unitTest()
00066 {
00067 std::cerr << "------------------ Gauss1D unit test ----------------------"
00068 << std::endl;
00069
00070 Gauss1D q(20, 0.0, M_PI);
00071
00072 double sum = 0.0;
00073 for (int i=0; i<q.nPoints(); i++)
00074 {
00075 sum += q.weights()[i]*sin(q.nodes()[i]);
00076 }
00077 std::cerr << "integral of sin(x) over [0, pi] = " << sum << std::endl;
00078 double sumErr = fabs(sum - 2.0);
00079 bool sumPass = sumErr < 1.0e-10;
00080 std::cerr << "error = " << sumErr << std::endl;
00081 if (sumPass) std::cerr << "Gauss1D sine test PASSED" << std::endl;
00082 else std::cerr << "Gauss1D sine test FAILED" << std::endl;
00083 std::cerr << "------------------ End Gauss1D unit test ----------------------"
00084 << std::endl;
00085 return sumPass;
00086 }
00087
00088