GithubHelp home page GithubHelp logo

chaotic-society / theoretica Goto Github PK

View Code? Open in Web Editor NEW
17.0 3.0 3.0 7.67 MB

A numerical and automatic mathematical library in C++ for scientific and graphical applications.

Home Page: https://chaotic-society.github.io/theoretica/

License: GNU Lesser General Public License v3.0

C++ 99.16% Makefile 0.84%
linear-algebra math-library mathematics cpp math statistics header-only complex-numbers quaternion automatic-differentiation approximation numerical-methods maths matrix

theoretica's Introduction

Theoretica

GitHub last commit GitHub Workflow Status Codacy Badge License

A numerical and automatic math library for scientific research and graphical applications

Theoretica is a header-only mathematical library which provides algorithms for systems simulation, statistical analysis of lab data and numerical approximation, using a functional oriented paradigm to mimic mathematical notation and formulas. The aim of the library is to provide simple access to powerful algorithms while keeping an elegant and transparent interface, enabling the user to focus on the problem at hand.

A short example

Given a Hamiltonian function H(q, p) and a function f(q, p) defined on its phase space, you can compute its exact time derivative at a position eta = (q, p) like this: $$\frac{df}{dt} = \nabla f(\vec \eta) \cdot J \cdot \nabla H(\vec \eta)$$

Where J is the symplectic matrix. The equation can be translated into code as:

mat<N, N> J = mat<N, N>::symplectic();
real df_dt = gradient(f, eta) * J * gradient(H, eta);

The library includes real and complex analysis functions optimized for the x86 architecture, linear algebra, quaternions, roots and extrema search, numerical approximation of derivatives, integrals and differential equations, as well as more advanced features like dual numbers for automatic differentiation, statistical functions including distribution sampling, pseudorandom and quasirandom number generation for Monte Carlo methods and simulations.

Table of Contents


Key Features

This is an overview of the library's functionalities. For a more detailed list see FEATURES.md

  • Real and complex analysis
  • Linear algebra with common vector and matrix operations
  • Complex numbers in algebraic and exponential form
  • Quaternions
  • Dual numbers, Multivariable Automatic Differentiation and Differential Operators
  • Pseudorandom and Quasirandom number generation (LCG, Xoshiro256++, Splitmix64, Wyrand, Weyl)
  • Statistical functions, including Least Squares Linearization
  • Random distribution sampling and Monte Carlo
  • Approximation of roots, extrema, derivatives and integrals of real functions
  • Numerical integration of Ordinary Differential Equations (Euler, Heun, RK4, K38, multistep)
  • Polynomial interpolation with Chebyshev nodes, Bezier curves and spline interpolation

Dependencies

The library has no dependencies. Only the C++ Standard Library with C++11 capabilities is needed to use it. You can include it in your project straight away!

Setup

You don't need anything other than your compiler to use the library. You can run make all in the root directory of the library to make sure it works. Define THEORETICA_INCLUDE_BASE if you intend to use only basic functionalities (linear algebra, real functions, complex numbers), as by default theoretica.h includes all headers. All library functions and objects are implemented in the theoretica namespace (th is a shorter namespace alias).

Documentation

The documentation for the library is available here. Introductory examples can be found in EXAMPLES.md and more advanced examples can be found inside the examples/ folder. The bibliography used for researching the algorithms used in the library is available here.

Quickstart

You can try to compile this simple code to check if you set up the library correctly:

#include "theoretica.h"
using namespace th;

int main() {
 
    vec3 v = {1, 2, 3};
    mat3 A = mat3::identity();
    vec3 w = A * v;
 
    return 0;
}

Other examples

Contributing

Contributions are welcome and very appreciated! Make sure to read the Contributing Guide to know more about how you can help. If you participate, you are expected to follow the Code of Conduct.

Testing

Test on Linux Test on Windows Test on MacOS

The library uses the custom built Chebyshev testing framework to estimate the precision of functions and test their performance. Tests are automatically run on Windows, Linux and MacOS on every commit to ensure stability. Test units are placed inside the test folder while benchmarks are placed inside the benchmark folder.

