⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmomof.c

📁 该文件为c++的数学函数库!是一个非常有用的编程工具.它含有各种数学函数,为科学计算、工程应用等程序编写提供方便!
💻 C
字号:
/* integration/qmomof.c *  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <config.h>#include <stdlib.h>#include <gsl/gsl_integration.h>#include <gsl/gsl_errno.h>static voidcompute_moments (double par, double * cheb);static intdgtsl (size_t n, double *c, double *d, double *e, double *b);gsl_integration_qawo_table *gsl_integration_qawo_table_alloc (double omega, double L,                                   enum gsl_integration_qawo_enum sine,                                  size_t n){  gsl_integration_qawo_table *t;  double * chebmo;  if (n == 0)    {      GSL_ERROR_VAL ("table length n must be positive integer",                        GSL_EDOM, 0);    }  t = (gsl_integration_qawo_table *)    malloc (sizeof (gsl_integration_qawo_table));  if (t == 0)    {      GSL_ERROR_VAL ("failed to allocate space for qawo_table struct",                        GSL_ENOMEM, 0);    }  chebmo = (double *)  malloc (25 * n * sizeof (double));  if (chebmo == 0)    {      free (t);      GSL_ERROR_VAL ("failed to allocate space for chebmo block",                        GSL_ENOMEM, 0);    }  t->n = n;  t->sine = sine;  t->omega = omega;  t->L = L;  t->par = 0.5 * omega * L;  t->chebmo = chebmo;  /* precompute the moments */  {     size_t i;    double scale = 1.0;    for (i = 0 ; i < t->n; i++)      {        compute_moments (t->par * scale, t->chebmo + 25*i);        scale *= 0.5;      }  }  return t;}intgsl_integration_qawo_table_set (gsl_integration_qawo_table * t,                                    double omega, double L,                                    enum gsl_integration_qawo_enum sine){  t->omega = omega;  t->sine = sine;  t->L = L;  t->par = 0.5 * omega * L;  /* recompute the moments */  {     size_t i;    double scale = 1.0;    for (i = 0 ; i < t->n; i++)      {        compute_moments (t->par * scale, t->chebmo + 25*i);        scale *= 0.5;      }  }  return GSL_SUCCESS;}intgsl_integration_qawo_table_set_length (gsl_integration_qawo_table * t,                                           double L){  /* return immediately if the length is the same as the old length */  if (L == t->L)    return GSL_SUCCESS;  /* otherwise reset the table and compute the new parameters */  t->L = L;  t->par = 0.5 * t->omega * L;  /* recompute the moments */  {     size_t i;    double scale = 1.0;    for (i = 0 ; i < t->n; i++)      {        compute_moments (t->par * scale, t->chebmo + 25*i);        scale *= 0.5;      }  }  return GSL_SUCCESS;}voidgsl_integration_qawo_table_free (gsl_integration_qawo_table * t){  free (t->chebmo);  free (t);}static voidcompute_moments (double par, double *chebmo){  double v[28], d[25], d1[25], d2[25];  const size_t noeq = 25;    const double par2 = par * par;  const double par4 = par2 * par2;  const double par22 = par2 + 2.0;  const double sinpar = sin (par);  const double cospar = cos (par);  size_t i;  /* compute the chebyschev moments with respect to cosine */  double ac = 8 * cospar;  double as = 24 * par * sinpar;  v[0] = 2 * sinpar / par;  v[1] = (8 * cospar + (2 * par2 - 8) * sinpar / par) / par2;  v[2] = (32 * (par2 - 12) * cospar          + (2 * ((par2 - 80) * par2 + 192) * sinpar) / par) / par4;  if (fabs (par) <= 24)    {      /* compute the moments as the solution of a boundary value         problem using the asyptotic expansion as an endpoint */            double an2, ass, asap;      double an = 6;      size_t k;      for (k = 0; k < noeq - 1; k++)        {          an2 = an * an;          d[k] = -2 * (an2 - 4) * (par22 - 2 * an2);          d2[k] = (an - 1) * (an - 2) * par2;          d1[k + 1] = (an + 3) * (an + 4) * par2;          v[k + 3] = as - (an2 - 4) * ac;          an = an + 2.0;        }      an2 = an * an;      d[noeq - 1] = -2 * (an2 - 4) * (par22 - 2 * an2);      v[noeq + 2] = as - (an2 - 4) * ac;      v[3] = v[3] - 56 * par2 * v[2];      ass = par * sinpar;      asap = (((((210 * par2 - 1) * cospar - (105 * par2 - 63) * ass) / an2                - (1 - 15 * par2) * cospar + 15 * ass) / an2                - cospar + 3 * ass) / an2               - cospar) / an2;      v[noeq + 2] = v[noeq + 2] - 2 * asap * par2 * (an - 1) * (an - 2);      dgtsl (noeq, d1, d, d2, v + 3);    }  else    {      /* compute the moments by forward recursion */      size_t k;      double an = 4;      for (k = 3; k < 13; k++)        {          double an2 = an * an;          v[k] = ((an2 - 4) * (2 * (par22 - 2 * an2) * v[k - 1] - ac)                  + as - par2 * (an + 1) * (an + 2) * v[k - 2])             / (par2 * (an - 1) * (an - 2));          an = an + 2.0;        }    }  for (i = 0; i < 13; i++)    {      chebmo[2 * i] = v[i];    }  /* compute the chebyschev moments with respect to sine */  v[0] = 2 * (sinpar - par * cospar) / par2;  v[1] = (18 - 48 / par2) * sinpar / par2 + (-2 + 48 / par2) * cospar / par;  ac = -24 * par * cospar;  as = -8 * sinpar;  if (fabs (par) <= 24)    {      /* compute the moments as the solution of a boundary value         problem using the asyptotic expansion as an endpoint */      size_t k;      double an2, ass, asap;      double an = 5;      for (k = 0; k < noeq - 1; k++)        {          an2 = an * an;          d[k] = -2 * (an2 - 4) * (par22 - 2 * an2);          d2[k] = (an - 1) * (an - 2) * par2;          d1[k + 1] = (an + 3) * (an + 4) * par2;          v[k + 2] = ac + (an2 - 4) * as;          an = an + 2.0;        }            an2 = an * an;      d[noeq - 1] = -2 * (an2 - 4) * (par22 - 2 * an2);      v[noeq + 1] = ac + (an2 - 4) * as;      v[2] = v[2] - 42 * par2 * v[1];      ass = par * cospar;      asap = (((((105 * par2 - 63) * ass - (210 * par2 - 1) * sinpar) / an2                + (15 * par2 - 1) * sinpar                - 15 * ass) / an2 - sinpar - 3 * ass) / an2 - sinpar) / an2;      v[noeq + 1] = v[noeq + 1] - 2 * asap * par2 * (an - 1) * (an - 2);      dgtsl (noeq, d1, d, d2, v + 2);    }  else    {      /* compute the moments by forward recursion */      size_t k;      double an = 3;      for (k = 2; k < 12; k++)        {          double an2 = an * an;          v[k] = ((an2 - 4) * (2 * (par22 - 2 * an2) * v[k - 1] + as)                  + ac - par2 * (an + 1) * (an + 2) * v[k - 2])             / (par2 * (an - 1) * (an - 2));          an = an + 2.0;        }    }  for (i = 0; i < 12; i++)    {      chebmo[2 * i + 1] = v[i];    }}static intdgtsl (size_t n, double *c, double *d, double *e, double *b){  /* solves a tridiagonal matrix A x = b           c[1 .. n - 1]   subdiagonal of the matrix A     d[0 .. n - 1]   diagonal of the matrix A     e[0 .. n - 2]   superdiagonal of the matrix A     b[0 .. n - 1]   right hand side, replaced by the solution vector x */  size_t k;  c[0] = d[0];  if (n == 0)    {      return GSL_SUCCESS;    }  if (n == 1)    {      b[0] = b[0] / d[0] ;      return GSL_SUCCESS;    }  d[0] = e[0];  e[0] = 0;  e[n - 1] = 0;  for (k = 0; k < n - 1; k++)    {      size_t k1 = k + 1;      if (fabs (c[k1]) >= fabs (c[k]))        {          {            double t = c[k1];            c[k1] = c[k];            c[k] = t;          };          {            double t = d[k1];            d[k1] = d[k];            d[k] = t;          };          {            double t = e[k1];            e[k1] = e[k];            e[k] = t;          };          {            double t = b[k1];            b[k1] = b[k];            b[k] = t;          };        }      if (c[k] == 0)        {          return GSL_FAILURE ;        }      {        double t = -c[k1] / c[k];        c[k1] = d[k1] + t * d[k];        d[k1] = e[k1] + t * e[k];        e[k1] = 0;        b[k1] = b[k1] + t * b[k];      }    }  if (c[n - 1] == 0)    {      return GSL_FAILURE;    }  b[n - 1] = b[n - 1] / c[n - 1];  b[n - 2] = (b[n - 2] - d[n - 2] * b[n - 1]) / c[n - 2];  for (k = n ; k > 2; k--)    {      size_t kb = k - 3;      b[kb] = (b[kb] - d[kb] * b[kb + 1] - e[kb] * b[kb + 2]) / c[kb];    }  return GSL_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -