Suggestions on syntax to express mathematical formula concisely

前端 未结 13 1117
予麋鹿
予麋鹿 2021-02-02 08:46

I am developing functional domain specific embedded language within C++ to translate formulas into working code as concisely and accurately as possible.

I posted a proto

13条回答
  •  迷失自我
    2021-02-02 09:20

    my prototype (still needs lots of work obviously, and comments)

    // #include "tensor/tensor.hpp"
    // #include "typename.hpp"
    
    #include 
    #include 
    #include 
    
    #define BOOST_FUSION_INVOKE_FUNCTION_OBJECT_MAX_ARITY PHOENIX_ARG_LIMIT
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    namespace range_ {
        namespace detail {
    
            namespace phoenix = boost::phoenix;
            namespace fusion = boost::fusion;
    
            /// undefined or implicit object
            struct undefined {};
    
            template
            struct index {
                // index(boost::phoenix::argument) {}
                typedef phoenix::actor > argument;
                argument arg() const { return argument(); }
            };
    
            template
            struct functional {
                typedef phoenix::actor > type;
                static type form(const T& t) { return type(t); }
            };
    
            template
            struct functional, U> {
                typedef phoenix::actor type;
                static type form(const T& t) { return type(t); }
            };
    
            template
            struct functional {
                typedef typename functional::type type;
                static type form(const undefined&) { return type(T()); }
            };
    
            template
            struct expression;
    
            template
            struct expression {
                typedef functional lower_function;
                typedef functional upper_function;
    
                expression(const L &lower, const U& upper, const C &cdr)
                    : lower_(lower), upper_(upper), cdr_(cdr) {}
    
                template
                expression operator()(const E &c) const {
                    return expression(lower_,  upper_, c);
                }
    
                template
                void operator[](const F &f) const {
    #define TEXT(z, n, text) text
    #define UNDEFINED_ARGUMENTS BOOST_PP_ENUM(PHOENIX_ARG_LIMIT, TEXT, undefined())
                    evaluate(f, fusion::make_vector(UNDEFINED_ARGUMENTS));
    #undef TEXT
    #undef UNDEFINED_ARGUMENTS
                }
    
                L lower_;
                U upper_;
                C cdr_;
    
                const L& left() const { return lower_; }
    
                const C& cdr() const {return cdr_; }
    
                template
                typename functional::type begin() const {
                    return functional::form(lower_);
                }
    
                template
                typename functional::type end() const {
                    return functional::form(upper_);
                }
    
                template
                void evaluate(const F &f, const A &arguments) const {
                    T i = this->begin()(arguments);
    #define AS_VECTOR(var, expr) BOOST_AUTO(var, fusion::as_vector(expr))
    #define ADVANCE_C(seq) fusion::advance_c(fusion::begin(seq))
                    AS_VECTOR(b, fusion::erase(arguments, ADVANCE_C(arguments)));
                    AS_VECTOR(a, fusion::insert_range(b, ADVANCE_C(b),
                                                      fusion::vector_tie(i)));
    #undef ADVANCE_C
    #undef AS_VECTOR
                    while (fusion::invoke_function_object(this->end(), a)) {
                        this->apply(cdr_, f, a);
                        ++i;
                    }
                }
    
                template
                void apply(const E &e, const F &f, const V &variables) const {
                    e.template evaluate(f, variables);
                }
    
                template
                void apply(const undefined&, const F &f, const V &variables) const {
                    fusion::invoke_function_object(f, fusion::as_vector(variables));
                }
    
            };
    
            template
            expression
            make_expression(const L &lower, const U& upper) {
                return expression(lower, upper, undefined());
            }
    
            template
            expression
            make_expression(const expression &expr, const U& right) {
                return expression(expr.left(), right, undefined());
            }
    
            template
            expression >
            operator,(const expression &e1,
                      const expression &e2)  {
                return e2(e1);
            }
    
    #define ARGUMENT(N) phoenix::actor >
    #define ACTOR_COMPOSITE(O,L,R)                                          \
            phoenix::actor::type>
    
    
    #define LOWER_BOUND_OPERATOR(op, eval, param)                           \
            template                                     \
            expression                                 \
            operator op (const param& left, const index &i) {            \
                return make_expression(left, undefined());               \
            }
    
    
    #define UPPER_BOUND_OPERATOR_INDEX(op, eval, param)             \
            template                             \
            expression   \
            operator op (const index &i, const param& e) {       \
                return make_expression(undefined(),              \
                                          (ARGUMENT(N)() op e));    \
            }
    
    #define UPPER_BOUND_OPERATOR_EXPRESSION(op, eval)                       \
            template                            \
            expression         \
            operator op (const expression &left,           \
                         const T& right) {                                  \
                return make_expression(left, (ARGUMENT(N)() op right));     \
            }
    
    #define UPPER_BOUND_OPERATOR(op, eval)                                  \
            UPPER_BOUND_OPERATOR_INDEX(op, eval, T)                         \
            UPPER_BOUND_OPERATOR_INDEX(op, eval, phoenix::actor)         \
            UPPER_BOUND_OPERATOR_EXPRESSION(op, eval)
    
            LOWER_BOUND_OPERATOR( < , phoenix::less_eval, T)
            LOWER_BOUND_OPERATOR( < , phoenix::less_eval, phoenix::actor)
            LOWER_BOUND_OPERATOR( <= , phoenix::less_equal_eval, T)
            LOWER_BOUND_OPERATOR( <= , phoenix::less_equal_eval, phoenix::actor)
    
            UPPER_BOUND_OPERATOR( < , phoenix::less_eval)
            UPPER_BOUND_OPERATOR( <= , phoenix::less_equal_eval)
    
        }
    
    }
    
    
    namespace index {
        using namespace boost::phoenix;
        boost::phoenix::actor > const i;
        boost::phoenix::actor > const j;
        boost::phoenix::actor > const k;
        boost::phoenix::actor > const l;
    
        template
        range_::detail::index range(const boost::phoenix::actor<
                                       boost::phoenix::argument >&) {
            return range_::detail::index();
        }
        template
        range_::detail::index range(const boost::phoenix::actor<
                                       boost::phoenix::argument >&,
                                       const F &f) {
            // return range_::detail::index();
            throw std::exception("not implemented");
        }
    
    
    
    }
    
    int main(){
    
        using namespace index;
    
        // formula domain language rough prototype
        // stuff in brackets can be any valid phoenix lambda expression
    
        // physicist notation, lower bound may be implicit
        (range(i) <= j, 3 <= range(j) < 4)[std::cout << i << " " << j << std::endl];
    
        // implicit physicist notation, not done yet
        //(range(i) < range(j) < 4)[...]
    
        // programmer notation, same as above , but order is reversed
        (3 <= range(j) < 4)(range(i) <= j)[std::cout << i << " " << j << std::endl];
    
        // ignore, some early prototype for lambda tensor
        // size_t N = 4;
        // tensor::tensor<4> T(N,N,N,N);
    
         // tensor::function > T_(T);
        // (range(j) < 4)(range(i) <= j)[std::cout << T_(i,j,0,0)];
    
        // (range(i) < j, range(j) < N)[T_(i,j,0,0) = T_(j,i,0,0)];
        // sum(j < val(N))[T_(i,j,0,0)];
    
    }
    

提交回复
热议问题