{"id":16499313,"url":"https://github.com/expander/tsil-mirror","last_synced_at":"2025-11-25T18:02:35.852Z","repository":{"id":137154839,"uuid":"333442965","full_name":"Expander/TSIL-mirror","owner":"Expander","description":"A mirror of TSIL","archived":false,"fork":false,"pushed_at":"2021-01-27T22:11:21.000Z","size":402,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-12T09:21:47.009Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Expander.png","metadata":{"files":{"readme":"README.txt","changelog":"CHANGELOG.txt","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-27T14:14:55.000Z","updated_at":"2021-01-27T22:11:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"060b1c3b-4ed8-485b-8e0d-d5e2de85ba2b","html_url":"https://github.com/Expander/TSIL-mirror","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Expander%2FTSIL-mirror","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Expander%2FTSIL-mirror/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Expander%2FTSIL-mirror/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Expander%2FTSIL-mirror/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Expander","download_url":"https://codeload.github.com/Expander/TSIL-mirror/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241404921,"owners_count":19957731,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T14:52:06.425Z","updated_at":"2025-11-25T18:02:35.747Z","avatar_url":"https://github.com/Expander.png","language":"C","readme":"                     ********************************\n\t\t            Welcome to TSIL\n                     ********************************\n\nCopyright (C) 2005 S.P. Martin and D.G. Robertson\n\nThis program is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 2 of the License, or (at\nyour option) any later version.  See the file LICENSE.txt for further\ndetails.\n\nContents of this file:\n\nI.   Overview\nII.  Building TSIL\nIII. Using TSIL\nIV.  The TSIL API\nV.   Numerical Integration in TSIL\nVI.  Using TSIL with C++\nVII. Using TSIL with Fortran\n\n\n************************************************************************\nI. Overview\n************************************************************************\n\nTSIL is a library of utilities for the numerical calculation of\ndimensionally regularized two-loop self-energy integrals.  A\nconvenient basis for these functions is given by the integrals\nobtained at the end of O.V. Tarasov's recurrence relation algorithm.\nTSIL computes the values of all of these basis functions, for\narbitrary input masses and external momentum.  When analytical\nexpressions in terms of polylogarithms are available, they are\nused. Otherwise, the evaluation proceeds by a Runge-Kutta integration\nof the coupled first-order differential equations for the basis\nintegrals, using the external momentum invariant as the independent\nvariable. The code is written in C, and may be linked from C/C++ or\nFortran.\n\nAuthors:\nS.P. Martin [spmartin AT niu.edu] \nDepartment of Physics\nNorthern Illinois University\nDeKalb, IL 60115\nUSA\n\nD.G. Robertson [drobertson AT otterbein.edu]\nDepartment of Physics\nOtterbein University\nWesterville, OH 43081\nUSA\n\nTo cite this program, please reference the paper (referred to in this\ndocument as MR05):\n\n\"TSIL: a program for the calculation of two-loop self-energy\nintegrals\", by S.P. Martin and D.G. Robertson, [hep-ph/0501132].\n\nAlso, please reference the paper containing some of the results on\nwhich it is based:\n\n\"Evaluation of two-loop self-energy basis integrals using differential\nequations,\" by S.P. Martin\nPhys. Rev. D 68, 075002 (2003) [hep-ph/0307101].\n\nTSIL is available from:\n\n       http://www.niu.edu/spmartin/TSIL\n       http://faculty.otterbein.edu/drobertson/TSIL\n\nVersion number: 1.43\n\n\n************************************************************************\nII. Building TSIL\n************************************************************************\n\nTSIL can be compiled on any system that supports the GNU Compiler\nCollection (gcc), the Intel C compiler (icc), or a similar C compiler\nwith support for complex mathematics. The compiler must also implement\nthe C99 standard (or later).\n\nTo compile TSIL, edit the Makefile and choose:\n\n1. The size of basic data types.  This is controlled by the compiler\n   flag\n\n\t -DTSIL_SIZE_\u003csize\u003e\n\n   where \u003csize\u003e may be LONG or DOUBLE:\n\n\t LONG\t    Basic floating point type is long double\n\t DOUBLE\t    Basic floating point type is double\n\n   Simply uncomment the line for the type you wish.  (If neither flag\n   is given, LONG is selected.)  LONG is strongly recommended on\n   systems where it is available.  There is a speed penalty due to the\n   use of long double intrinsic functions, but it is minor and\n   execution times are in any case low (less than one second) on\n   modern hardware.\n\n   In your own programs that use TSIL, you may declare variables as\n\n         TSIL_REAL\n         TSIL_COMPLEX\n\n   which will automatically correspond to the type selected when the\n   library was compiled.  Note also that macros of the form\n\n         TSIL_CLOG\n\n   will automatically select the appropriate intrinsic function (in\n   this case, either clog or clogl).  For a full list of intrinsics\n   with this behavior, see the file tsil.h.\n\n2. Compiler and optimization flags.\n\n   Several sets are pre-defined in the Makefile; simply uncomment the\n   appropriate one for your system if present.  TSIL is currently\n   known to compile with gcc (under Linux or Mac OS X) and icc.  Other\n   C compilers should work provided that complex mathematics is\n   supported, but in this case you will need to explicitly set the\n   compiler name and optimization flags.\n\n   If you succeed in building TSIL on a new platform, the authors\n   would be grateful to know it, and to learn of any special measures\n   that were needed to compile it.\n\n3. Install directories, if desired.\n\n   You can set TSIL_LIBDIR and TSIL_INCDIR to point to directories\n   where you would like the library and the TSIL header file,\n   respectively, to be placed after compilation. If TSIL_LIBDIR and\n   TSIL_INCDIR are not set, then the library and the header file will be \n   left after compilation in the directory where the sources reside, and \n   they can be moved by hand to an appropriate place. Standard directories\n   that are automatically searched by compilers and linkers typically\n   include /usr/lib and /usr/include, but you will need root access to\n   write to these directories.  If you specify other directories not\n   on the standard search path, note that when compiling your own code\n   it will be necessary to specify these directories using the options\n   -I\u003cdir\u003e and -L\u003cdir\u003e.  See the compiler/linker man pages for\n   complete details. \n\nOnce these choices have been made, simply type\n\n       make\n\nto build the library, along with the associated test and sample\nprograms.  After this command is complete, and after TSIL has been\ntested with satisfactory results (see below), you can type\n\n       make install\n\nto install the library and header files in the specified locations.\nCongratulations, TSIL is ready for action!\n\nThe end product intended for the user consists of the files:\n\n       libtsil.a     The static TSIL archive (will be placed in\n\t\t     TSIL_LIBDIR upon \"make install\")\n\n       tsil.h        The TSIL header file, must be included in any \n\t\t     user code that uses TSIL (will be placed in\n\t\t     TSIL_INCDIR upon \"make install\")\n\n       tsil\t     Executable for basic computation (see below \n\t\t     for details)\n\n       tsil.tst\t     Test program (see below for details)\n\nIn addition, the files\n\n       tsil_cpp.h\n       tsil_fort.inc\n\nmay be useful if you are planning to call TSIL from C++ or Fortran,\nrespectively.  See section VII-VIII of this document for additional\ninformation on using TSIL with these langauges.\n\nIt is strongly recommended that you run the test program after\ncompiling TSIL, to insure that correct results are being obtained.\nThe program\n\n       tsil.tst\n\ncompares the output of TSIL_Evaluate to predefined results in 320 data\nfiles, which are located in the directory TestData.  These data files\ninclude cases representing all known analytic results as well as cases\nrequiring integration that have thresholds and pseudo-thresholds at\ns=0 and at the final s.\n\ntsil.tst takes a list of filenames as command line arguments, and\noutputs, for each test case (i.e. for each file) either PASS, WARN or\nFAIL.  If a WARN or FAIL results, the responsible functions are\nprinted, with both the expected and obtained values.  Assuming you\nhave just compiled TSIL, the easiest way to run the entire suite of\ntests is via the command\n\n       ./tsil.tst TestData/* \u003e foo.txt\n\nwith the output redirected to the file foo.txt (recommended here due\nto the large number of tests).  The end of this file will contain a\nsummary with the total number of PASS, FAIL and WARN results.\n\nThe pass/fail/warn criteria are controlled by macros TSIL_PASS,\nTSIL_WARN, TSIL_PASS_V and TSIL_WARN_V, defined in tsil_testparams.h.\nThe first sets the maximum relative error allowed for the test to\npass; the second sets a lower error threshold below which the test is\ndeemed to fail.  A relative error between these two values results in\na warning.  (TSIL_PASS_V and TSIL_WARN_V define slightly less\nstringent requirements for the V functions.)  As an example, for long\ndouble data the default values are\n\n       TSIL_PASS   = 1.e-9\n       TSIL_WARN   = 1.e-6\n       TSIL_PASS_V = 1.e-6\n       TSIL_WARN_V = 1.e-4\n\nGeneric cases should usually exceed these relative precisions with\nease; these pass/warn/fail parameters are aimed to be \"friendly\" to\nthe more difficult cases. Even so, you may see some WARNs, and\npossibly even FAILs, when running the test suite, depending on your\nplatform.\n\nUsers should not need to do this to insure correct functionality, but\nthe test program can be configured to evaluate subset cases (STU or ST\nfunctions) by uncommenting the appropriate flag in the Makefile. In\nthis case the test program evaluates the selected subset case for each\nset of input parameters, comparing the results to values taken from\nthe full data files.\n\nThe make command also produces the executable\n\n       tsil\n\nwhich implements the most basic TSIL calculation: it takes as\ncommand-line arguments x, y, z, u, v, s, and Q^2, in that order, and\nprints the values of all integral functions together with timing and\nother information.  As an example,\n\n       ./tsil 1 2 3 4 5 10 1\n\nevaluates all functions for x=1.0, y=2.0, z=3.0, u=4.0, v=5.0, s=10.0,\nand Q^2=1.0 and prints the results to stdout.\n\n\n************************************************************************\nIII. Using TSIL\n************************************************************************\n\nTo use TSIL functions in your code, you must:\n\n1. Include the header file tsil.h in any source file that makes use of\n   TSIL data structures or functions, e.g. by adding the line\n\n\t#include \"tsil.h\"\n\n   This is appropriate if the file tsil.h is located in the directory\n   where the code is being compiled; if it has been placed in a\n   standard location such as /usr/include, then\n\n\t#include \u003ctsil.h\u003e\n\n   would work.  If it is a nonstandard directory \u003cinc_dir\u003e, the\n   compiler option\n\n        -I\u003cinc_dir\u003e\n\n   will generally be necessary.  See the compiler man pages on your\n   system for further details.\n\n   Some potentially useful constants are also defined in the file\n\n\ttsil_global.h \n\n   which may be included by users wishing to access them.  Note that\n   the constant names defined herein are not prefixed by TSIL_ and are\n   therefore potentially subject to namespace collisions with objects\n   in the user code.  Users wishing to make use of these constants\n   should be careful to insure that their own variable and function\n   names do not match any of those defined in tsil_global.h.\n\n2. Link to the library at the end of the compilation process.  This is\n   accomplished via the (linker) flag\n\n\t-ltsil\n\n   If libtsil.a is not in a standard location (including the case\n   where it is in the current directory), you will generally need to\n   add the flag\n\n        -L\u003clib_dir\u003e\n\n   where \u003clib_dir\u003e is the directory in which libtsil.a may be found.\n   If this is the current directory, then\n\n\t -L.\n\n   may be used.  Again, consult the compiler man pages for complete\n   details on making user libraries available to the linker.\n\nComplete details regarding the TSIL functions are given in section IV\nof this document.  In the rest of the section we will discuss some\ngeneral points and exhibit some simple examples.\n\nThe basic data object in TSIL is a C struct with type name\n\n       TSIL_DATA\n\nthat contains the parameter values x, y, z, u, v and Q^2 as well as\nthe 15 basis functions of types B, S, T, U, M.  Each basis function is\nitself a struct containing its value, arguments, and various\nunchanging coefficients used in computing its derivative.  Also\ncontained in the basic data struct are values of the integrals Tbar,\nV, and bold versions of S, T, U, and V.  Definitions of all datatypes\nare contained in the header file tsil.h.\n\nIn any program that calls TSIL functions requiring Runge-Kutta\nevaluation, at least one of these high-level data objects must be\ndeclared, e.g.\n\n\tTSIL_DATA foo;\n\nMore than one such object, and arrays of such objects, are allowed.\nUsers can of course access the items in the struct directly, though it\nis recommended that the provided user interface routines be used.\nThese allow one to extract values of individual functions (or all of\nthem), set the values of the external parameters, and so on.  See\nsection VI for additional details.\n\nNote that, as discussed above, the types TSIL_REAL and TSIL_COMPLEX\nare available to insure that intrinsic floating-point types match\nthose used in compiling the library.\n\nIn the simplest application of TSIL, the parameters x, y, z, u, v and\nQ^2 will be set using TSIL_SetParameters, the integrals for real s\nevaluated using TSIL_Evaluate, and the results either printed using\nTSIL_PrintData, or perhaps extracted by the calling program with the\ncommand TSIL_GetFunction.  Generic code for this would look like:\n\n\tTSIL_DATA    foo;\n\tTSIL_REAL    x, y, z, u, v, s, qq;\n\tTSIL_COMPLEX integral1, integral2;\n\t...\n\tTSIL_SetParameters (\u0026foo, x, y, z, u, v, qq);\n\tTSIL_Evaluate (\u0026foo, s);\n\tintegral1 = TSIL_GetFunction (\u0026foo, \u003cstring1\u003e);\n\tintegral2 = TSIL_GetFunction (\u0026foo, \u003cstring2\u003e);\n\t...\n\nwhere the strings \u003cstring1\u003e, \u003cstring2\u003e can each be one of\n\n         \"M\", \"Uzxyv\", \"Uuyxv\", \"Uxzuv\", \"Uyuzv\", \"Tvyz\", \"Tuxv\",\n\t \"Tyzv\", \"Txuv\", \"Tzyv\", \"Tvxu\", \"Svyz\", or \"Suxv\"\n\naccording to which of the basis integrals is desired. The strings can\nalso be one of\n\n          \"Vzxyv\", \"Vuyxv\", \"Vxzuv\", \"Vyuzv\", \"Bxz\", or \"Byu\"\n\nto access the functions V and the one-loop B functions.\n\nThe \"bold\" variants of the S, T, U and V functions can be accessed in\na similar way, e.g.\n\n          integral3 = TSIL_GetBoldFunction (\u0026foo, \u003cstring3\u003e, n);\n\nwould return the coefficient of 1/\\epsilon^n (for n=0,1, or 2) in the\nbold-faced function corresponding to an appropriate \u003cstring3\u003e from the\nlist above.\n\nTSIL_Evaluate first decides whether the case at hand is known\nanalytically; if so, the basis functions are computed directly.  If\nnot, numerical integration is performed.  TSIL_Evaluate returns 1\n(TRUE) for successful execution or 0 (FALSE) for error execution.  (A\nwarning message is printed if the external parameters correspond to\nthe unnatural threshold case discussed in [MR05].)  The data object\nfurther contains a status parameter, accessible via the function\nTSIL_GetStatus, which indicates how the master integral evaluation was\nperformed: either analytic, numerical integration along real axis, or\nnumerical integration along the displaced contour.\n\nAll integrals that are analytically known in terms of polylogarithms\ncan also be evaluated directly, without TSIL_SetParameters or\nTSIL_Evaluate or TSIL_GetFunction. For example,\n\n       TSIL_Manalytic (x,y,z,u,v,s,\u0026res);\n\nwill return the int value 1 and set the variable res equal to\nM(x,y,z,u,v) for the appropriate s, if it is analytically available,\nand otherwise will return 0. Here x,y,z,u,v,qq are of type TSIL_REAL,\nand s and res are of type TSIL_COMPLEX.  The functions\n\n       TSIL_Sanalytic\n       TSIL_Tanalytic\n       TSIL_Tbaranalytic\n       TSIL_Uanalytic\n       TSIL_Vanalytic\n\nhave analogous behavior, except that they carry an additional argument\nqq of type TSIL_REAL for the renormalization scale squared Q^2. For\nexample,\n\n       TSIL_Uanalytic (x,y,z,u,s,qq,\u0026res)}\n\nwill return the int value 1 and set the variable res equal to\nU(x,y,z,u) for the appropriate s and Q^2, if it is analytically\navailable, and otherwise will return 0.\n\nThe other analytic functions (i.e. those that are known for arbitrary\nparameter values and values of s) assign without pointers, for example\n\n       res = TSIL_Bp (x,y,s,qq);\n\nwill set result equal to B(x',y) computed analytically for the\nappropriate s and Q^2.\n\nIn addition to the evaluation for generic parameters described above,\nTSIL provides functions for direct analytical evaluation of the vacuum\nintegrals A(x) and I(x,y,z), the one-loop integral B(x,y), as well as\nvarious derivatives of these.\n\nThe standard output function is TSIL_PrintData, which prints all\nfunction values on stdout.  An alternate format, designed so that\ncaptured output can serve as valid input files for Mathematica, is\ngiven by TSIL_PrintDataM.  Additional utilities allow the user to\nextract individual basis functions or sets of functions to arrays.\nNote that warning and error messages appear on stderr so they may be\nredirected by the shell and examined separately.\n\nA complete example program that uses TSIL to compute the two-loop pole\nmass of a scalar particle with both cubic and quartic self-\ninteractions is given in\n\n     scalarpole.c,\n\nincluded with the distribution.  (Detailed background on this\ncalculation may be found in ref. [MR05].)  It takes parameter values\nm^2, g, lambda and Q^2 as command-line inputs, in that order.  It then\ncomputes the required basis functions at s=m^2, assembles the one- and\ntwo-loop pole mass squared values as outlined in [MR05], and prints\nthe results to stdout.  Most of the basic functionality available in\nTSIL is exhibited in scalarpole.c.\n\nTo compile this program using gcc, assuming tsil.h and libtsil.a are\npresent in the current directory, use e.g.\n\n     gcc -o spole -DTSIL_SIZE_\u003csize\u003e scalarpole.c -L. -ltsil -lm\n\nwhere \u003csize\u003e is either LONG or DOUBLE, and matches the size chosen\nwhen libtsil.a was compiled.  If you used the default size when\ncompiling libtsil.a, then you may omit this flag.  This command\nproduces the executable spole, which can then be run as, e.g.\n\n     ./spole 1 2 3 1\n\nNote the use in scalarpole.c of TSIL_A, TSIL_I2p, TSIL_B, TSIL_Bp, and\nTSIL_dBds to evaluate the functions A(x), I(x',x,x), B(x,x), B(x',x),\nand the partial derivative of B(x,x) with respect to s, respectively.\nIn the evaluation of pi2, we arbitrarily chose to use\n\n     TSIL_GetFunction(\u0026result, \"Bxz\") \n\nwhere TSIL_B could also have been used.\n\nFor convenience there is also a struct of type TSIL_RESULT, which\ncontains only the parameter values and the results for the B, S, T,\nTbar, U, V, and M functions.  A function TSIL_CopyResult takes an\nevlauated TSIL_DATA struct and copies the results into a specified\nTSIL_RESULT. There is also a function TSIL_PermuteResult that can\npermute the arguments of a TSIL_RESULT to produce another\nTSIL_RESULT. See section IV below for complete details.\n\n\n************************************************************************\nIV. The TSIL Application Programmer Interface\n************************************************************************\n\nIn this section we give the signatures of all TSIL functions, and\ndescribe their operation.\n\nBasic Evaluation and Extraction Functions\n=========================================\n\nBefore evaluation, one of the following three functions should be called\nto set the relevant squared mass and renormalization scale parameters.\n\n1a. int TSIL_SetParameters (TSIL_DATA *foo,\n                            TSIL_REAL x,\n\t\t\t    TSIL_REAL y,\n\t\t\t    TSIL_REAL z,\n\t\t\t    TSIL_REAL u,\n\t\t\t    TSIL_REAL v,\n                            TSIL_REAL qq)\n  \n   Sets parameter values x, y, z, u, v, qq in the data object *foo.\n   Return value is currently ignored.\n\n1b. int TSIL_SetParametersSTU (TSIL_DATA *foo,\n                               TSIL_REAL x,\n\t\t\t       TSIL_REAL z,\n\t\t\t       TSIL_REAL u,\n\t\t\t       TSIL_REAL v,\n\t\t\t       TSIL_REAL qq)\n  \n   Sets parameter values x, z, u, v, qq in the data object *foo, and\n   selects evaluation of the STU subset case. Return value is\n   currently ignored.\n\n1c. int TSIL_SetParametersST (TSIL_DATA *foo,\n                              TSIL_REAL x,\n\t\t\t      TSIL_REAL u,\n\t\t\t      TSIL_REAL v,\n                              TSIL_REAL qq)\n  \n   Sets parameter values x, u, v, qq in the data object *foo and\n   selects evaluation of the ST subset case. Return value is currently\n   ignored.\n\n   Subsequent calls of TSIL_SetParameters, TSIL_SetParametersSTU, or\n   TSIL_SetParametersST to change one or more of x, y, z, u, v, qq are\n   allowed, and to select the default (1a) or subset (1b) or (1c)\n   evaluation modes. Each such call also resets the default values of\n   parameters related to numerical integration (see section VII\n   below).\n\n---------------------------------------------------------------------\n\n2. int TSIL_Evaluate (TSIL_DATA *foo, TSIL_REAL s)\n\n   Evaluates all functions in *foo, including bold variants, at the\n   specified value of s.  If *foo was initialized with\n   TSIL_SetParametersSTU() or TSIL_SetParametersST(), then only the\n   relevant subset of the basis functions is computed.  Return value\n   is 1 (TRUE) for successful execution, 0 (FALSE) for error\n   execution.\n\n---------------------------------------------------------------------\n\n3. int TSIL_GetStatus (TSIL_DATA *foo)\n\n   Returns the evaluation status of *foo; either\n\n\t   0  Unevaluated\n\t   1  Evaluated by analytical formula\n\t   2  Evaluated by numerical integration along real s axis\n\t   3  Evaluated by numerical integration along displaced contour\n\n   Note that a set of enum'ed constants (UNEVALUATED, ANALYTIC,\n   REAXIS, CONTOUR) representing these are available in\n   tsil_global.h.\n\n---------------------------------------------------------------------\n\n4. void TSIL_GetData (TSIL_DATA *foo,\n\t              const char *str,\n\t\t      TSIL_COMPLEX *res)\n\n   Extracts a collection of functions to an array res[] according to\n   the string str provided.  This may be one of\n\n       \"M\", \"U\", \"T\", \"S\", \"V\", \"B\", or \"TBAR\"\n\n   The user is responsible for insuring that the array res[] is of the\n   correct size to hold all of the specified values.  The macros\n   NUM_U_FUNCS, NUM_V_FUNCS, NUM_T_FUNCS, NUM_S_FUNCS, NUM_B_FUNCS are\n   available and may be used in dimensioning such arrays.\n\n   Example:\n   ========\n   TSIL_DATA foo;\n   TSIL_COMPLEX uvals[NUM_U_FUNCS];\n   ...\n   TSIL_GetData (\u0026foo, \"U\", uvals);\n\n   Note that in subset evaluation (STU or ST), calling this function\n   will generate an error message.  Instead, TSIL_GetFunction should\n   be used to extract results.\n\n   A fatal error results if an invalid function identifier is\n   specified, or if an attempt is made to extract functions from an\n   unevaluted TSIL_DATA struct.\n\n---------------------------------------------------------------------\n\n4a. void TSIL_GetDataR (TSIL_RESULT *foo,\n \t              const char *str,\n \t\t      TSIL_COMPLEX *res)\n\n   Same functionality as TSIL_GetData above, but takes a pointer to a\n   TSIL_RESULT rather than a TSIL_DATA.\n\n---------------------------------------------------------------------\n\n5. void TSIL_GetBoldData (TSIL_DATA *foo,\n                          const char *str,\n\t \t\t  TSIL_COMPLEX res[][3])\n\n   Similar to TSIL_ExtractData, but extracts a collection of \"bold\"\n   functions to a two-dimensional array res[][3] according to the\n   string provided.  As above, this may be one of\n\n       \"M\", \"U\", \"T\", \"S\", \"V\", \"B\", or \"TBAR\"\n\n   The user is responsible for insuring that the array res[][3] is of\n   the correct size to hold all of the specified values.  \n\n   Example:\n   ========\n   TSIL_DATA foo;\n   TSIL_COMPLEX bolduvals[NUM_U_FUNCS][3];\n   ...\n   TSIL_GetBoldData (\u0026foo, \"U\", bolduvals);\n\n   Note that in subset evaluation (STU or ST), calling this function\n   will generate an error message.  Instead, TSIL_GetBoldFunction\n   should be used to extract results.\n\n   A fatal error results if an invalid function identifier is\n   specified, or if an attempt is made to extract functions from an\n   unevaluted TSIL_DATA struct.\n\n---------------------------------------------------------------------\n\n6. TSIL_COMPLEX TSIL_GetFunction (TSIL_DATA *foo, const char *str)\n\n   Returns a single function from *foo according to the string\n   provided.  str may be any of\n\n         \"M\",\n\t \"Uzxyv\", \"Uuyxv\", \"Uxzuv\", \"Uyuzv\",\n\t \"Vzxyv\", \"Vuyxv\", \"Vxzuv\", \"Vyuzv\",\n\t \"Tvyz\", \"Tuxv\", \"Tyzv\", \"Txuv\", \"Tzyv\", \"Tvxu\",\n\t \"Svyz\", \"Suxv\",\n\t \"Bxz\", or \"Byu\"\n\n   Example:\n   ========\n   TSIL_DATA foo;\n   TSIL_COMPLEX tyzv;\n   ...\n   tyzv = TSIL_GetFunction (\u0026foo, \"Tyzv\");\n\n   Note that function identifier strings that are permutations of the\n   ones shown are also allowed, if they match the symmetries of the\n   basis functions.  For example, the U functions are symmetric under\n   interchange of their last two arguments: U(z,x,y,v) = U(z,x,v,y).\n   This function can be accessed using the ideintifier string \"Uzxvy\"\n   in addition to \"Uzxyv\".  Likewise, any of the strings \"Suxv\",\n   \"Sxuv\", \"Suvx\", \"Svux\", \"Sxvu\", or \"Svxu\" will return the function\n   S(u,x,v) (symmetric under interchange of any of its arguments),\n   etc.\n\n   Note also that where there is only a single function of a given\n   type available, only the first character in the specification\n   string is relevant.  For example, for STU evaluation the single\n   U-type function Uxzuv can be extracted using \"Uxzuv\" or \"U\".\n\n   A fatal error results if an invalid function identifier is\n   specified, or if an attempt is made to extract a function from an\n   unevaluted TSIL_DATA struct.\n\n---------------------------------------------------------------------\n\n6a. TSIL_COMPLEX TSIL_GetFunctionR (TSIL_RESULT *foo, const char *str)\n\n   Same functionality as TSIL_GetFunction above, but takes a pointer\n   to a TSIL_RESULT rather than a TSIL_DATA.\n\n---------------------------------------------------------------------\n\n7. TSIL_COMPLEX TSIL_GetBoldFunction (TSIL_DATA *foo, \n                                      const char *str,\n\t\t\t\t      int n)\t\t\t      \n\n   Like TSIL_GetFunction but returns the coefficient of 1/epsilon^n in\n   the \"bold\" variant function specified by the string str.  As above,\n   str may be any of\n\n         \"M\",\n\t \"Uzxyv\", \"Uuyxv\", \"Uxzuv\", \"Uyuzv\",\n\t \"Vzxyv\", \"Vuyxv\", \"Vxzuv\", \"Vyuzv\",\n\t \"Tvyz\", \"Tuxv\", \"Tyzv\", \"Txuv\", \"Tzyv\", \"Tvxu\",\n\t \"Svyz\", \"Suxv\",\n\t \"Bxz\", or \"Byu\"\n\n   (or permutations matching the symmetries of the basis functions).\n\n   Example:\n   ========\n   TSIL_DATA foo;\n   TSIL_COMPLEX tyzv2;\n   ...\n   /* Returns power of 1/epsilon^2 in bold Tyzv: */\n   tyzv2 = TSIL_GetBoldFunction (\u0026foo, \"Tyzv\", 2);\n\n   Note that where there is only a single function of a given type\n   available, only the first character in the specification string is\n   relevant.  E.g., for STU evaluation the single U-type function\n   Uxzuv can be extracted using \"Uxzuv\" or \"U\".\n\n   A fatal error results if an invalid function identifier is\n   specified, or if an attempt is made to extract a function from an\n   unevaluted TSIL_DATA struct.\n\n---------------------------------------------------------------------\n\n8. void TSIL_CopyResult (TSIL_DATA *foo, TSIL_RESULT *bar)\n\n   Copies the parameters and integral values from an evaluated\n   TSIL_DATA struct into a smaller TSIL_RESULT struct, for\n   convenience.\n\n---------------------------------------------------------------------\n\n9. void TSIL_PermuteResult (TSIL_RESULT *in, int perm, TSIL_RESULT *out)\n\n   Permutes the arguments of a TSIL_RESULT *in to produce a new\n   TSIL_RESULT *out. The integral functions are reorganized\n   appropriately.\n\n   Allowed values of perm are:\n\n   0 (or NOSWAP)  - No permutation, just copies the result\n   1 (or XYandZU) - Permute x \u003c-\u003e y and z \u003c-\u003e u\n   2 (or XZandYU) - Permute x \u003c-\u003e z and y \u003c-\u003e u\n   3 (or XUandYZ) - Permute x \u003c-\u003e u and y \u003c-\u003e z\n\n---------------------------------------------------------------------\n\nI/O and Related Functions\n=========================\n\n1. void TSIL_PrintStatus (TSIL_DATA *foo)\n\n   Prints to stdout the evaluation status of *foo, whether\n   unevaluated, evaluated by analytical formula, evaluated by\n   numerical integration along real s axis, or evaluated by numerical\n   integration along displaced contour.\n\n---------------------------------------------------------------------\n\n2. void TSIL_PrintData (TSIL_DATA *foo)\n\n   Prints to stdout the values of all integral functions associated\n   with *foo, including Tbar, V, and \"bold\" variants. In STU or\n   ST evaluation only the appropriate subset of functions is\n   displayed.\n\n---------------------------------------------------------------------\n\n3. void TSIL_WriteData (FILE *fp, TSIL_DATA *foo)\n\n   Like TSIL_PrintData, but writes to the file pointer fp rather than\n   stdout.  The user is responsible for properly initializing the file\n   pointer.\n\n---------------------------------------------------------------------\n\n4. void TSIL_PrintDataM (TSIL_DATA *foo)\n\n   Same as TSIL_PrintData, but uses a format that is valid Mathematica\n   input.\n\n---------------------------------------------------------------------\n\n5. void TSIL_WriteDataM (FILE *fp, TSIL_DATA *foo)\n\n   Same as TSIL_WriteData, but uses a format that is valid Mathematica\n   input.\n\n---------------------------------------------------------------------\n\n6. void TSIL_cprintf (TSIL_COMPLEX)\n\n   Prints a complex value to stdout.  (No newline is appended.)\n\n---------------------------------------------------------------------\n\n7. void TSIL_cprintfM (TSIL_COMPLEX)\n\n   Prints a complex value to stdout in a form digestible by\n   Mathematica.  (No newline is appended.)\n\n---------------------------------------------------------------------\n\n8. void TSIL_Error (char *func, char *msg, int errcode)\n\n   Prints an error message to stderr and exits with status errcode.\n   The message contains the function in which the error was generated\n   (func) and an error-specific message (msg) of the user's choice.\n\n---------------------------------------------------------------------\n\n9. void TSIL_Warn (char *func, char *msg)\n\n   Prints a warning message to stderr; execution continues normally.\n   The message contains the function in which the error was generated\n   (func) and an error-specific message (msg) of the user's choice.\n\n---------------------------------------------------------------------\n\nUtilities\n=========\n\n1. void TSIL_ResetStepSizeParams (TSIL_DATA *foo,\n\t\t\t          TSIL_REAL precisionGoal,\n                                  int nStepsStart,\n\t\t\t\t  int nStepsMaxCon,\n\t\t\t\t  int nStepsMaxVar,\n\t\t\t\t  int nStepsMin)\n\n   Allows modification of integration parameters.  In *foo, sets\n   precisionGoal, nStepsStart, nStepsMaxCon, nStepsMaxVar, nStepsMin\n   to the specified values.  A subsequent call to TSIL_SetParameters\n   will cause these to reset to their default values.\n\n---------------------------------------------------------------------\n\n2. int TSIL_IsInfinite (TSIL_COMPLEX z)\n\n   Returns 1 (TRUE) or 0 (FALSE) according to whether z is infinite.\n\n---------------------------------------------------------------------\n\n3. int TSIL_DataSize (void)\n\n   Returns a code indicating the size of intrinsic datatypes.\n   Possible values are:\n\n\t    0   long double\n\t    1   double\n\n   Note that there are enum'ed constants (LONG_DOUBLE, DOUBLE)\n   representing these available in tsil_global.h.\n\n---------------------------------------------------------------------\n\n4. void TSIL_PrintInfo (void)\n\n   Prints intrinsic datatype used by TSIL to stdout.\n\n---------------------------------------------------------------------\n\n5. void TSIL_PrintVersion (void)\n\n   Prints the current version of TSIL to stdout.\n\n---------------------------------------------------------------------\n\n6. void TSIL_WarnsOff (void)\n\n   Disables warning messages, for example when one tries to access an\n   undefined function with TSIL_GetFunction, TSIL_GetBoldFunction,\n   TSIL_GetData, or TSIL_GetBoldData.  Error messages cannot be\n   disabled.\n\n---------------------------------------------------------------------\n\n7. void TSIL_WarnsOn (void)\n\n   Enables warning messages, for example when one tries to access an\n   undefined function with TSIL_GetFunction, TSIL_GetBoldFunction,\n   TSIL_GetData, or TSIL_GetBoldData.  This is the default setting.\n\n\nAnalytic Cases\n==============\n\n1. TSIL_COMPLEX TSIL_Dilog (TSIL_COMPLEX z)\n\n   Returns the dilogarithm of z.\n\n---------------------------------------------------------------------\n\n2. TSIL_COMPLEX TSIL_Trilog (TSIL_COMPLEX z)\n\n   Returns the trilogarithm of z.\n\n---------------------------------------------------------------------\n\n3. TSIL_REAL TSIL_A (TSIL_REAL x, TSIL_REAL qq)\n\n   Returns the one-loop vacuum function A(x) with renormalization\n   scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n4. TSIL_REAL TSIL_Ap (TSIL_REAL x, TSIL_REAL qq)\n\n   Returns the derivative of the one-loop vacuum function A(x) with\n   respect to x, with renormalization scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n5. TSIL_COMPLEX TSIL_Aeps (TSIL_REAL x, TSIL_REAL qq)\n\n   Returns A_epsilon(x) with renormalization scale squared equal to\n   qq.\n\n---------------------------------------------------------------------\n\n6. TSIL_COMPLEX TSIL_B (TSIL_REAL x,\n\t\t        TSIL_REAL y,\n\t\t\tTSIL_COMPLEX s,\n\t\t\tTSIL_REAL qq)\n\n   Returns the one-loop self-energy function B(x,y) with external\n   momentum invariant s and renormalization scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n7. TSIL_COMPLEX TSIL_Bp (TSIL_REAL x,\n\t\t\t TSIL_REAL y,\n\t\t\t TSIL_COMPLEX s,\n\t\t\t TSIL_REAL qq)\n\n   Returns the function B(x',y) for external momentum invariant s and\n   renormalization scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n8. TSIL_COMPLEX TSIL_dBds (TSIL_REAL x,\n\t\t\t   TSIL_REAL y,\n\t\t\t   TSIL_COMPLEX s, \n\t\t\t   TSIL_REAL qq)\n\n   Returns the derivative of B(x,y) with respect to s, for external\n   momentum invariant s and renormalization scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n9. TSIL_COMPLEX TSIL_Beps (TSIL_REAL x,\n\t\t\t   TSIL_REAL y,\n\t\t\t   TSIL_COMPLEX s, \n                           TSIL_REAL qq)\n\n   Returns the function B_epsilon(x,y) for external momentum invariant\n   s and renormalization scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n10. TSIL_COMPLEX TSIL_I2 (TSIL_REAL x,\n     \t\t\t  TSIL_REAL y,\n\t\t\t  TSIL_REAL z,\n\t\t\t  TSIL_REAL qq)\n\n   Returns the two-loop vacuum integral I(x,y,z), with renormalization\n   scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n11. TSIL_COMPLEX TSIL_I2p (TSIL_REAL x,\n\t\t\t   TSIL_REAL y,\n\t\t\t   TSIL_REAL z,\n\t\t\t   TSIL_REAL qq)\n\n   Returns the first derivative I(x',y,z), with renormalization scale\n   squared equal to qq.\n\n---------------------------------------------------------------------\n\n12. TSIL_COMPLEX TSIL_I2p2 (TSIL_REAL x,\n\t\t\t    TSIL_REAL y,\n\t\t\t    TSIL_REAL z,\n\t\t\t    TSIL_REAL qq)\n\n   Returns the second derivative I(x'',y,z), with renormalization\n   scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n13. TSIL_COMPLEX TSIL_I2pp (TSIL_REAL x,\n\t\t\t    TSIL_REAL y,\n\t\t\t    TSIL_REAL z,\n\t\t\t    TSIL_REAL qq)\n\n   Returns the mixed second derivative I(x',y',z), with\n   renormalization scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n14. TSIL_COMPLEX TSIL_I2p3 (TSIL_REAL x,\n\t\t\t    TSIL_REAL y,\n\t\t\t    TSIL_REAL z,\n\t\t\t    TSIL_REAL qq)\n\n   Returns the third derivative I(x''',y,z), with renormalization\n   scale squared equal to qq.\n\n---------------------------------------------------------------------\n\n15. int TSIL_Sanalytic (TSIL_REAL x,\n\t\t        TSIL_REAL y,\n\t\t\tTSIL_REAL z,\n\t\t\tTSIL_COMPLEX s,\n\t\t\tTSIL_REAL qq,\n\t\t\tTSIL_COMPLEX *res)\n\n    If an analytic result for S(x,y,z) for external momentum invariant\n    s is available, return 1 (TRUE) and evaluate it for\n    renormalization scale squared qq.  The result is placed in *res.\n\n    If no analytical result for S is available, return 0 (FALSE).  In\n    this case *res is unchanged.\n\n---------------------------------------------------------------------\n\n16. int TSIL_Tanalytic (TSIL_REAL x,\n\t\t        TSIL_REAL y,\n\t\t\tTSIL_REAL z,\n\t\t\tTSIL_COMPLEX s,\n\t\t\tTSIL_REAL qq,\n\t\t\tTSIL_COMPLEX *res)\n\n    If an analytic result for T(x,y,z) for external momentum invariant\n    s is available, return 1 (TRUE) and evaluate it for\n    renormalization scale squared qq.  The result is placed in *res.\n\n    If no analytical result for T is available, return 0 (FALSE).  In\n    this case *res is unchanged.\n\n---------------------------------------------------------------------\n\n17. int TSIL_Tbaranalytic (TSIL_REAL x,\n\t\t\t   TSIL_REAL y,\n\t\t\t   TSIL_REAL z,\n\t\t\t   TSIL_COMPLEX s,\n\t\t\t   TSIL_REAL qq,\n\t\t\t   TSIL_COMPLEX *res)\n\n    If an analytic result for Tbar(x,y,z) for external momentum\n    invariant s is available, return 1 (TRUE) and evaluate it for\n    renormalization scale squared qq.  The result is placed in *res.\n\n    If no analytical result for Tbar is available, return 0 (FALSE).\n    In this case *res is unchanged.\n\n---------------------------------------------------------------------\n\n18. int TSIL_Uanalytic (TSIL_REAL x,\n    \t\t\tTSIL_REAL y,\n\t\t\tTSIL_REAL z,\n\t\t\tTSIL_REAL u,\n\t\t\tTSIL_COMPLEX s,\n\t\t\tTSIL_REAL qq,\n\t\t\tTSIL_COMPLEX *res)\n\n    If an analytic result for U(x,y,z,u) for external momentum\n    invariant s is available, return 1 (TRUE) and evaluate it for\n    renormalization scale squared qq.  The result is placed in *res.\n\n    If no analytical result for U is available, return 0 (FALSE).  In\n    this case *res is unchanged.\n\n---------------------------------------------------------------------\n\n19. int TSIL_Vanalytic (TSIL_REAL x,\n    \t\t\tTSIL_REAL y,\n\t\t\tTSIL_REAL z,\n\t\t\tTSIL_REAL u,\n\t\t\tTSIL_COMPLEX s,\n\t\t\tTSIL_REAL qq,\n\t\t\tTSIL_COMPLEX *res)\n\n    If an analytic result for V(x,y,z,u) for external momentum\n    invariant s is available, return 1 (TRUE) and evaluate it for\n    renormalization scale squared qq.  The result is placed in *res.\n\n    If no analytical result for V is available, return 0 (FALSE).  In\n    this case *res is unchanged.\n\n---------------------------------------------------------------------\n\n20. int TSIL_Manalytic (TSIL_REAL x,\n    \t\t\tTSIL_REAL y,\n\t\t\tTSIL_REAL z,\n\t\t\tTSIL_REAL u,\n\t\t\tTSIL_REAL v,\n\t\t\tTSIL_COMPLEX s,\n\t\t\tTSIL_REAL qq,\n\t\t\tTSIL_COMPLEX *res)\n\n    If an analytic result for M(x,y,z,u,v) for external momentum\n    invariant s is available, return 1 (TRUE) and evaluate it for\n    renormalization scale squared qq.  The result is placed in *res.\n    If no analytical result for M is available, return 0 (FALSE).  In\n    this case *res is unchanged.\n\n---------------------------------------------------------------------\n\n\nFortran Interface\n=================\n\nsubroutine tsilfevaluate (REAL x,\n\t\t\t  REAL y,\n\t\t\t  REAL z,\n\t\t\t  REAL u,\n\t\t\t  REAL v,\n\t\t\t  REAL qq,\n\t\t\t  REAL s)\n\nWrapper for TSIL_Evaluate, to be called from Fortran.  See \"Using TSIL\nwith Fortran\" below for complete details.\n\n---------------------------------------------------------------------\n\n\n************************************************************************\nV. Numerical Integration in TSIL\n************************************************************************\n\nAs discussed in [MR05], we generically use a 6-stage, 5th-order\nembedded Runge-Kutta scheme with coefficients given by Cash and Karp.\nThis gives an error estimate for each dependent variable at each step\nand thus allows estimation of the step size necessary to achieve a\ngiven precision.\n\nIn addition, whenever the final value of s is at (or near) a threshold\nor pseudo-threshold, we switch for the final leg of the numerical\nintegration to a 5-stage, 4th-order scheme.  This is slower and does\nnot provide an error estimate, but it avoids evaluation of basis\nfunction derivatives at the endpoint, where they may be singular.\n\nThe \"nearness\" criterion is controlled by the constant THRESH_CUTOFF,\nwhich is defined in tsil_params.h and has default value 0.025.  (This\nis in dimensionless units; prior to numerical integration all\ndimensionful quantities are rescaled by the largest of x,y,z,u,v, and\n|s|.)  That is, if the final value of s is within 0.025 of the nearest\nthreshold or pseudo-threshold, the special 5-stage, 4th order\nintegration is used for the last leg of integration, otherwise the\nnormal 6-stage scheme is used throughout.  Users can adjust this value\nif they find their results to be excessively sensitive to thresholds\nor pseudo-thresholds outside this limit.\n\nFor the generic rectangular integration contour described in [MR05],\nthe displacement along the imaginary axis of the complex s plane is\nset by IM_DISPL, also defined in tsil_params.h.  Its default value is\n0.2, again in dimensionless units.  Of course all results should be\nindependent of this value, so users can change this as a probe of\nnumerical stability if unusual results are observed.\n\nFinally let us describe the parameters associated with adaptive\nstepsize control.  These are also all defined in tsil_params.h, and,\nalong with the intrinsic data size chosen, they have the most\nsignificant effect on execution speed and accuracy.\n\nThese are realized as members of the TSIL_DATA struct, with names:\n\n* precisionGoal: This is \\delta_P in eq. (3.14) of [MR05].  (We use a\n                 safety factor S=0.9.)  If the maximum estimated error\n                 for any dependent variable exceeds \\delta_P\n                 multiplied by the increment of that variable for that\n                 step, and also exceeds the relative precision of the\n                 computer arithmetic times the absolute value of that\n                 variable, then the step is retried with a smaller\n                 step size, unless the step size would become smaller\n                 than specified below. Also, after a successful step,\n                 the size for the next step is chosen according to\n                 eq. (3.14), unless it would exceed the\n                 amount specified below.  (Defaults: 10^{-12} for long\n                 double data, 5 x 10^{-11} for double data.)\n\n* nStepsStart:   For each leg of the contour, the initial step size is\n                 chosen so that there would be this many steps if the\n                 step size did not change. (Default: 500)\n\n* nStepsMin:     The maximum allowed step size on a leg of the contour\n                 with dimensionless (rescaled) independent variable \n\t\t length L is given by L/nStepsMin. (Default: 100)\n\n* nStepsMaxCon,\n  nStepsMaxVar:  The minimum allowed step size on a leg of the contour\n\t\t with dimensionless independent variable length L is \n\t\t given by L/(nStepsMaxCon + L*nStepsMaxVar).\n\t\t (Defaults: 10000, 10000)\n\nThe step size is not allowed to increase by more than a factor of 1.5\nor decrease by more than a factor of 2 after each step or attempted\nstep.  Note that by setting precisionGoal to 0, one can arrange that\nthe total number of steps on each leg tends to nStepsMaxCon +\nL*nStepsMaxVar. If instead one sets precisionGoal to a very large\nnumber, the number of steps will tend to nStepsMin.\n\nThe default values have been found to give good results for a wide\nvariety of different choices of input parameters, for the integration\nvariables used in the program.  However, to deal with exceptional\nsituations, they can be reset at run time with the function\nTSIL_ResetStepSizeParams, after calling TSIL_SetParameters and before\ncalling TSIL_Evaluate.\n\nNote that in general, long double data (typically with 63 or more bits\nof relative precision) gives results with relative accuracies better\nthan 10^{-10} for generic cases, but sometimes somewhat worse in cases\nwith large mass hierarchies, and in some particularly difficult cases\nsignificantly worse.  (The function V(x,y,z,u) for very small but\nnon-zero y can be particularly sensitive to roundoff errors, since the\nindividual terms in its evaluation are proportional to 1/y and yet it\nis only logarithmically divergent as y approaches 0.)  The user should\nconsider modifying the default parameters of the program if\nsignificant sensitivity to parameters is expected (or observed), or if\nspeed is an overriding concern.\n\n\n************************************************************************\nVI. Using TSIL with C++\n************************************************************************\n\nIt is possible to call TSIL functions from C++ code.  The header file\n\ntsil_cpp.h\n\nshould be included in any C++ source files that make use of TSIL\nfunctions.  This file is equivalent to the usual tsil.h, but with\nadditional definitions to streamline interoperation with C++.\n\nCare should be taken that C++ type sizes match those used in TSIL.\nFor example, if TSIL was compiled with -DTSIL_SIZE_LONG (so that real\nvariables are long double and complexes are long double complex), then\nyou must use\n\nstd::complex\u003clong double\u003e\n\nfor the corresponding C++ variables.  A simple way to achieve this is\nto compile your C++ code with the usual TSIL macro:\n\n-DTSIL_SIZE_LONG\n\nor\n\n-DTSIL_SIZE_DOUBLE\n\n(the former is the default).  This will set the macros\n\nTSIL_REAL\nTSIL_COMPLEXCPP\n\nto the approriate types.  Note that macro TSIL_COMPLEX retains its\ndefinition as the appropriate C complex type, i.e., double _Complex or\nlong double _Complex.\n\nThe one real subtlety has to do with compatibility of the C complex\ntype and C++ std::complex\u003c\u003e, for example when a TSIL function returns\na TSIL_COMPLEX and the result is to be stored in a std::complex\u003c\u003e of\nappropriate size, or when a TSIL function takes a complex value as an\nargument.  Despite that the two complex types are supposed to be byte\nequivalent, a straight assignment of this type does not work as\nexpected for all compilers.\n\nHowever, the relevant standards guarantee that *pointers* to either\ntype will be correctly interpreted in any context.  Hence it is\nnecessary to add \"wrapper\" code around such TSIL function calls, so\nthat complex values (either return values or arguments) are referred\nto via pointers.\n\nWhat this means for the user is that the TSIL functions all have\nC++-specific versions that can be called with C++ types as arguments\nand will return C++ types.  The names of these are the same as the\ncorresponding TSIL functions, with a trailing underscore.  Thus the C\nfunction\n\nTSIL_GetFunction (...)\n\nbecomes\n\nTSIL_GetFunction_ (...) \n\nwhen called from C++, etc.  *All* functions in the user API have been\nsupplied with such wrappers, even though not all functions really need\nthem; this is so that users need not remember which functions have\nspecial names.\n\nAll these definitions appear at the end of tsil_cpp.h, should you wish\nto examine them.\n\nThe sample code\n\nscalarpole.cpp\n\nshows all this in action.  After building TSIL, it can be compiled as, e.g.,\n\ng++ scalarpole.cpp -L. -ltsil\n\nIn this C++ source code, note the\n* inclusion of tsil_cpp.h;\n* declaration of pi1, etc., as TSIL_COMPLEXCPP, which will default to\n  std::complex\u003clong double\u003e;\n* use of the C++-specific calls to TSIL_A_, TSIL_B_,\n  TSIL_GetFunction_, etc.\n\nPlease alert the authors if you encounter any issues using TSLI with\nC++ code!\n\n\n************************************************************************\nVII. Using TSIL with Fortran\n************************************************************************\n\nIt is possible to use TSIL with Fortran, and some basic utilities for\nthis are included with the package.  Essential functionality is\nprovided by a wrapper function tsilfevaluate (defined in the file\nfevaluate.c), which is called as a subroutine from a Fortran program.\nThis subroutine implements the most general TSIL calculation: it takes\nas arguments x,y,z,u,v,Q^2, and s and returns the values of all basis\nfunctions, including Tbar, V, and \"bold\" functions.\n\nThese results are returned to the calling program in a COMMON block,\nwhich corresponds to a special C struct used by tsilfevaluate.  This\nCOMMON block contains a number of pre-defined arrays that hold the\nvarious function values.  Definitions of the COMMON block and\nsubsidiary arrays are given in the header file\n\n       tsil_fort.inc\n\nwhich users should INCLUDE in their Fortran program.\n\nIMPORTANT NOTE: It is crucial that the type sizes match between the\ncalling Fortran program and TSIL, because the COMMON block must have\nthe same memory \"footprint\" as the C struct defined in the wrapper\ncode.  In addition, the arguments to tsilfevaluate must be\nconsistently defined in both fevaluate.c and the calling Fortran\nprogram.  Type mismatches will often result in non-fatal errors.\nUsers should be aware that corresponding types may not actually exist,\ndepending on platform and compiler.  (For example, on a Pentium (IA32)\nCPU, gcc supports 8-byte doubles and 12-byte long doubles, but g77\nonly supports REAL*8.)  It is strongly recommended that exact type\nsizes for your system be determined before building TSIL for use with\nFortran.\n\nThe Fortran include file\n\n       tsil_fort.inc\n\nassumes that the basic floating-point type in the Fortran program is\nREAL*8, assumed to be equivalent to C type double.  (This is true on\nall systems of which the authors are aware, but anomalies may exist.)\nThe associated complex type is of course COMPLEX*16.  These types must\nmatch those defined in the file\n\n       tsil_fortran.h\n\nwhich contains definitions for the C wrapper program (fevaluate.c).\nSpecifically, the macro\n\n       TSIL_REAL_F\n\nshould be set to the C type corresponding to the Fortran floating-\npoint type used (default: double).  Furthermore,\n\n       TSIL_COMPLEX_F\n\nshould be set to the C type corresponding to the Fortran complex type\n(default: double complex).  Finally,\n\n       TSIL_REAL_SIZE\n\nshould be set to the number of bytes in the basic floating-point type\n(default: 8 for REAL*8/double).  This value is used when tsilfevaluate\nis called to test whether there may be a type mismatch.  (If a\npossible mismatch is detected, a warning message is printed but\nexecution continues.)  However, this test is rather simple and should\nnot be relied upon to detect all possible errors.\n\nNote that in principle these types need not match the basic types used\nin the main TSIL routines.  When the wrapper calls TSIL_Evaluate, the\narguments are cast to the appropriate type used in the main TSIL\nlibrary (i.e., to TSIL_REAL), and upon return the results are cast\nback to the type TSIL_COMPLEX_F, appropriate for return to the calling\nFortran program.  Thus it can be that the Fortran program uses a\n\"smaller\" type, which is cast by the wrapper to a more precise type\nfor evaluation, and then cast back to the earlier type for return.\n\nFor example, in the case mentioned parenthetically above (IA32 CPU\nwith gcc/g77) the 8-byte type is the only option for the struct/COMMON\nblock that enables communication between Fortran and the wrapper\nprogram.  Thus the Fortran code would use REAL*8, and TSIL_REAL_F and\nTSIL_COMPLEX_F would be set to double and double complex,\nrespectively.  However, the main TSIL library could be built with\neither double or long double.  In the latter case, the input\nparameters would be cast to long double for evaluation, giving\nadditional accuracy in the results.\n\n\nSample Code\n===========\n\nA Fortran program fragment that uses these utilities is shown below. \n\n       PROGRAM ftest\nc      Includes array and COMMON definitions:\n       INCLUDE 'tsil_fort.inc'\n\nc      (Code setting values of x,y,z,u,v,qq,s not shown)\n       ...\nc      Evaluate basis integrals:\n       CALL tsilfevaluate(x,y,z,u,v,qq,s)\n\nc      Print a representative value:\n       PRINT *, U(xzuv)\n       ...\n\nNote in the last line the use of the INTEGER xzuv.  This is one of a\nset of integer variables, also defined in tsil_fort.inc, that allow\nitems in the COMMON block arrays to be referred to by name.\n\nA complete functional sample fortran program is available in ftest.f. It \ncan be compiled by\n\n     g77 ftest.f -L. -ltsil\n\nRunning ./a.out then prints out the values of the integral functions\nfor the case x, y, z, u, v, s, qq = 1, 2, 3, 4, 5, 10, 1\n\n\nCompiling with g77 under Mac OS X\n=================================\n\nNote that when using g77 under Mac OS X, the flags\n\n     -lmx -lcc_dynamic\n\nare required in addition to the flags that link the tsil archive.\nThus to compile the test program ftest.f one would typically use\n\n     g77 ftest.f -lmx -lcc_dynamic -L. -ltsil\n\nassuming libtsil.a is in the current directory (.).  See the g77\ndocumentation for additional information.\n\n\nOther General Fortran Issues\n============================\n\nThe provided wrapper code can serve as a model for users wishing to\nwrite their own interface routines with additional functionality.  In\naddition to the type size issue discussed above, the following general\npoints should be noted:\n\n* In Fortran arguments are passed by reference, i.e. as pointers in C.\n  Thus any C function that is called from Fortran should have pointer\n  arguments.\n\n* Fortran compilers typically append an underscore to all external\n  names, to identify them as Fortran constructs.  (This is important\n  because of the call-by-reference convention.)  Thus the Fortran\n  subroutine tsilfevaluate is known as tsilfevaluate_ in C, and the\n  COMMON block results corresponds to the struct results_ in C.\n  Fortran names that already contain an underscore typically have\n  two underscores appended.  Unfortunately, these conventions are\n  not uniform among Fortran compilers, so testing is required in any\n  particular case.  The utilities provided with TSIL have been tested\n  with the GNU compilers gcc/g77 and the Intel compilers icc/ifort.\n\n* Fortran and C store the elements of multi-dimensional arrays in a\n  different order (column-major and row-major ordering, respectively).\n  Thus a two-dimensional array generated in C must be reorganized for\n  proper indexing in Fortran.  This reorganization amounts to\n  \"transposing\" the arrays, interpreted as matrices.  Note also that\n  indexing conventions differ: Fortran array indices start at 1 while\n  C indices start at 0.\n\n************************************************************************\nEnd of README.txt\n************************************************************************\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpander%2Ftsil-mirror","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexpander%2Ftsil-mirror","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpander%2Ftsil-mirror/lists"}