file Backends/mathematica_function.hpp
[No description available] More…
Namespaces
Name |
---|
Gambit TODO: see if we can use this one: |
Gambit::Backends |
Classes
Name | |
---|---|
class | Gambit::Backends::mathematica_function Holds the info about a Mathematica backend function, and defines conversion functions. |
Detailed Description
Author:
- Tomas Gonzalo (t.e.gonzalo@fys.uio.no)
- Pat Scott (p.scott@imperial.ac.uk)
Date:
- 2016 Sep
- 2017 Dec
Templated class for holding and executing pointers to Mathematica backends.
Authors (add name and date if you modify):
Source code
// GAMBIT: Global and Modular BSM Inference Tool
// *********************************************
/// \file
///
/// Templated class for holding and executing
/// pointers to Mathematica backends.
///
/// *********************************************
///
/// Authors (add name and date if you modify):
///
/// \author Tomas Gonzalo
/// (t.e.gonzalo@fys.uio.no)
/// \date 2016 Sep
///
/// \author Pat Scott
/// (p.scott@imperial.ac.uk)
/// \date 2017 Dec
///
/// *********************************************
#ifndef __mathematica_function_hpp__
#define __mathematica_function_hpp__
#include "gambit/Elements/ini_catch.hpp"
#include "gambit/Utils/util_functions.hpp"
#include "gambit/Backends/backend_singleton.hpp"
#include "gambit/cmake/cmake_variables.hpp"
#include <boost/algorithm/string/replace.hpp>
#ifdef HAVE_MATHEMATICA
#include "gambit/Backends/mathematica_helpers.hpp"
#include MATHEMATICA_WSTP_H
#endif
namespace Gambit
{
namespace Backends
{
/// Holds the info about a Mathematica backend function, and defines conversion functions.
template <typename TYPE, typename... ARGS>
class mathematica_function
{
private:
#ifdef HAVE_MATHEMATICA
/// Pointer to the Mathematica Kernel running the session that this backend is loaded up in
WSLINK _WSlink;
#endif
/// The name of the backend function
str _symbol;
public:
/// Constructor
mathematica_function(const str& be, const str& ver, const str& symbol) : _symbol(symbol)
{
try
{
#ifdef HAVE_MATHEMATICA
// Extract the backend WSLINK pointer from the backendInfo object
if (backendInfo().works.at(be+ver))
{
_WSlink = backendInfo().loaded_mathematica_backends.at(be+ver);
}
else _WSlink = (WSLINK)0;
// Modify the symbol to allow for non-ASCII characters
boost::replace_all(_symbol, "\\[", "\\\\[");
#else
// Avoid compiler warnings
(void)be;
(void)ver;
#endif
}
catch (std::exception& e) { ini_catch(e); }
}
/// Operation (execute function and return value)
TYPE operator()(ARGS&&... args)
{
#ifdef HAVE_MATHEMATICA
// If TYPE is a numeric type, send N first
if(is_numeric<TYPE>())
{
if(!WSPutFunction(_WSlink, "N", 1))
{
math_error(_WSlink, LOCAL_INFO, "Error sending packet throught WSTP");
return TYPE();
}
}
// Send the symbol name now
if(!WSPutFunction(_WSlink, "Apply", 2) or
!WSPutFunction(_WSlink, "ToExpression",1) or
!WSPutString(_WSlink, _symbol.c_str()) or
!WSPutFunction(_WSlink, "List", sizeof...(args)))
{
math_error(_WSlink, LOCAL_INFO, "Error sending packet through WSTP");
return TYPE();
}
// Now send all the arguments
if (!WSPutVariables(_WSlink, args...))
{
math_error(_WSlink, LOCAL_INFO, "Error sending packet through WSTP");
return TYPE();
}
// Last, mark the end of the message
if(!WSEndPacket(_WSlink))
{
math_error(_WSlink, LOCAL_INFO, "Error sending packet through WSTP");
return TYPE();
}
// Wait to receive a packet from the kernel
int pkt;
while( (pkt = WSNextPacket(_WSlink), pkt) && pkt != RETURNPKT)
{
WSNewPacket(_WSlink);
if (WSError(_WSlink))
{
math_error(_WSlink, LOCAL_INFO, "Error reading packet from WSTP");
return TYPE();
}
}
// Read the received packet into the return value, unless it's void
if (boost::is_same<TYPE, void>::value)
{
WSNewPacket(_WSlink);
}
else
{
decltype(instance_helper<TYPE>::member) val;
if(!WSGetVariable(_WSlink, &val))
{
math_error(_WSlink, LOCAL_INFO, "Error reading packet from WSTP");
return TYPE();
}
return static_cast<TYPE>(val);
}
#else
// Avoid cimpiler warnings
Utils::dummy_function<ARGS...>(args...);
#endif
return TYPE();
}
};
}
}
#endif //defined __mathematica_function_hpp__
Updated on 2024-07-18 at 13:53:35 +0000