Coder Social home page Coder Social logo

Accuracy of FmEval_Taylor about libint HOT 7 CLOSED

bingao avatar bingao commented on August 22, 2024
Accuracy of FmEval_Taylor

from libint.

Comments (7)

evaleev avatar evaleev commented on August 22, 2024

@bingao could you share more details please. I have tested the Taylor-based engine and do not see any issues

m=20 T=3.350905e+01 ref_value=1.456421e-14 value==1.456421e-14 abs_error=7.835090e-30 relabs_error=5.379688e-16
m

But this is on a Mac with Apple clang, Debug, etc.

The recommended engine is FmEval_Chebyshev7, which on x86 uses intrinsics to produce vectorized code.

P.S. For the Boys engine only absolute precision can be guaranteed practically, but for most practical T,m combinations almost max relative precision is attained.

from libint.

evaleev avatar evaleev commented on August 22, 2024

from libint.

bingao avatar bingao commented on August 22, 2024

Hi @evaleev sorry I forgot to post more details. I built Libint without C++11 and Fortran03+ interfaces (so Eigen3 is not used). The compiler flag is quite simple:

g++ -D__COMPILING_LIBINT2 -I/cluster/home/gaobin/libint-2.7.1/include -I/cluster/home/gaobin/libint-2.7.1/build/include -O3 -DNDEBUG -MD -MT

I have used FmEval_Chebyshev7 which is very fast and accurate. A maximum relative error 6e-15 is obtained in my tests, with mmax as 10, 20, 30, 40, and different 100,000 T's.

However, FmEval_Taylor<double,7> gave me a bit inaccurate or strange results that I will explain below. First, the source code (named as test_FmEval.cpp) of testing FmEval_Taylor<double,7> is:

#include <cmath>
#include <iomanip>
#include <stream>
#include <string>

#include <libint2.h>
#include <libint2/boys.h>
#if !LIBINT2_CONSTEXPR_STATICS
#  include <libint2/statics_definition.h>
#endif
#include <libint2/initialize.h>

int main()
{
    LIBINT2_PREFIXED_NAME(libint2_static_init)();
    const int num_args = 100000;
    /* I use Chebyshev nodes as different T's */
    double vmin = 0.0;
    double vmax = 5000.0;
    double step_angle = 3.141592653589793/num_args;
    double sum_ab = 0.5*(vmax+vmin);
    double diff_ab = 0.5*(vmax-vmin);
    std::vector<double> args(num_args, 0.0);
    for (int iarg=0; iarg<num_args; ++iarg) {
        args[iarg] = sum_ab+diff_ab*std::cos((iarg+0.5)*step_angle);
    }
    std::ofstream fboys;
    for (int mmax=10; mmax<=60; mmax+=10) {
        auto vals = new double[mmax+1];
        libint2::FmEval_Taylor<double> fm_eval(mmax);
        /* Write computed Boys functions into a file and verify their accuracy afterwards. */
        fboys.open("boys_vals_"+std::to_string(mmax)+".txt");
        fboys << std::setprecision(17);
        fboys << std::scientific;
        for (int iarg=0; iarg<num_args; ++iarg) {
            fm_eval.eval(vals, args[iarg], mmax);
            fboys << args[iarg] << "\n";
            for (int ival=0; ival<=mmax; ++ival) {
                fboys << vals[ival] << ", ";
            }
            fboys << "\n";
        }
        fboys.close();
        delete[] vals;
    }
    LIBINT2_PREFIXED_NAME(libint2_static_cleanup)();
    return 0;
}

I compiled the above code as:

g++ -D__COMPILING_LIBINT2 -I/cluster/home/gaobin/libint-2.7.1/include -I/cluster/home/gaobin/libint-2.7.1/build/include -I/cluster/home/gaobin/libint-2.7.1/build/include/libint2 -O3 -DNDEBUG test_FmEval.cpp libint2.a

I know there is a highly accurate reference evaluator available in Libint. But I prepared an evaluator of Boys functions in Python by using mpmath (https://mpmath.org). So after running the above tests, I compared computed Boys functions to those obtained from mpmath.

For mmax=20 and T=3.35090483885032882e+01, I got (the first line is T):

3.35090483885032882e+01
1.53096017450543687e-01, 2.28439816725841457e-03, 1.02258864864150114e-04, 7.62919791678374625e-06, 7.96865145132092385e-07, 1.07012682369235934e-07, 1.75645021251209397e-08, 3.40711741764366456e-09, 7.62581465636089048e-10, 1.93438529874176702e-10, 5.48408481299377374e-11, 1.71842392698288492e-11, 5.89743251314769462e-12, 2.19989852912697362e-12, 8.86245101528155682e-13, 3.83453259285439483e-13, 1.77328979862341899e-13, 8.72757704661901120e-14, 4.55377250178399760e-14, 2.50991240051276858e-14, 1.43348373251435156e-14,

The 20th order Boys function Fm(20)=1.43348373251435156e-14. When I used mmax=30, the results are:

3.35090483885032882e+01
1.53096017450543687e-01, 2.28439816725841457e-03, 1.02258864864150114e-04, 7.62919791678374625e-06, 7.96865145132092385e-07, 1.07012682369235934e-07, 1.75645021251209397e-08, 3.40711741764366456e-09, 7.62581465636089048e-10, 1.93438529874176702e-10, 5.48408481299377374e-11, 1.71842392698288492e-11, 5.89743251314769462e-12, 2.19989852912697362e-12, 8.86245101528155682e-13, 3.83453259285439483e-13, 1.77328979862341899e-13, 8.72757704661901120e-14, 4.55377250178399760e-14, 2.50991240051276858e-14, 1.45642084612065371e-14, 8.86823516968384032e-15, 5.64823273763774357e-15, 3.75078047894668816e-15, 2.58864973473364547e-15, 1.85089608480443712e-15, 1.36672631219974662e-15, 1.03906547379208609e-15, 8.10949573412370265e-16, 6.47941730763401423e-16, 2.99266049301716253e-16,

The 20th order Boys function becomes more accurate, as Fm(20)=1.45642084612065371e-14.

It seems that the last element of computed Boys functions is not accurate, a bit strange to me.

I hope I have written all details of my testing. Did I do something wrong in the above testing code? Thank you for your kind help. Have a nice weekend.

from libint.

evaleev avatar evaleev commented on August 22, 2024

from libint.

bingao avatar bingao commented on August 22, 2024

Hi @evaleev I ran Libint and my testing code on one Norwegian supercomputer (https://documentation.sigma2.no/hpc_machines/betzy.html) whose CPU type is AMD® Epyc™ 7742 2.25GHz and has Red Hat Enterprise Linux 7.

Actually, I am benchmarking my Boy function evaluator against Libint. My evaluator focuses on error control with a wide range of orders and arguments, but for sure is slower than Libint.

Thank you for your kind help.

from libint.

evaleev avatar evaleev commented on August 22, 2024

@bingao should be fixed, to test you have to apply 9e92fad manually

from libint.

evaleev avatar evaleev commented on August 22, 2024

@bingao I would be interested in learning which argument values do not produce sufficient precision .... Last revision of the Boys engine greatly increased its implicit precision, but clearly there are use cases still where the precision is not sufficient?

from libint.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.