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

📄 hyperg_u.c

📁 开放gsl矩阵运算
💻 C
📖 第 1 页 / 共 3 页
字号:
          Uap1 = -(Uam1 + (b-2.0*ap-x)*Ua)/(ap*(1.0+ap-b));          Uam1 = Ua;          Ua   = Uap1;	  RESCALE_2(Ua,Uam1,scale_factor,scale_count_for);        }        Ua1_for_val  = Ua;	Ua1_for_err  = fabs(Ua) * fabs(r_Ua.err/r_Ua.val);	Ua1_for_err += 2.0 * GSL_DBL_EPSILON * (fabs(a1-a0)+1.0) * fabs(Ua1_for_val);      }      /* Now do the matching to produce the final result.       */      if(Ua1_bck_val == 0.0) {        result->val = 0.0;	result->err = 0.0;	result->e10 = 0;        GSL_ERROR ("error", GSL_EZERODIV);      }      else if(Ua1_for_val == 0.0) {        /* Should never happen. */        UNDERFLOW_ERROR_E10(result);      }      else {        double lns = (scale_count_for - scale_count_bck)*log(scale_factor);	double ln_for_val = log(fabs(Ua1_for_val));	double ln_for_err = GSL_DBL_EPSILON + fabs(Ua1_for_err/Ua1_for_val);	double ln_bck_val = log(fabs(Ua1_bck_val));	double ln_bck_err = GSL_DBL_EPSILON + fabs(Ua1_bck_err/Ua1_bck_val);        double lnr_val = lm_for.val + ln_for_val - ln_bck_val + lns;	double lnr_err = lm_for.err + ln_for_err + ln_bck_err	  + 2.0 * GSL_DBL_EPSILON * (fabs(lm_for.val) + fabs(ln_for_val) + fabs(ln_bck_val) + fabs(lns));	double sgn = GSL_SIGN(Ua1_for_val) * GSL_SIGN(Ua1_bck_val);        int stat_e = gsl_sf_exp_err_e10_e(lnr_val, lnr_err, result);	result->val *= sgn;        return GSL_ERROR_SELECT_3(stat_e, stat_bck, stat_for);      }    }  }}/* Handle b >= 1 for generic a,b values. */staticinthyperg_U_bge1(const double a, const double b, const double x,              gsl_sf_result_e10 * result){  const double rinta = floor(a+0.5);  const int a_neg_integer = (a < 0.0 && fabs(a - rinta) < INT_THRESHOLD);  if(a == 0.0) {    result->val = 1.0;    result->err = 0.0;    result->e10 = 0;    return GSL_SUCCESS;  }  else if(a_neg_integer && fabs(rinta) < INT_MAX) {    /* U(-n,b,x) = (-1)^n n! Laguerre[n,b-1,x]     */    const int n = -(int)rinta;    const double sgn = (GSL_IS_ODD(n) ? -1.0 : 1.0);    gsl_sf_result lnfact;    gsl_sf_result L;    const int stat_L = gsl_sf_laguerre_n_e(n, b-1.0, x, &L);    gsl_sf_lnfact_e(n, &lnfact);    {      const int stat_e = gsl_sf_exp_mult_err_e10_e(lnfact.val, lnfact.err,                                                      sgn*L.val, L.err,                                                      result);      return GSL_ERROR_SELECT_2(stat_e, stat_L);    }  }  else if(ASYMP_EVAL_OK(a,b,x)) {    const double ln_pre_val = -a*log(x);    const double ln_pre_err = 2.0 * GSL_DBL_EPSILON * fabs(ln_pre_val);    gsl_sf_result asymp;    int stat_asymp = hyperg_zaU_asymp(a, b, x, &asymp);    int stat_e = gsl_sf_exp_mult_err_e10_e(ln_pre_val, ln_pre_err,                                              asymp.val, asymp.err,                                              result);    return GSL_ERROR_SELECT_2(stat_e, stat_asymp);  }  else if(fabs(a) <= 1.0) {    gsl_sf_result rU;    double ln_multiplier;    int stat_U = hyperg_U_small_a_bgt0(a, b, x, &rU, &ln_multiplier);    int stat_e = gsl_sf_exp_mult_err_e10_e(ln_multiplier, 2.0*GSL_DBL_EPSILON*fabs(ln_multiplier), rU.val, rU.err, result);    return GSL_ERROR_SELECT_2(stat_U, stat_e);  }  else if(SERIES_EVAL_OK(a,b,x)) {    gsl_sf_result ser;    const int stat_ser = hyperg_U_series(a, b, x, &ser);    result->val = ser.val;    result->err = ser.err;    result->e10 = 0;    return stat_ser;  }  else if(a < 0.0) {    /* Recurse backward on a and then upward on b.     */    const double scale_factor = GSL_SQRT_DBL_MAX;    const double a0 = a - floor(a) - 1.0;    const double b0 = b - floor(b) + 1.0;    int scale_count = 0;    double lm_0, lm_1;    double lm_max;    gsl_sf_result r_Uap1;    gsl_sf_result r_Ua;    int stat_0 = hyperg_U_small_a_bgt0(a0+1.0, b0, x, &r_Uap1, &lm_0);    int stat_1 = hyperg_U_small_a_bgt0(a0,     b0, x, &r_Ua,   &lm_1);    int stat_e;    double Uap1 = r_Uap1.val;    double Ua   = r_Ua.val;    double Uam1;    double ap;    lm_max = GSL_MAX(lm_0, lm_1);    Uap1 *= exp(lm_0-lm_max);    Ua   *= exp(lm_1-lm_max);    /* Downward recursion on a.     */    for(ap=a0; ap>a+0.1; ap -= 1.0) {      Uam1 = ap*(b0-ap-1.0)*Uap1 + (x+2.0*ap-b0)*Ua;      Uap1 = Ua;      Ua   = Uam1;      RESCALE_2(Ua,Uap1,scale_factor,scale_count);    }    if(b < 2.0) {      /* b == b0, so no recursion necessary       */      const double lnscale = log(scale_factor);      gsl_sf_result lnm;      gsl_sf_result y;      lnm.val = lm_max + scale_count * lnscale;      lnm.err = 2.0 * GSL_DBL_EPSILON * (fabs(lm_max) + scale_count * fabs(lnscale));      y.val  = Ua;      y.err  = fabs(r_Uap1.err/r_Uap1.val) * fabs(Ua);      y.err += fabs(r_Ua.err/r_Ua.val) * fabs(Ua);      y.err += 2.0 * GSL_DBL_EPSILON * (fabs(a-a0) + 1.0) * fabs(Ua);      y.err *= fabs(lm_0-lm_max) + 1.0;      y.err *= fabs(lm_1-lm_max) + 1.0;      stat_e = gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result);    }    else {      /* Upward recursion on b.       */      const double err_mult = fabs(b-b0) + fabs(a-a0) + 1.0;      const double lnscale = log(scale_factor);      gsl_sf_result lnm;      gsl_sf_result y;      double Ubm1 = Ua; 				/* U(a,b0)   */      double Ub   = (a*(b0-a-1.0)*Uap1 + (a+x)*Ua)/x;	/* U(a,b0+1) */      double Ubp1;      double bp;      for(bp=b0+1.0; bp<b-0.1; bp += 1.0) {    	Ubp1 = ((1.0+a-bp)*Ubm1 + (bp+x-1.0)*Ub)/x;    	Ubm1 = Ub;    	Ub   = Ubp1;        RESCALE_2(Ub,Ubm1,scale_factor,scale_count);      }      lnm.val = lm_max + scale_count * lnscale;      lnm.err = 2.0 * GSL_DBL_EPSILON * (fabs(lm_max) + fabs(scale_count * lnscale));      y.val = Ub;      y.err  = 2.0 * err_mult * fabs(r_Uap1.err/r_Uap1.val) * fabs(Ub);      y.err += 2.0 * err_mult * fabs(r_Ua.err/r_Ua.val) * fabs(Ub);      y.err += 2.0 * GSL_DBL_EPSILON * err_mult * fabs(Ub);      y.err *= fabs(lm_0-lm_max) + 1.0;      y.err *= fabs(lm_1-lm_max) + 1.0;      stat_e = gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result);    }    return GSL_ERROR_SELECT_3(stat_e, stat_0, stat_1);  }  else if(b >= 2*a + x) {    /* Recurse forward from a near zero.     * Note that we cannot cross the singularity at     * the line b=a+1, because the only way we could     * be in that little wedge is if a < 1. But we     * have already dealt with the small a case.     */    int scale_count = 0;    const double a0 = a - floor(a);    const double scale_factor = GSL_SQRT_DBL_MAX;    double lnscale;    double lm_0, lm_1, lm_max;    gsl_sf_result r_Uam1;    gsl_sf_result r_Ua;    int stat_0 = hyperg_U_small_a_bgt0(a0-1.0, b, x, &r_Uam1, &lm_0);    int stat_1 = hyperg_U_small_a_bgt0(a0,     b, x, &r_Ua,   &lm_1);    int stat_e;    gsl_sf_result lnm;    gsl_sf_result y;    double Uam1 = r_Uam1.val;    double Ua   = r_Ua.val;    double Uap1;    double ap;    lm_max = GSL_MAX(lm_0, lm_1);    Uam1 *= exp(lm_0-lm_max);    Ua   *= exp(lm_1-lm_max);    for(ap=a0; ap<a-0.1; ap += 1.0) {      Uap1 = -(Uam1 + (b-2.0*ap-x)*Ua)/(ap*(1.0+ap-b));      Uam1 = Ua;      Ua   = Uap1;      RESCALE_2(Ua,Uam1,scale_factor,scale_count);    }    lnscale = log(scale_factor);    lnm.val = lm_max + scale_count * lnscale;    lnm.err = 2.0 * GSL_DBL_EPSILON * (fabs(lm_max) + fabs(scale_count * lnscale));    y.val  = Ua;    y.err  = fabs(r_Uam1.err/r_Uam1.val) * fabs(Ua);    y.err += fabs(r_Ua.err/r_Ua.val) * fabs(Ua);    y.err += 2.0 * GSL_DBL_EPSILON * (fabs(a-a0) + 1.0) * fabs(Ua);    y.err *= fabs(lm_0-lm_max) + 1.0;    y.err *= fabs(lm_1-lm_max) + 1.0;    stat_e = gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result);    return GSL_ERROR_SELECT_3(stat_e, stat_0, stat_1);  }  else {    if(b <= x) {      /* Recurse backward to a near zero.       */      const double a0 = a - floor(a);      const double scale_factor = GSL_SQRT_DBL_MAX;      int scale_count = 0;      gsl_sf_result lnm;      gsl_sf_result y;      double lnscale;      double lm_0;      double Uap1;      double Ua;      double Uam1;      gsl_sf_result U0;      double ap;      double ru;      double r;      int CF1_count;      int stat_CF1 = hyperg_U_CF1(a, b, 0, x, &ru, &CF1_count);      int stat_U0;      int stat_e;      r = ru/a;      Ua   = GSL_SQRT_DBL_MIN;      Uap1 = r * Ua;      for(ap=a; ap>a0+0.1; ap -= 1.0) {        Uam1 = -((b-2.0*ap-x)*Ua + ap*(1.0+ap-b)*Uap1);        Uap1 = Ua;        Ua   = Uam1;	RESCALE_2(Ua,Uap1,scale_factor,scale_count);      }      stat_U0 = hyperg_U_small_a_bgt0(a0, b, x, &U0, &lm_0);      lnscale = log(scale_factor);      lnm.val = lm_0 - scale_count * lnscale;      lnm.err = 2.0 * GSL_DBL_EPSILON * (fabs(lm_0) + fabs(scale_count * lnscale));      y.val  = GSL_SQRT_DBL_MIN*(U0.val/Ua);      y.err  = GSL_SQRT_DBL_MIN*(U0.err/fabs(Ua));      y.err += 2.0 * GSL_DBL_EPSILON * (fabs(a0-a) + CF1_count + 1.0) * fabs(y.val);      stat_e = gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result);      return GSL_ERROR_SELECT_3(stat_e, stat_U0, stat_CF1);    }    else {      /* Recurse backward to near the b=2a+x line, then       * forward from a near zero to get the normalization.       */      int scale_count_for = 0;      int scale_count_bck = 0;      const double scale_factor = GSL_SQRT_DBL_MAX;      const double eps = a - floor(a);      const double a0 = ( eps == 0.0 ? 1.0 : eps );      const double a1 = a0 + ceil(0.5*(b-x) - a0);      gsl_sf_result lnm;      gsl_sf_result y;      double lm_for;      double lnscale;      double Ua1_bck;      double Ua1_for;      int stat_for;      int stat_bck;      int stat_e;      int CF1_count;      {        /* Recurse back to determine U(a1,b), sans normalization.         */        double Uap1;        double Ua;        double Uam1;        double ap;        double ru;        double r;        int stat_CF1 = hyperg_U_CF1(a, b, 0, x, &ru, &CF1_count);        r = ru/a;        Ua   = GSL_SQRT_DBL_MIN;        Uap1 = r * Ua;        for(ap=a; ap>a1+0.1; ap -= 1.0) {          Uam1 = -((b-2.0*ap-x)*Ua + ap*(1.0+ap-b)*Uap1);          Uap1 = Ua;          Ua   = Uam1;	  RESCALE_2(Ua,Uap1,scale_factor,scale_count_bck);        }        Ua1_bck = Ua;        stat_bck = stat_CF1;      }      {        /* Recurse forward to determine U(a1,b) with         * absolute normalization.         */	gsl_sf_result r_Uam1;	gsl_sf_result r_Ua;	double lm_0, lm_1;        int stat_0 = hyperg_U_small_a_bgt0(a0-1.0, b, x, &r_Uam1, &lm_0);        int stat_1 = hyperg_U_small_a_bgt0(a0,     b, x, &r_Ua,   &lm_1);        double Uam1 = r_Uam1.val;        double Ua   = r_Ua.val;        double Uap1;        double ap;	lm_for = GSL_MAX(lm_0, lm_1);	Uam1 *= exp(lm_0 - lm_for);	Ua   *= exp(lm_1 - lm_for);        for(ap=a0; ap<a1-0.1; ap += 1.0) {          Uap1 = -(Uam1 + (b-2.0*ap-x)*Ua)/(ap*(1.0+ap-b));          Uam1 = Ua;          Ua   = Uap1;	  RESCALE_2(Ua,Uam1,scale_factor,scale_count_for);        }        Ua1_for = Ua;	stat_for = GSL_ERROR_SELECT_2(stat_0, stat_1);      }      lnscale = log(scale_factor);      lnm.val = lm_for + (scale_count_for - scale_count_bck)*lnscale;      lnm.err = 2.0 * GSL_DBL_EPSILON * (fabs(lm_for) + fabs(scale_count_for - scale_count_bck)*fabs(lnscale));      y.val = GSL_SQRT_DBL_MIN*Ua1_for/Ua1_bck;      y.err = 2.0 * GSL_DBL_EPSILON * (fabs(a-a0) + CF1_count + 1.0) * fabs(y.val);      stat_e = gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result);      return GSL_ERROR_SELECT_3(stat_e, stat_bck, stat_for);    }  }}/*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/intgsl_sf_hyperg_U_int_e10_e(const int a, const int b, const double x,                             gsl_sf_result_e10 * result){  /* CHECK_POINTER(result) */  if(x <= 0.0) {    DOMAIN_ERROR_E10(result);  }  else {    if(b >= 1) {      return hyperg_U_int_bge1(a, b, x, result);    }    else {      /* Use the reflection formula       * U(a,b,x) = x^(1-b) U(1+a-b,2-b,x)       */      gsl_sf_result_e10 U;      double ln_x = log(x);      int ap = 1 + a - b;      int bp = 2 - b;      int stat_e;      int stat_U = hyperg_U_int_bge1(ap, bp, x, &U);      double ln_pre_val = (1.0-b)*ln_x;      double ln_pre_err = 2.0 * GSL_DBL_EPSILON * (fabs(b)+1.0) * fabs(ln_x);      ln_pre_err += 2.0 * GSL_DBL_EPSILON * fabs(1.0-b); /* error in log(x) */      stat_e = gsl_sf_exp_mult_err_e10_e(ln_pre_val + U.e10*M_LN10, ln_pre_err,                                            U.val, U.err,                                            result);      return GSL_ERROR_SELECT_2(stat_e, stat_U);    }  }}intgsl_sf_hyperg_U_e10_e(const double a, const double b, const double x,                         gsl_sf_result_e10 * result){  const double rinta = floor(a + 0.5);  const double rintb = floor(b + 0.5);  const int a_integer = ( fabs(a - rinta) < INT_THRESHOLD );  const int b_integer = ( fabs(b - rintb) < INT_THRESHOLD );  /* CHECK_POINTER(result) */  if(x <= 0.0) {    DOMAIN_ERROR_E10(result);  }  else if(a == 0.0) {    result->val = 1.0;    result->err = 0.0;    result->e10 = 0;    return GSL_SUCCESS;  }  else if(a_integer && b_integer) {    return gsl_sf_hyperg_U_int_e10_e(rinta, rintb, x, result);  }  else {    if(b >= 1.0) {      /* Use b >= 1 function.       */      return hyperg_U_bge1(a, b, x, result);    }    else {      /* Use the reflection formula       * U(a,b,x) = x^(1-b) U(1+a-b,2-b,x)       */      const double lnx = log(x);      const double ln_pre_val = (1.0-b)*lnx;      const double ln_pre_err = fabs(lnx) * 2.0 * GSL_DBL_EPSILON * (1.0 + fabs(b));      const double ap = 1.0 + a - b;      const double bp = 2.0 - b;      gsl_sf_result_e10 U;      int stat_U = hyperg_U_bge1(ap, bp, x, &U);      int stat_e = gsl_sf_exp_mult_err_e10_e(ln_pre_val + U.e10*M_LN10, ln_pre_err,                                            U.val, U.err,                                            result);      return GSL_ERROR_SELECT_2(stat_e, stat_U);    }  }}intgsl_sf_hyperg_U_int_e(const int a, const int b, const double x, gsl_sf_result * result){  gsl_sf_result_e10 re;  int stat_U = gsl_sf_hyperg_U_int_e10_e(a, b, x, &re);  int stat_c = gsl_sf_result_smash_e(&re, result);  return GSL_ERROR_SELECT_2(stat_c, stat_U);}intgsl_sf_hyperg_U_e(const double a, const double b, const double x, gsl_sf_result * result){  gsl_sf_result_e10 re;  int stat_U = gsl_sf_hyperg_U_e10_e(a, b, x, &re);  int stat_c = gsl_sf_result_smash_e(&re, result);  return GSL_ERROR_SELECT_2(stat_c, stat_U);}/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/#include "eval.h"double gsl_sf_hyperg_U_int(const int a, const int b, const double x){  EVAL_RESULT(gsl_sf_hyperg_U_int_e(a, b, x, &result));}double gsl_sf_hyperg_U(const double a, const double b, const double x){  EVAL_RESULT(gsl_sf_hyperg_U_e(a, b, x, &result));}

⌨️ 快捷键说明

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