Branches

main

Where the current stable version of the library is developed.

physics

The physics module implementing quantum mechanics features.

sparse

Sparse matrix and vector algebra classes.

machine-learning

Machine learning development branch, with cost functions, models and training algorithms.

Other information

License

This project is currently under the GNU Lesser General Public License 3.0.

Macros

These are common macros that can be defined to change the library's behaviour:

Macro Description
THEORETICA_INCLUDE_BASE Including theoretica.h will only include base headers
THEORETICA_THROW_EXCEPTIONS Exceptions will be thrown and errno set on error (by default errno is set and NaN is returned)
THEORETICA_ONLY_EXCEPTIONS Exceptions will be thrown on error (without modifying errno)
THEORETICA_X86 Assembly x86 implementations will be used whenever possible (automatically defined on most compilers by the library)
THEORETICA_FLOAT_PREC Floating point precision (float) will be used for the real type (by default double is used)
THEORETICA_LONG_DOUBLE_PREC Long double precision (long double) will be used
THEORETICA_ROW_FIRST The mat<N, K> class will use row-first storage of matrix data instead of column-first.

See src/core/constants.h for more specific macros.

Error handling

The library uses errno and th::math_exception (if enabled) to report errors. The behaviour of the library may be modified using the THEORETICA_THROW_EXCEPTIONS and THEORETICA_ONLY_EXCEPTIONS. See Macros to learn more.

theoretica's People

Contributors

3mln avatar annalettieri avatar mattiaisgro avatar sophielabs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

theoretica's Issues

Add and improve extrema and root search of multivariate functions

Add new algorithms and improve the existing ones for roots and extrema search for multivariate functions:

Root finding:

  • Multivariate Newton's method
  • Complex Newton's method
  • Broyden's method
  • Secant method

Extrema search:

  • Gradient descent
  • Line search gradient descent
  • BFGS
  • Conjugate gradient method
  • Trust region

Error checking support

Add two different methods for error checking:

  • Exceptions
  • Flag checking
  • Add error checking to existing functions

Project Roadmap

