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

Move assignment functions to a namespace #72

Open
romeric opened this issue Apr 27, 2020 · 2 comments
Open

Move assignment functions to a namespace #72

romeric opened this issue Apr 27, 2020 · 2 comments

Comments

@romeric
Copy link
Owner

romeric commented Apr 27, 2020

No description provided.

@romeric romeric added this to the V0.6 milestone Apr 27, 2020
@romeric
Copy link
Owner Author

romeric commented Apr 27, 2020

Moving things to a namespace requires the definition of assign to be available while declaring the tensor which requires pre-including a lot of header files in Tensor.h. There is got to be a better way.

Maybe a class with specialisation would be nicer way

template<typename TLhs, typename TRhs, size_t DIM>
struct assignment<BinaryMulOp<TLhs,TRhs,DIM>> {
    assign(...,...);
};

@romeric
Copy link
Owner Author

romeric commented Apr 27, 2020

The above method does work for instance for tensor assignment

template<typename T, size_t ...Rest>
struct assignment<Tensor<T,Rest...>> {
    template<typename Derived, size_t DIM>
    static FASTOR_INLINE void assign(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
        if (dst.self().data()==src.data()) return;
        trivial_assign(dst.self(),src);
    }
    template<typename Derived, size_t DIM>
    static FASTOR_INLINE void assign_add(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
        trivial_assign_add(dst.self(),src);
    }
    template<typename Derived, size_t DIM>
    static FASTOR_INLINE void assign_sub(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
        trivial_assign_sub(dst.self(),src);
    }
    template<typename Derived, size_t DIM>
    static FASTOR_INLINE void assign_mul(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
        trivial_assign_mul(dst.self(),src);
    }
    template<typename Derived, size_t DIM>
    static FASTOR_INLINE void assign_div(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
        trivial_assign_div(dst.self(),src);
    }
};

and all unary math op assignments in a single macro

// arithmetic assignments
#define FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, ASSIGN_TYPE)\
    template<typename Derived, size_t DIM, typename OtherDerived = Derived_, size_t OtherDIM = DIM_,\
        typename std::enable_if<requires_evaluation_v<OtherDerived>,bool>::type = false>\
    static FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const Unary ##NAME ## Op<OtherDerived,OtherDIM> &src) {\
        using result_type = typename Unary ##NAME ## Op<OtherDerived,OtherDIM>::result_type;\
        const result_type tmp(src.expr().self());\
        trivial_assign ##ASSIGN_TYPE (dst.self(), sqrt(tmp));\
    }\
    template<typename Derived, size_t DIM, typename OtherDerived = Derived_, size_t OtherDIM = DIM_,\
        typename std::enable_if<!requires_evaluation_v<OtherDerived>,bool>::type = false>\
    static FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const Unary ##NAME ## Op<OtherDerived,OtherDIM> &src) {\
        trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
    }\


#define FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(OP, NAME)\
template<typename Derived_, size_t DIM_>\
struct assignment<Unary ##NAME ## Op<Derived_,DIM_>> {\
    FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME,     )\
    FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _add)\
    FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _sub)\
    FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _mul)\
    FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _div)\
};\

// FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sqrt, Sqrt)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT( ,    Add )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(-,    Sub )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(abs,  Abs )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sqrt, Sqrt)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(exp,  Exp )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(log,  Log )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sin,  Sin )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(cos,  Cos )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(tan,  Tan )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(asin, Asin)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(acos, Acos)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(atan, Atan)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sinh, Sinh)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(cosh, Cosh)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(tanh, Tanh)

without changing headers like the namespace solution. The tensor constructor would then just call

    template<typename Derived, size_t DIMS>
    FASTOR_INLINE Tensor(const AbstractTensor<Derived,DIMS>& src) {
        FASTOR_ASSERT(src.self().size()==size(), "TENSOR SIZE MISMATCH");
        assignment<Derived>::assign(*this, src.self());
    }

However, this seems like a lot work for encapsulation plus two separate types need to be provided one for the struct assignment itself like assignment<Derived>::assign<DerivedAssignTo,DerivedAssignFrom> where is with free functions Derived and DerivedAssignFrom are the same.

Removing milestone from this for now

@romeric romeric removed this from the V0.6 milestone Apr 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant