public inbox for gsl-discuss@sourceware.org
 help / color / mirror / Atom feed
From: "G.W.M. Vissers" <vissers@theochem.kun.nl>
To: gsl-discuss@sources.redhat.com
Subject: gsl_sf_coupling_3j, BUG #7
Date: Wed, 23 Apr 2003 15:58:00 -0000	[thread overview]
Message-ID: <Pine.LNX.4.50.0304231420540.20323-100000@tc5.theochem.kun.nl> (raw)


Hi,

I saw at documents.wolfram.com/v4/RefGuide/ThreeJSymbol.html that 
mathematica's 3j symbol is built upon binomial coefficients. I implemented 
their expression in the following routine:

int
gsl_sf_coupling_3j_e_new (int two_ja, int two_jb, int two_jc,
                          int two_ma, int two_mb, int two_mc,
                          gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  if(two_ja < 0 || two_jb < 0 || two_jc < 0) {
    DOMAIN_ERROR(result);
  }
  else if (   triangle_selection_fails(two_ja, two_jb, two_jc)
           || m_selection_fails(two_ja, two_jb, two_jc, two_ma, two_mb, two_mc)
     ) {
    result->val = 0.0;
    result->err = 0.0;
    return GSL_SUCCESS;
  }
  else {
    int jca  = (-two_ja + two_jb + two_jc) / 2,
        jcb  = ( two_ja - two_jb + two_jc) / 2,
        jcc  = ( two_ja + two_jb - two_jc) / 2,
        jmma = ( two_ja - two_ma) / 2,
        jmmb = ( two_jb - two_mb) / 2,
        jmmc = ( two_jc - two_mc) / 2,
        jpma = ( two_ja + two_ma) / 2,
        jpmb = ( two_jb + two_mb) / 2,
        jpmc = ( two_jc + two_mc) / 2,
        jsum = ( two_ja + two_jb + two_jc) / 2,
        kmin = locMax3 (0, jpmb - jmmc, jmma - jpmc),
        kmax = locMin3 (jcc, jmma, jpmb),
        k, sign = GSL_IS_ODD (kmin - jpma + jmmb) ? -1 : 1,
        status = 0;
    double ksump = 0.0, ksumn = 0.0, norm, term;
    gsl_sf_result bc1, bc2, bc3, bcn1, bcn2, bcd1, bcd2, bcd3, bcd4;

    status += gsl_sf_choose_e (two_ja, jcc , &bcn1);
    status += gsl_sf_choose_e (two_jb, jcc , &bcn2);
    status += gsl_sf_choose_e (jsum+1, jcc , &bcd1);
    status += gsl_sf_choose_e (two_ja, jmma, &bcd2);
    status += gsl_sf_choose_e (two_jb, jmmb, &bcd3);
    status += gsl_sf_choose_e (two_jc, jpmc, &bcd4);
    
    if (status != 0) {
      OVERFLOW_ERROR (result);
    }
    
    norm = sqrt (bcn1.val * bcn2.val)
           / sqrt (bcd1.val * bcd2.val * bcd3.val * bcd4.val * ((double) two_jc + 1.0));

    for (k = kmin; k <= kmax; k++) {
      status += gsl_sf_choose_e (jcc, k, &bc1);
      status += gsl_sf_choose_e (jcb, jmma - k, &bc2);
      status += gsl_sf_choose_e (jca, jpmb - k, &bc3);
      
      if (status != 0) {
        OVERFLOW_ERROR (result);
      }
      
      term = bc1.val * bc2.val * bc3.val;
      
      if (sign < 0) {
        ksumn += norm * term;
      } else {
        ksump += norm * term;
      }
      
      sign = -sign;
    }
    
    result->val  = ksump - ksumn;
    result->err  = 2.0 * GSL_DBL_EPSILON * (ksump + ksumn);
    result->err += 2.0 * GSL_DBL_EPSILON * (kmax - kmin) * fabs(result->val);

    return GSL_SUCCESS;
  }
}

This seems to be a lot more stable than the previous routine (to use the 
example in the BUGS file:
 
gsl_sf_coupling_3j_new (80,80,80,0,0,0) 

now produces 1.4968524483265e-02 with an estimated error of 
1.3934261781184e-10. The actual value is 1.4968524489706e-02 which is 
well within the error bars.)

The routine passes all 6 tests in test_sf.c. Please let me know if 
anything is wrong with it, 

Cheers,

Gé Vissers

             reply	other threads:[~2003-04-23 15:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-04-23 15:58 G.W.M. Vissers [this message]
2003-05-10 18:56 ` Brian Gough
2003-05-12  7:01   ` G.W.M. Vissers
2003-07-25 11:32     ` Brian Gough

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.50.0304231420540.20323-100000@tc5.theochem.kun.nl \
    --to=vissers@theochem.kun.nl \
    --cc=gsl-discuss@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).