Short term

  • Find good approximations for ln() or log2() (#33)
  • Find good approximations for sin(), cos() and tan() (#26)
  • Improve the approximation of atan() (#18)
  • Write test cases for most functions

Medium term

  • Move towards a mixed functional and object-oriented paradigm to mimic mathematical notation
  • Make matrix and vector code independent of allocation strategy (static or dynamic) (#42)
  • PDE integration methods
  • Markov Chain Monte Carlo methods (Metropolis-Hastings)

Long term

  • Arbitrary precision types for integer and real numbers, with arbitrary precision functions
  • Lazy evaluation of matrix operations
  • Vectorized operations taking advantage of SSE/AVX (#2)

Improve architecture-independent implementation of tan()

Implement an architecture independent implementation of tan() with less then 10^-8 maximum error. CORDIC or polynomial interpolation may be used. An architecture dependent implementation for x86 machines is already present.

Consider implementing lazy evaluation of matrix operations

"Lazy evaluation" refers to the delayed evaluation of certain expressions through the usage of dedicated structures with corresponding operators. This concept may be used to delay and control evaluation of matrix expressions and enable notations of the type:

A.col(1) = B.row(2) + B.row(3);

Multivariable dual numbers

Evaluation of multivariate dual functions could be optimized by implementing multivariable dual numbers.

Implement the Metropolis-Hastings algorithm for random number generation

Implement the Metropolis-Hastings algorithm (Markov Chain Monte Carlo) to generate a random sample from a given probability density function.

  • The implementation may be written in a new metropolis.h file, placed inside the pseudorandom directory.
  • Gibbs sampling may also be implemented

Resources:
https://blog.demofox.org/2019/05/25/generating-random-numbers-from-a-specific-distribution-with-the-metropolis-algorithm-mcmc/

https://en.m.wikipedia.org/wiki/Metropolis%E2%80%93Hastings_algorithm

Make matrix code row/column precedence independent

Make it optional whether to use row or column-first matrices using the at() and get() methods and a macro constant.

Matrices can be stored column-first or row-first, and can be accessed through lexicographical or colexicographical notation:
Aij can either refer to the element on the i-th row and j-th column or the element on the i-th column and j-th row, depending on the convention.

By using 4 macro definitions and an additional method in mat, the library may become independent on the choices of storage and notation.

  • Macros UROBORO_COLUMN_FIRST and UROBORO_ROW_FIRST may be defined to decide which storage convention to use (column-first by default for OpenGL usage)
  • Macros UROBORO_MATRIX_LEXIC and UROBORO_MATRIX_COLEXIC may be defined to decide which notation convention to use (row-column or column-row in matrix access with at, get and set
  • A choice independent method iat may be defined for internal usage. This method will always use row-column notation and check for the storage convention and access matrix data accordingly.
  • The at, get and set methods will be implemented on top of iat

Write test cases

Write test cases for all major blocks of the library using the Chebyshev testing framework. Example code can be found in test_template.cpp. The functionalities which need test cases are:

  • core
  • algebra (more tests for transformations may be needed)
  • autodiff
  • polynomial
  • calculus
  • complex
  • interpolation
  • optimization
  • pseudorandom
  • statistics

Benchmarks for performance critical code are also needed.

Spline interpolation

Implement spline interpolation algorithms:

  • Natural Cubic Splines
  • B-splines
  • Quadratic Splines

Dynamic allocation of variable-size objects

Variable-size objects like matrices and vectors should have a dynamically allocated version for use in interactive and symbolic computations. To reduce code duplication, the following methods might be used:

  • Inheritance: A generic matrix class implements all functions and static and dynamic versions of it inherit and implement different allocation functions.
  • Templated generic functions (functional programming style): All functions on matrices and vectors get implemented with a template on the variable type and specific (differentiated) classes call those functions.

Inspect Xoshiro256++ code for potential errors

The Xoshiro256++ PRNG generator gives unexpected results when used to generate random real numbers, as it gives twice the number of values to the right of the mean of the interval and is thus unreliable for distribution sampling.

Generic Bezier curves

The library currently supports quadratic and cubic Bezier curves. A generic implementation may be added in interpolation/spline_interp.h

Improve the precision of atan and atan2

The atan(real) and atan2(real, real) functions need an implementation with a maximum error at least smaller than 10^-8. CORDIC and polynomials interpolation may be used.

Determinant of a generic matrix

Implement the computation of the determinant of a generic matrix. Code for 2x2 and 3x3 already exists.
The code should be implemented in the mat::det() method.

Suggested algorithms:

  • Gauss elimination to get a triangular matrix
  • Laplace
  • LU decomposition

Improve the precision of exp and powf

The exp(real) and powf(real) functions currently lack an architecture independent implementation with a maximum error lower than 10^-8. An x86 implementation is already implemented.

Floating Point Stack Overflow on MSVC

The current approach to inlined assembly is causing a stack overflow on the floating point registers.

For example

inline real sqrt(real x) {
#ifdef MSVC_ASM
__asm {
    fld x
    fsqrt
    fst x
}
#endif
return x;

compiles down to

fld         qword ptr [x]  
fsqrt  
fst         qword ptr [x]  
fld         qword ptr [x]  
//function outro

Note the injected fld (push) at the end. This unbalances the pushes and pops, which causes a stack overflow and garbage on the stack.

This can be resolved by either changing fst x to fstp x, or by omitting the return statement, which MSVC implicitly adds anyway. That is, the following code works without any warning:

inline real sqrt(real x) {
#ifdef MSVC_ASM
__asm {
    fld x
    fsqrt
}
#endif

and generates the following assembly

fld         qword ptr [x]  
fsqrt  
//function outro - exactly as above

This works for all the affected functions, as they all work on register ST0 which is also used for returning.

I'm submitting a PR to implement this latter approach.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.