Sympp

Build Status Website

Math

Symbolic computing deals with algorithms that manipulate mathematical expressions. They are useful for mathematical experiments, scientific computation, optimization, improving numerical methods, reducing approximation errors, and as an alternative when numerical analysis fails. However, algebraic manipulations tend to have very low performance, and that makes symbolic computing less attractive to a variety of fields that could otherwise benefit from it. In that context, this project proposes a library for symbolic computing whose symbols can compile themselves. SymPP can numerically evaluate expressions in runtime by 1) generating and compiling the symbolic tree as machine code, 2) concatenating recursive lambdas, or 3) with a depth-first search on the symbol nodes.

Facebook QZone Weibo Reddit Twitter LinkedIn WhatsApp Line.me Telegram.me HackerNews

Please note that this is a work in progress. See our roadmap to understand some of our plans for the future.

Table of Contents - [Examples](#examples) - [Hello World](#hello-world) - [Operations](#operations) - [Equations](#equations) - [Simplification](#simplification) - [Compiling expressions](#compiling-expressions) - [Benchmarks](#benchmarks) - [Integration](#integration) - [Packages](#packages) - [Build from source](#build-from-source) - [CMake targets](#cmake-targets) - [Other build systems](#other-build-systems) - [Limitations and Roadmap](#limitations-and-roadmap) - [Contributing](#contributing) - [Contributors](#contributors) - [Thanks](#thanks)

Examples

For complete examples, see the directory examples.

Hello World

By passing a string literal to a sym object, we create a symbolic variable:

#include <sympp/sympp.h>

int main() {
    using namespace sympp;
    using std::cout, std::endl;
    sym a("Hello");
    sym b("World");
    sym c = a + b;
    cout << c << endl;
    return 0;
}

Instead of trying to somehow immediately evaluate the expression, the result (c) stores the complete symbolic expression:

Hello+World

Operations

Symbols can represent constants, variables, numbers, functions, or complete expressions:

#include <sympp/sympp.h>

int main() {
    using namespace sympp;
    using std::cout, std::endl;
    // Constants
    sym A("A",10);
    sym n("n",3);
    sym pi = constant::pi();

    // Variables
    sym x1("x_1");
    sym x2("x_2");
    sym x3("x_3");

    // Function terms
    sym begin = A * n;
    sym term1 = sympp::pow(x1, sym(2)) - A * sympp::cos(2 * pi * x1);
    sym term2 = power(x2, sym(2)) - A * cosine(2 * pi * x2);
    sym term3 = power(x3, sym(2)) - A * cosine(2 * pi * x3);

    // Function
    sym rastrigin = begin + term1 + term2 + term3;

    cout << rastrigin << endl;
    return 0;
}

Output:

A*n+x_1^(2)-A*cos(2*pi*x_1)+x_2^(2)-A*cos(2*pi*x_2)+x_3^(2)-A*cos(2*pi*x_3)

Equations

Work in progress Work in progress

Simplification

Work in progress Work in progress

Compiling expressions

Work in progress Work in progress

Benchmarks

These benchmarks illustrate how we can have significant performance gains by compiling expressions. The compiled expressions not only perform better than the usual symbolic evaluation but also the original unsimplified numeric evaluation.

Work in progress Work in progress

Integration

Packages

You can download the binary packages from the CI artifacts or build the library from the source files.

Once the package is installed, link your C++ program to the library and include the directories where you installed SymPP.

Unless you changed the default options, the C++ library is likely to be in /usr/local/ (Linux / Mac OS) or C:/Program Files/ (Windows). The installer will try to find the directory where you usually keep your libraries but that’s not always perfect.

If you are using CMake, you can then find SymPP with the usual find_package command:

find_package(SymPP REQUIRED)
# ...
target_link_libraries(my_target PUBLIC sympp)

CMake should be able to locate the SymPPConfig.cmake script automatically if you installed the library under /usr/local/ (Linux / Mac OS) or C:/Program Files/ (Windows). Otherwise, you need to include your installation directory in CMAKE_MODULE_PATH first:

list(APPEND CMAKE_MODULE_PATH put/your/installation/directory/here)
find_package(SymPP REQUIRED)
# ...
target_link_libraries(my_target PUBLIC sympp)

Build from source

Dependencies

This section lists the dependencies you need before installing SymPP from source. The build script will try to find all these dependencies for you:

Instructions: Linux/Ubuntu/GCC Check your GCC version ```bash g++ --version ``` The output should have something like ```console g++-8 (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0 ``` If you see a version before GCC-8, update it with ```bash sudo apt update sudo apt install gcc-8 sudo apt install g++-8 ``` To update to any other version, like GCC-9 or GCC-10: ```bash sudo apt install build-essential sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt install g++-10 ``` Once you installed a newer version of GCC, you can link it to `update-alternatives`. For instance, if you have GCC-7 and GCC-10, you can link them with: ```bash sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 7 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 7 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10 ``` You can now use `update-alternatives` to set you default `gcc` and `g++`: ```bash update-alternatives --config g++ update-alternatives --config gcc ``` Check your CMake version: ```bash cmake --version ``` If it's older than CMake 3.14, update it with ```bash sudo apt upgrade cmake ``` or download the most recent version from [cmake.org](https://cmake.org/). [Later](#build-the-examples) when running CMake, make sure you are using GCC-8 or higher by appending the following options: ```bash -DCMAKE_C_COMPILER=/usr/bin/gcc-8 -DCMAKE_CXX_COMPILER=/usr/bin/g++-8 ```
Instructions: Mac Os/Clang Check your Clang version: ```bash clang --version ``` The output should have something like ```console Apple clang version 11.0.0 (clang-1100.0.33.8) ``` If you see a version before Clang 11, update XCode in the App Store or update clang with homebrew. Check your CMake version: ```bash cmake --version ``` If it's older than CMake 3.14, update it with ```bash sudo brew upgrade cmake ``` or download the most recent version from [cmake.org](https://cmake.org/). If the last command fails because you don't have [Homebrew](https://brew.sh) on your computer, you can install it with ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" ``` or you can follow the instructions in [https://brew.sh](https://brew.sh).
Instructions: Windows/MSVC * Make sure you have a recent version of [Visual Studio](https://visualstudio.microsoft.com) * Download Git from [https://git-scm.com/download/win](https://git-scm.com/download/win) and install it * Download CMake from [https://cmake.org/download/](https://cmake.org/download/) and install it

Build the Examples

This will build the examples in the build/examples directory:

mkdir build
cmake -version
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O2"
cmake --build . -j 2 --config Release

On windows, replace -O2 with /O2.

Installing SymPP from Source

This will install SymPP on your system:

mkdir build
cmake -version
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O2" -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF 
cmake --build . -j 2 --config Release
cmake --install .

On windows, replace -O2 with /O2. You might need sudo for this last command.

Building the packages

This will create the binary packages you can use to install SymPP on your system:

mkdir build
cmake -version
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O2" -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF
cmake --build . -j 2 --config Release
cmake --install .
cpack .

On windows, replace -O2 with /O2. You might need sudo for this last command.

CMake targets

Find it as a CMake Package

If you have the library installed, you can call

find_package(SymPP)

from your CMake build script.

When creating your executable, link the library to the targets you want:

add_executable(my_target main.cpp)
target_link_libraries(my_target PUBLIC sympp)

Add this header to your source files:

#include <sympp/sympp.h>

Use it as a CMake subdirectory

You can use SymPP directly in CMake projects without installing it. Check if you have Cmake 3.14+ installed:

cmake -version

Clone the whole project

git clone https://github.com/alandefreitas/sympp/

and add the subdirectory to your CMake project:

add_subdirectory(sympp)

When creating your executable, link the library to the targets you want:

add_executable(my_target main.cpp)
target_link_libraries(my_target PUBLIC sympp)

Add this header to your source files:

#include <sympp/sympp.h>

However, it’s always recommended to look for SymPP with find_package before including it as a subdirectory. Otherwise, we can get ODR errors in larger projects.

CMake with Automatic Download

Check if you have Cmake 3.14+ installed:

cmake -version

Install CPM.cmake and then:

CPMAddPackage(
    NAME SymPP
    GITHUB_REPOSITORY alandefreitas/sympp
    GIT_TAG origin/master # or whatever tag you want
)
# ...
target_link_libraries(my_target PUBLIC sympp)

Then add this header to your source files:

#include <sympp/sympp.h>

However, it’s always recommended to look for SymPP with find_package before including it as a subdirectory. You can use:

option(CPM_USE_LOCAL_PACKAGES "Try `find_package` before downloading dependencies" ON)

to let CPM.cmake do that for you. Otherwise, we can get ODR errors in larger projects.

Other build systems

If you want to use it in another build system you can either install the library (Section Installing) or you have to somehow rewrite the build script.

If you want to rewrite the build script, your project needs to 1) include the headers and compile all source files in the sources directory, and 2) link the dependencies described in sources/CMakeLists.txt.

Then add this header to your source files:

#include <sympp/sympp.h>

Limitations and Roadmap

Things SymPP needs to improve:

Things SymPP doesn’t do yet:

Contributing

There are many ways in which you can contribute to this library:

If contributing with code, please turn the pedantic mode ON (-DBUILD_WITH_PEDANTIC_WARNINGS=ON), don’t forget cppcheck and clang-format.

Example: CLion ![CLion Settings with Pedantic Mode](/sympp/documentation/images/pedantic_clion.png)

Contributors

alandefreitas
Alan De Freitas

Thanks

We would like to thank the developers of these libraries: