Hephaestus++ is a mathematical tool which has many components: FCO
, BN
and H(eph)
. It is used for high precision calculation and tensor mathematics as well as function aproximations.
Hephaestus can be built with CMake.
Requirements:
- CMake extensions (VScode)
- g++ and gcc compilers
Run without CMake:
make # or
g++ -std=c++17 -stdlib=libc++ main.cpp --include athena/*.cpp hephaestus/*.cpp
|- athena <- athena
|- hephaestus <- hephaestus
|- CMakeLists.txt <- cmake build
|- Makefile <- main makefile
|- main.cpp <- have fun!
- Paralelize (if possible) tensorial operations and CORDIC implementations. hephaestus/HTensor.h
- Rewrite foreach function and create Itreable interface
- Add large ranging functions for CORDIC
- Athena and HTensor separate lib: athena
- Make HTensors better and Paralelize it
- Get started on Heph lang (maybe)
Big Numbers includes big real numbers
, big ints
and big binary ints
and works head to toe with the big:: namespace which contains all the trig, inverse trig and hyperbolic functions, but also a quick exponential and others. Some of the basic functions (floor, abs, to_decimal, to_binary etc) will be found in the big:: namespace in the big.cpp file.
In a future update, they will all be included in the same namespace!
UPDATE: 21 DEC merged big and big_cordic
Using the BNdecimal (aka bigreal) type:
#include "hephaestus.cpp"
// ...
bigreal a("3.14"), b("2.33");
bigreal sin_a = big::sin(a);
bigreal a_pow_b = big::pow(a, b);
bigreal ln_a = big::ln(a);
bigreal exp_a = big::exp(a);
bigreal arctan_a, hyp_a;
big::calc_arctan(a, arctan_a, hyp_a);
bigreal floor_a = big::floor(a);
bigreal ab_sum = a + b, ab_prod = a * b, ab_div = a / b;
There is also a natural number namespace (natural_num) which contains functions that take natural numbers as inputs (still using the bigreal type)
#include "hephaestus.cpp"
// ...
bigreal gcd_ab = natural_num::gcd(a, b);
bigreal a_mod_b = natural_num::mod(a, b);
bigreal a_quot_b = natural_num::divide(a, b);
There are also bigint and bigint2 aka BNint and BinaryBNint respectively.
#include "hephaestus.cpp"
// ...
// see if string is number
std::cout<< (big::is_number("123.32asa")) ;
bigint2 binary_a = big::to_binary(a);
bigreal same_a = big::to_decimal(binary_a);
It can be used to easily declare bigreal types. You need to include the Heph_Utils.h header. One can also declare BNComplex numbers (aka bigcomplex) and use the hcomp namespace for more complex-related functions. This namespace will soon receive an update.
#include "hephaestus.cpp"
#include "Heph_Utils.h"
// ...
auto a = 12.34_big;
bigcomplex z = a * I_big + 1.23_big;
The brute namespace consists of rough estimates of functions and is only for experimental purposes. It should not be used in practice, because the big namespace works much faster and has much more precision (100 digits).
The H classes are new and some of them still in beta (HSymbolic), but provide methods that work with more abstract objects.
The classes which are the most important are HTensor, HShape, HPoly, HRational, HSymbolic and MVExp. The last 2 will soon merge into one big class called HSym in a future update.
Tensors are very abstract (let's say matrix-like) objects. They are used in relativity. For now they are only implemented over the long double space, but soon there will also be a bigreal version for more exact calculations. UPDATE: bigreal support for tensors has been added Friday 4 November 2022. Please report any bugs!
Example of creation of 2 3x3 tensors (izomorph to the space of 3x3 matrices), and implementing the matrix product.
#include "hephaestus.cpp"
#include "Heph_Utils.h"
// ...
std::vector<long double> tensor1_values = {1.1, 2.0, 3.2, 5.0, 6.2, 4.2, 8.8, 5.0, 8.3};
std::vector<long double> tensor2_values = {-1.4, 1.0, 7.2, 5.7, 6.72, 4.62, 8.850, 7.7, 5.760};
HTensor<long double> tensor1(tensor1_values, MATRIX_3X3);
HTensor<long double> tensor2(tensor2_values, MATRIX_3X3);
HTensor<long double> tensorproduct = HTensor<long double>::tensor_product(tensor1, tensor2);
HEinsteinNotation<long double> einstein_notation_tensor1 = __(tensor1, "^alpha_beta");
HEinsteinNotation<long double> einstein_notation_tensor2 = __(tensor2, "^beta_gamma");
HEinsteinNotation<long double> einstein_notation_tensorprod = __m(einstein_notation_tensor1, einstein_notation_tensor2);
// (*)
You can also use the DEF_TENSOR_PRODUCT_TO_INDEXED_TENSOR macro to easily define a product between 2 tensors. It declares a lambda-function which provided 2 tensors returns an indexed tensor (using Einstein's notation).
DEF_TENSOR_PRODUCT_TO_INDEXED_TENSOR(innerprod, REAL, _x, "_alpha", _y, "^alpha", _x.dim() == 1 && _y.dim()==1);
DEF_TENSOR_PRODUCT_TO_INDEXED_TENSOR(matrixprod, REAL, _x, "^alpha_beta", _y, "^beta_gamma", _x.dim() == 2 && _y.dim()==2);
You can call them using the name preceded by DEFN_:
LET m1_mak = __(m1vals, MATRIX_3X3) DONE
LET m2_mak = __(m2vals, MATRIX_3X3) DONE
LET m1m2 = DEFN_matrixprod(m1_mak, m2_mak) DONE
[Read about the "__" macro here]
In this case Einstein notation is used and HEPHAESTUS provides an easy macro to convert from tensors to einstein notations and viceversa. It also provides an easy way to loop through array-like objects using a macro-based language included in the Heph_Utils.h header.
FOREACH(i, indices, IN_TENSOR, einstein_notation_tensorprod.tensor,
LOG einstein_notation_tensorprod.at(indices) NEAR "" DONE
)
As you saw before HEPHAESTUS++ also comes with a simplified macro-language. We will now look through the most important thigs you can do with this language.
The __ macro is used as a converter tool. It is short for _heph_predef_normalize, and can be used to get the value of a tensor at some coordinates, or the conversion from a tensor to an EinsteinNotation, to build a tensor with a shape and a values-vector or to calculate the value of a mve function.
auto einstein_notation_tensor2 = __(tensor2, "^beta_gamma");
// einstein_notation_tensor2 will be of type HEinsteinNotation<long double>
You can think of it as a kind of "join" function which takes some inputs and returns what it thinks you wanted to say.
More such oveloads will be added in a future release.
For example the ( * ) codebox is the same as
HEinsteinNotation<long double> einstein_notation_tensorprod = __m(tensor1, "^alpha_beta", tensor2, "^beta_gamma");
As the name suggest, they are polynomial classes, the last one representing Rational Polynomials.
QPOLY represents a sortcut macro for HPoly<HRational>
.
One can integrate a rational function (formed by taking the raport of two ratioal polynomials) as such:
QPOLY PF = multipleroot(5_frac, 3) * multipleroot(1_frac, 4) * multipleroot(3_frac, 1) ;
QPOLY PG = QPOLY({-3, 0, 1});
LOG QPOLY::integrate_polyfrac(PG, PF) DONE
where the _frac suffix operator returns HRational fraction with denominator 1.
integrate_polyfrac returns a string which has the full function. It might not work for polynomials with non-real solutions.
Hephaestus aims to be able to handle large data, and to be used for model training.
- Advanced solution finding algorithms for polynomials
- Advanced solution finding for simple functions
- Advanced integration
- Parralelization and grouping for tensors, as well as naming dimensions