Esempio n. 1
0
static VALUE rb_gsl_utrunc_accel(VALUE obj)
{
  gsl_sum_levin_utrunc_workspace *w = NULL;
  double sum, err, sum_plain, *ptr;
  size_t terms_used, n, stride;
  ptr = get_vector_ptr(obj, &stride, &n);
  w = gsl_sum_levin_utrunc_alloc(n);
  gsl_sum_levin_utrunc_accel(ptr, n, w, &sum, &err);
  sum_plain = w->sum_plain;
  terms_used = w->terms_used;
  gsl_sum_levin_utrunc_free(w);
  return rb_ary_new3(4, rb_float_new(sum), rb_float_new(err), 
		     rb_float_new(sum_plain), INT2FIX(terms_used));
}
Esempio n. 2
0
File: test.c Progetto: lemahdi/mglib
void
check_trunc (double * t, double expected, const char * desc)
{
  double sum_accel, prec;

  gsl_sum_levin_utrunc_workspace * w = gsl_sum_levin_utrunc_alloc (N);
  
  gsl_sum_levin_utrunc_accel (t, N, w, &sum_accel, &prec);
  gsl_test_rel (sum_accel, expected, 1e-8, "trunc result, %s", desc);

  /* No need to check precision for truncated result since this is not
     a meaningful number */

  gsl_sum_levin_utrunc_free (w);
}
Esempio n. 3
0
Real
funcSum_all_accel(boost::function<Real(unsigned int i)> f,
                  std::size_t max_i, Real tolerance)
{
    const Real p_0(f(0));
    if (p_0 == 0.0)
    {
        return 0.0;
    }

    std::vector<Real> pTable(max_i);
    pTable[0] = p_0;
    for(std::size_t i=1; i < max_i; ++i)
    {
        pTable[i] = f(i);
    }

    Real sum;
    Real error;
    gsl_sum_levin_utrunc_workspace* workspace(gsl_sum_levin_utrunc_alloc(max_i));
    gsl_sum_levin_utrunc_accel(
            pTable.data(), pTable.size(), workspace, &sum, &error);

#ifdef ECELL_GREENS_FUNCTIONS_DEBUG_OUTPUT
    if (std::abs(error) >= std::abs(sum * tolerance))
    {
        std::cerr << (boost::format("series acceleration error: %.16g"
                " (rel error: %.16g), terms_used = %d (%d given)") %
                std::abs(error) % std::abs(error / sum) %
                workspace->terms_used % pTable.size()
            ).str() << std::endl;
    }
#endif // ECELL_GREENS_FUNCTIONS_DEBUG_OUTPUT

    gsl_sum_levin_utrunc_free(workspace);

    return sum;
}
Esempio n. 4
0
Real
funcSum(boost::function<Real(unsigned int i)> f, std::size_t max_i, Real tolerance)
// funcSum
// ==
// Will simply calculate the sum over a certain function f, until it converges
// (i.e. the sum > tolerance*current_term for a CONVERGENCE_CHECK number of
// terms), or a maximum number of terms is summed (usually 2000).
//
// Input:
// - f: A       function object
// - max_i:     maximum number of terms it will evaluate
// - tolerance: convergence condition, default value 1-e8 (see .hpp)
{
    // DEFAULT = 4
    const unsigned int CONVERGENCE_CHECK(4);

    const Real p_0(f(0));
    if (p_0 == 0.0)
    {
        return 0.0;
    }

    Real sum(p_0);
    std::vector<Real> pTable;
    pTable.reserve(max_i);
    pTable.push_back(p_0);

    unsigned int convergenceCounter(0);

    for(std::size_t i=1; i < max_i; ++i)
    {
        const Real p_i(f(i));
        pTable.push_back(p_i);
        sum += p_i;

        if (std::abs(sum) * tolerance >= std::abs(p_i)) // '=' is important
        {
            ++convergenceCounter;
        }
        // this screws it up; why?
        else
        {
            convergenceCounter = 0;
        }

        if (convergenceCounter >= CONVERGENCE_CHECK)
        {
            return sum; // converged! series acceleration is not needed! yay!
        }
    }

    Real error;
    gsl_sum_levin_utrunc_workspace*
        workspace(gsl_sum_levin_utrunc_alloc(max_i));
    gsl_sum_levin_utrunc_accel(
        pTable.data(), pTable.size(), workspace, &sum, &error);

#ifdef ECELL_GREENS_FUNCTIONS_DEBUG_OUTPUT
    if (std::abs(error) >= std::abs(sum * tolerance * 10))
    {
        std::cerr << (boost::format("series acceleration error: %.16g"
                " (rel error: %.16g), terms_used = %d (%d given)") %
                std::abs(error) % std::abs(error / sum) %
                workspace->terms_used % pTable.size()
            ).str() << std::endl;
    }
#endif // ECELL_GREENS_FUNCTIONS_DEBUG_OUTPUT

    gsl_sum_levin_utrunc_free(workspace);

    return sum;
}