The SimianQuant library is organized using a strict hierarchy of abstractions. This is useful for both internal development and external customization. The hierarchy is designed to capture:

- The natural ordering of the concepts used by the library
- The decoupling of the dependencies between the concepts and their implementations
- The natural extensibility and customizability of each facet of the library
- The design principles that ensure a good end-user experience

Each layer is built transparently using concepts defined in the previous layers.

# Core

The core module defines the top-level abstractions of the library and the laws that determine how and when they may be combined. This is the most conceptual part of the library and the end-users will almost never have to directly interact with it. It defines four ‘interfaces’ that encapsulate the SimianQuant processing pipeline, and tooling to execute the compiled expressions without any runtime overhead. The interfaces are:

**Field**: A Field constrains the algebraic properties of an expression**Simplifier**: A Simplifier implements algebraic simplification**DeAbstracter**: A DeAbstracter implements graph simplification**Materializer**: Implements programming language specific optimizations and generates code that can be fed into a standard compiler

A tuple of a mutually compatible Field, Simplifier, DeAbstracter and Materializer is called a **Context**.

# Standard Library

The standard library provides default implementations for a variety of Fields, Simplifiers, DeAbstracters and Materializers. Additionally, it provides APIs for:

- Constructing expressions using a user-friendly combinators (instead of the arity combinators provided by the core module)
- Symbolic differentiation, and invariants that guard against trivial errors
- Runtime compilation and subsequent garbage collection

All of the implementations are decoupled, and it is trivial to use a SimianQuant Simplifier with a custom DeAbstracter and a SimianQuant Materializer.

### Preconfiguration

By necessity, SimianQuant implementations are orthogonal and a large number need to be overlaid to create a context that is suitable for writing practical expressions. To simplify the development process, the standard library provides a set of objects that function as a useful default for a given context. Using these objects, going from an implementation that evaluates over Doubles in Java to one that implements algorithmic differentiation in C++ is as easy as changing a single line of code.

These preconfigured objects represent the lowest level of abstraction that users will reasonably need to use.

# Domain Specific Layers

The standard library provides implementations for algebra over elementary operations, like exponentiation and trigonometric expressions. The submodules of the domain specific layers use those to define domain specific functions. These functions can be manipulated with the same ease as elementary operations. Examples are interpolators and the financial formula repositories.

### Interplib

The interpolator library defines functions for constructing interpolators, for example linear, cubic spline, polynomial etc. Since both the abscissae and ordinates can be arbitrary expressions, these functions also succinctly define higher dimensional variants like bilinear interpolators.

### Qflib

The quantitative finance formula library provides definitions for financial models that can be expressed using closed form formulae, for example variations of Black-Scholes, Stochastic Alpha Beta Rho (SABR) and Heston.

# Application Specific Layers

Standard algebraic expressions are limited by only being able to capture acyclic computational graphs (i.e. closed form solutions). Resolving this in theory is straightforward, i.e. by augmenting the input with propogated state and modeling cyclic graphs as acyclic graphs with feedback.

Implementing this in practice can be tedious. Application Specific Layers provide abstractions that make this process seamless, while allowing the transformation function to be specified symbolically. Additionally, they also provide the creature comforts that separate a library from a framework. Examples are differential equation solvers (both ordinary and partial), tree based solvers and Monte-Carlo engines.