https://github.com/alandefreitas/sympp
SymPP: A Symbolic Library that compiles itself
https://github.com/alandefreitas/sympp
compile mathematical-modelling numerical-analysis optimization symbolic symbolic-computation
Last synced: 2 months ago
JSON representation
SymPP: A Symbolic Library that compiles itself
- Host: GitHub
- URL: https://github.com/alandefreitas/sympp
- Owner: alandefreitas
- License: mit
- Created: 2020-09-29T00:35:52.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2020-11-23T20:55:33.000Z (almost 5 years ago)
- Last Synced: 2025-03-25T09:21:45.646Z (7 months ago)
- Topics: compile, mathematical-modelling, numerical-analysis, optimization, symbolic, symbolic-computation
- Language: C++
- Homepage: https://alandefreitas.github.io/sympp/
- Size: 2.22 MB
- Stars: 13
- Watchers: 2
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Sympp
[](https://github.com/alandefreitas/sympp/actions?query=workflow%3ASymPP+event%3Apush)
[](https://alandefreitas.github.io/sympp/)
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.
[](https://www.facebook.com/sharer/sharer.php?t=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself&u=https://github.com/alandefreitas/sympp/)
[](http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=https://github.com/alandefreitas/sympp/&title=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself&summary=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself)
[](http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=https://github.com/alandefreitas/sympp/&title=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself&summary=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself)
[](http://www.reddit.com/submit?url=https://github.com/alandefreitas/sympp/&title=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself)
[](https://twitter.com/intent/tweet?text=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself&url=https://github.com/alandefreitas/sympp/&hashtags=SymbolicComputing,ComputerAlgebra,SymbolicComputation)
[](https://www.linkedin.com/shareArticle?mini=false&url=https://github.com/alandefreitas/sympp/&title=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself)
[](https://api.whatsapp.com/send?text=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself:+https://github.com/alandefreitas/sympp/)
[](https://lineit.line.me/share/ui?url=https://github.com/alandefreitas/sympp/&text=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself)
[](https://telegram.me/share/url?url=https://github.com/alandefreitas/sympp/&text=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself)
[](https://news.ycombinator.com/submitlink?u=https://github.com/alandefreitas/sympp/&t=SymPP:%20A%20Symbolic%20Library%20That%20Compiles%20Itself)> Please note that this is a work in progress. See our [roadmap](#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](./examples/).
### Hello World
By passing a string literal to a `sym` object, we create a symbolic variable:
```cpp
#includeint 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:
```console
Hello+World
```### Operations
Symbols can represent constants, variables, numbers, functions, or complete expressions:
```cpp
#includeint 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:
```console
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
### Simplification
>  Work in progress
### Compiling expressions
>  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
## Integration
### Packages
You can download the [binary packages from the CI artifacts](https://github.com/alandefreitas/sympp/actions?query=workflow%3ASymPP+event%3Apush) or build the library [from the source files](#build-from-source).
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:
```cmake
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:
```cmake
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:
* C++17
* CMake 3.14 or higher
* LibTCC (Embedded)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:
```bash
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:
```bash
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:
```bash
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
```cmake
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:
```cpp
#include
```#### Use it as a CMake subdirectory
You can use SymPP directly in CMake projects without installing it. Check if you have [Cmake](http://cmake.org) 3.14+ installed:
```bash
cmake -version
```Clone the whole project
```bash
git clone https://github.com/alandefreitas/sympp/
```and add the subdirectory to your CMake project:
```cmake
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:
```cpp
#include
```However, it's always recommended to look for SymPP with `find_package` before including it as a subdirectory. Otherwise, we can get [ODR errors](https://en.wikipedia.org/wiki/One_Definition_Rule) in larger projects.
#### CMake with Automatic Download
Check if you have [Cmake](http://cmake.org) 3.14+ installed:
```bash
cmake -version
```Install [CPM.cmake](https://github.com/TheLartians/CPM.cmake) and then:
```cmake
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:
```cpp
#include
```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](https://en.wikipedia.org/wiki/One_Definition_Rule) in larger projects.
### Other build systems
If you want to use it in another build system you can either install the library (Section [*Installing*](#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`](sources) directory, and 2) link the dependencies described in [`sources/CMakeLists.txt`](sources/CMakeLists.txt).
Then add this header to your source files:
```cpp
#include
```## Limitations and Roadmap
Things SymPP needs to improve:
* Lots of tests
* Merge redundant `print` and `c_code` functions
* More printing formats (inline, code, latex)
* Smarter simplification functionsThings SymPP doesn't do yet:
* Serialization
* Interval arithmetic
* Black-box function lambdas
* Calculus
* Variable integration graphs (VIG)
* Conditional VIGs
* OpenCL
* Matrices## Contributing
There are many ways in which you can contribute to this library:
* Testing the library in new environments
* Contributing with interesting examples
* Developing new node types
* Finding bugs in general
* Whatever idea seems interesting to youIf contributing with code, please turn the pedantic mode ON (`-DBUILD_WITH_PEDANTIC_WARNINGS=ON`), don't forget cppcheck and clang-format.
Example: CLion

### Contributors
## Thanks
We would like to thank the developers of these libraries:
- [SymPy](https://www.sympy.org/): we often use SymPy as a reference for our interface
- [SymbolicC++](http://symboliccpp.sourceforge.net): we used SymbolicC++ as a reference for our polymorphic design
- [TinyCC](https://github.com/TinyCC/tinycc): we use TinyCC to compile expressions to machine code