GitLab Repository | GitLab Wiki | Website | Report Issues | Chat

symbol x ( "x" ); value res ; std :: string method = "Newton" ; shell << Values ( FindRoot ( ArcTan ( 1000 * Cos ( x )), List ( x , 1 , 2 ), Rule ( "Method" ) = method )); shell >> res ; std :: vector < double > results = cast < std :: vector < double >> ( res ); std :: cout << results [ 0 ] << std :: endl ; // Prints 10.9956

$ bash < ( curl -s https://gitlab.com/neel.basu/mathematicapp/snippets/1752115/raw )

The above script pulls mathematica++ from git and sets up a Hallo World Project. you must have cmake , mathematica , boost installed in order this to work. Or clone it from gitlab. More on Quickstart and Build Instructions

$ git clone https://gitlab.com/neel.basu/mathematicapp.git $ cd mathematicapp $ mkdir build $ cd build $ cmake .. $ make

A C++ Library that talks Mathematica¶

Dot product and Determinant calculation in Mathematica Language

mata = Table [ Mod [ i + j , 2 ], { i , 1 , 2 }, { j , 1 , 2 }]; matb = Table [ Mod [ i + j , 3 ], { i , 1 , 2 }, { j , 1 , 2 }]; matc = Dot [ mata , matb ]; matd = Det [ matc ];

Equivalent C++ code with Mathematica++

mathematica :: m mata = Table ( Mod ( i + j , 2 ), List ( i , 1 , 2 ), List ( j , 1 , 2 )); mathematica :: m matb = Table ( Mod ( i + j , 3 ), List ( i , 1 , 2 ), List ( j , 1 , 2 )]; mathematica :: m matc = Dot ( mata , matb ); mathematica :: m matd = Det ( matc ); // Execute mathematica constructs and fetch the response shell << matd ; shell >> determinant ; // determinant can be converted to C++ machine sized types std :: cout << determinant << std :: endl ; // Prints -2

The Mathematica functions declared with MATHEMATICA_DECLARE outside any function (may be inside a header) e.g. MATHEMATICA_DECLARE(Table) , MATHEMATICA_DECLARE(Det)

outside any function (may be inside a header) e.g. , A symbols created using mathematica::symbol e.g. mathematica::symbol i("i") , mathematica::symbol j("j")

e.g. , mathematica::m creates a mathematica construct

creates a mathematica construct mathematica::value holds the value returnd from mathematica

// Declare Mathematica functions MATHEMATICA_DECLARE ( Table ) MATHEMATICA_DECLARE ( Mod ) MATHEMATICA_DECLARE ( Dot ) MATHEMATICA_DECLARE ( Det ) // connect to mathematica (optionally pass argc, argv) See http://reference.wolfram.com/language/ref/c/WSOpenArgcArgv.html connector shell ; // Declare symbols mathematica :: symbol i ( "i" ); mathematica :: symbol j ( "j" ); // declare variable to contain mathematica output mathematica :: value determinant ; // create mathematica constructs mathematica :: m mata = Table ( Mod ( i + j , 2 ), List ( i , 1 , 2 ), List ( j , 1 , 2 )); mathematica :: m matb = Table ( Mod ( i + j , 3 ), List ( i , 1 , 2 ), List ( j , 1 , 2 )]; mathematica :: m matc = Dot ( mata , matb ); mathematica :: m matd = Det ( matc ); // Execute mathematica constructs and fetch the response shell << matd ; shell >> determinant ; // determinant can be converted to C++ machine sized types std :: cout << determinant << std :: endl ; // Prints -2

Simple Example of adding all numbers in a list¶

using namespace mathematica ; symbol i ( "i" ); // declare mathematica symbol i value result_sum ; // declare the variable to hold the result shell << Total ( Table ( i , List ( i , 1 , 10 ))); // In Mathematica Total[Table[i, {i, 1, 10}]] shell >> result_sum ;

result_sum is the result object that can be converted to int , double , std::string and streamed to std::ostream .

std :: cout << result_sum << std :: endl ; // Prints 55 std :: cout << result_sum -> stringify () << std :: endl ; // Prints 55 int sum1 = * result_sum ; // auto coercion through type operator overloading for scaler types int sum2 = cast < int > ( result_sum ); double sum3 = * result_sum ; double sum4 = cast < double > ( result_sum ); std :: cout << sum1 << " " << sum2 << " " << sum3 << " " << sum4 << std :: endl ; // Prints 55 55 55 55

Fetching composite results (in STL containers)¶

mathematica::value can hold composite values returned from mathematica like this example of List

symbol i ( "i" ); // declare mathematica symbol i value result_list ; // declare the variable to hold the result shell << Table ( i , List ( i , 1 , 10 )); // In Mathematica Table[i, {i, 1, 10}] shell >> result_list ; std :: cout << result_list << std :: endl ; // Prints List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] std :: cout << result_list -> stringify () << std :: endl ; // Prints List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

mathematica::value object can be converted to an equivalent STL container like std::vector using mathematica::cast

std :: vector < int > list ; list = cast < std :: vector < int >> ( result_list );

Executing intermediate returned output¶

An mathematica::value object can be using to build a mathematica::m construct. Here res_mata and res_matb are values returned by mathematica that we are passing inside Det .

value res_mata ; value res_matb ; value res_matc ; value res_det ; shell << Table ( Mod ( i + j , 2 ), List ( i , 1 , 2 ), List ( j , 1 , 2 )); shell >> res_mata ; shell << Table ( Mod ( i + j , 3 ), List ( i , 1 , 2 ), List ( j , 1 , 2 )); shell >> res_matb ; shell << Dot ( res_mata , res_matb ); shell >> res_matc ; shell << Det ( res_matc ); shell >> res_det ;

Serialize struct to Mathematica Association ¶

struct point { std :: pair < int , int > location ; std :: string name ; double elevation ; point () : location ( std :: make_pair ( 0 , 0 )), name ( "" ), elevation ( 0.0f ){} point ( std :: pair < int , int > loc , const std :: string & name_ , double elevation_ ) : location ( loc ), name ( name_ ), elevation ( elevation_ ){} }; value result ; point pti ( std :: make_pair ( 1 , 1 ), "Hallo" , 100.0f ); shell << Evaluate ( pti ); shell >> result ; point pto = cast < point > ( result );

The object pti of type struct point is the above example will be serialized as Association[Rule["location", List[1, 1]], Rule["name", "Hallo"], Rule["elevation", 100]] . The associations need to be declared as following.

MATHEMATICA_ASSOCIATE ( point , std :: pair < int , int > , std :: string , double ){ MATHEMATICA_PROPERTY ( 0 , location ) MATHEMATICA_PROPERTY ( 1 , name ) MATHEMATICA_PROPERTY ( 2 , elevation ) };

more on Association

LibraryLink Support¶

Start with the known boilerplate code shown in mathematica manual. add function overloads to it. input arguments and returned output will be automatically be serialized and deserialized. Overload either based on head or based on number of arguments.

EXTERN_C DLLEXPORT int SomeFunctionX ( WolframLibraryData libData , WMK_LINK native_link ){ mathematica :: wtransport shell ( libData , native_link ); try { mathematica :: resolver resolver ( shell ); resolver , overload ( & some_function_impl_geo , shell ) = { "GeoPosition" , "GeoPosition" } , overload ( & some_function_impl_complex ) = { "Complex" , "Complex" } , overload ( & some_function_impl_binary ) , overload ( & some_function_impl_unary ); return resolver . resolve (); } catch (...){ return shell . pass (); } return 0 ; }

The impl functions in the above example have the following signature. The shell can be used to perform computations using mathematica.

double some_function_impl_geo ( mathematica :: transport & shell , point_2d < double > p1 , point_2d < double > p2 ){ std :: string unit ( "Kilometers" ); double res ; shell << QuantityMagnitude ( GeoDistance ( p1 , p2 , Rule ( "!UnitSystem" ) = unit )); shell >> res ; return res ; } double some_function_impl_complex ( std :: complex < double > p1 , std :: complex < double > p2 ); int some_function_impl_binary ( double x , double y ); mathematica :: m some_function_impl_unary ( double x );

Tensors can also be cast ed to nested std::vector . More on LibraryLink