Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with Eigen #69

Open
evanwporter opened this issue Oct 1, 2024 · 1 comment
Open

Integration with Eigen #69

evanwporter opened this issue Oct 1, 2024 · 1 comment

Comments

@evanwporter
Copy link
Contributor

Eigen is a very popular library for linear algebra with the C++ ecosystem. Especially for users working with larger financial datasets (ie: stock prices), it would be useful to have a method for using the decimal datatype within Eigen matrices.

Eigen allows the user to define custom scalars, see here, and so if this a feature that is desired then it could be implemented as follows:

#ifdef EIGEN_DECIMAL

#include <Eigen/Core>

namespace Eigen {
    template<int Precision>
    struct NumTraits<dec::decimal<Precision>> : GenericNumTraits<dec::decimal<Precision>> {
        typedef dec::decimal<Precision> Real;
        typedef dec::decimal<Precision> NonInteger;
        typedef dec::decimal<Precision> Nested;

        static inline Real epsilon() {
            // Return a small value that represents the precision limit of the decimal type
            return dec::decimal<Precision>(0.0001); // Adjust this value according to your needs
        }

        static inline Real dummy_precision() {
            // Provide a dummy precision, typically a small value
            return dec::decimal<Precision>(0.0001); // Adjust this value according to your needs
        }

        static inline int digits10() {
            // Returns the number of base-10 digits that can be represented without loss of precision
            return Precision;
        }

        enum {
            IsInteger = 0,
            IsSigned = 1,
            IsComplex = 0,
            RequireInitialization = 1,
            ReadCost = 1,
            AddCost = 1,
            MulCost = 1
        };
    };

    namespace internal {
        // Scalar addition
        template<int Precision>
        struct scalar_sum_op<dec::decimal<Precision>, dec::decimal<Precision>> {
            EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
            typedef dec::decimal<Precision> result_type;
            EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
            result_type operator()(const dec::decimal<Precision>& a, const dec::decimal<Precision>& b) const {
                return a + b;
            }
        };

        // Scalar multiplication
        template<int Precision>
        struct scalar_product_op<dec::decimal<Precision>, dec::decimal<Precision>> {
            EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
            typedef dec::decimal<Precision> result_type;
            EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
            result_type operator()(const dec::decimal<Precision>& a, const dec::decimal<Precision>& b) const {
                return a * b;
            }
        };

        // Scalar quotient
        template<int Precision>
        struct scalar_quotient_op<dec::decimal<Precision>, dec::decimal<Precision>> {
            EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
            typedef dec::decimal<Precision> result_type;
            EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
            result_type operator()(const dec::decimal<Precision>& a, const dec::decimal<Precision>& b) const {
                return a / b;
            }
        };

        // Scalar min
        template<int Precision>
        struct scalar_min_op<dec::decimal<Precision>, dec::decimal<Precision>> {
            EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
            typedef dec::decimal<Precision> result_type;
            EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
            result_type operator()(const dec::decimal<Precision>& a, const dec::decimal<Precision>& b) const {
                return std::min(a, b);
            }
        };

        // Scalar max
        template<int Precision>
        struct scalar_max_op<dec::decimal<Precision>, dec::decimal<Precision>> {
            EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
            typedef dec::decimal<Precision> result_type;
            EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
            result_type operator()(const dec::decimal<Precision>& a, const dec::decimal<Precision>& b) const {
                return std::max(a, b);
            }
        };
    }
}

#endif

More thought will have to be put into how to best implement this and this would obviously increase the complexity of the overall project. Given this I think the best option here is leave this issue as it is now, keeping it as a reference for other users in the future trying to implement this library into Eigen

@vpiotr
Copy link
Owner

vpiotr commented Oct 1, 2024

It's not an issue and even not a potential feature for decimal library - clearly this code is independent part which can be distributed alone. Please create a gist or github repo for this and link here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants