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

Design of higher order response operators #167

Open
stigrj opened this issue Dec 10, 2018 · 1 comment
Open

Design of higher order response operators #167

stigrj opened this issue Dec 10, 2018 · 1 comment

Comments

@stigrj
Copy link
Contributor

stigrj commented Dec 10, 2018

From @robertodr in #161 :

Some comments and suggestions, mostly due to the fact that I am not quite that fluent in MRChem. The D1/D2 variants are there for ground state and linear response, right? That would mean that for e.g. quadratic you'd have to add a D3 variant, isn't it? Using variadic templates might help handle the code duplication a bit:

template <typename Head, typename... Tail>
class Collection final {
   public:
     Collection(const Head & h, const Tail&... t) : collection_{h, t...} {}
    void print() const {
        for (const auto & f: collection_) {
            f.print();
        }
    }
    private:
    std::array<Head, sizeof...(Tail)+1> collection_;
};

where the type of Head and Tail should be Orbital * in your case. Based on the sizeof...(Tail)+1 (a compile-time constant) you can dispatch all the needed algorithms correctly with not too much hassle (I think!) This is a slightly more verbose solution upon instantiation: you need to give the types of all arguments up front: auto coll = Collection<A, A, A, A>(a1, a2, a3, a4); There's probably a smarter way to coerce the parameter pack to be of one single type though.

@robertodr
Copy link
Contributor

Slightly improved version of the above code snippet (so it doesn't get lost on Slack):

template <std::size_t, typename T>
using ignore_val = T;

// Unused primary template
template <size_t N, typename=std::make_index_sequence<N>> class Collection;

// Partial specialization
template <size_t N, std::size_t... indices>
class Collection<N, std::index_sequence<indices...>> final {
    public:
    inline Collection(ignore_val<indices, MyType>... args) : mytypes_{args...} {}
    
    void print() const {
      for (const auto & mt: mytypes_) {
            mt.print();
      }
    }
    
    private:
    std::array<MyType, N> mytypes_;
};

using MyTypes = Collection<3>;
  1. This only allows homogeneous collections;
  2. Not quite as verbose at instantiation.

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

2 participants