1

I'm writing a small library for quantum mechanics and I want to use expression template to form operator expressions. Especially forming the Hamiltonian with expression template.

I basically followed this source to construct the code and overloading the corresponding operators + * -: https://en.wikipedia.org/wiki/Expression_templates

Forming the expression for the Hamiltonian requires a sum

Vec x = u_1 + u_2 + ... + u_N

where N is a (const) integer and u_i are also of type Vec. Writing this expression in the code works but I would like to be able to write

Vec x = Sum_{i=0}^{N} u_i

How would one do this?

------------ EDIT ------------

After some research and with the help of the comments, I came up with an idea of static for loop... After googling I found an article in http://www.drdobbs.com/loops-metaloops-c/184401835?pgno=8 which is exactly what I needed.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199

1 Answers1

0

There is no way to write a template or function that magically pattern matches variables from the surrounding scope, so your u_i syntax can not work. You could do something similar with a macro, e.g.:

#define SUM_4(x) x ## 1 + x ## 2 + x ## 3 + x ## 4

Usage:

Vec u_1, u_2, u_3, u_4;
...
Vec x = SUM_4(u_);

You'd need to define additional macros for other numbers of source vectors.

The subscript operator in C++ is modeled by array access, e.g. u[1], u[2], .... If you are willing to maintain an array of Vec, you could write a generic function that iterates over the array. In this case the parameter would be the array. Something like:

template<typename T, int N>
T sum(T (&u)[N])
{
    // (or your preferred summation procedure)
    T x = u[0];
    for (int i=1; i < N; ++i)
        x += u[i];
    return x;
}

Usage:

Vec u[4];
...
Vec x = sum(u);

Even better use a std::vector or fixed size array template.

P.S. Consider using Eigen.

EDIT: Updated sum() template with array size deduction from http://www.cplusplus.com/articles/D4SGz8AR/

Ross Bencina
  • 3,822
  • 1
  • 19
  • 33
  • Why not let the compiler deduce N? – Marc Glisse Oct 17 '15 at 13:21
  • @MarkGlisse, because I did not know how to do that. But now I do. Fixed. – Ross Bencina Oct 17 '15 at 13:24
  • Thank you very much for your answer. I'm not totally sure to understand though. In your proposed way to sum, since the type T is Vec then the operator += should return something like VecAdd, isn't it? (see https://en.wikipedia.org/wiki/Expression_templates). Therefore it is my understanding that operations such as x += u[i]; are not possible? – user2460530 Oct 17 '15 at 13:30
  • @user2460530 I suppose that you are correct, if you want sum() to return an expression template, then you could consider defining sum() recursively. – Ross Bencina Oct 17 '15 at 13:34
  • @user2460530 If you expect only a certain number of array dimensions then you could also use specialization to define multiple versions of sum. – Ross Bencina Oct 17 '15 at 13:36
  • @Ross Bencina I don't really know how to do this, since the return type will depend on the operation done within the function sum().... Do you have any reference for this? – user2460530 Oct 17 '15 at 13:47
  • @user2460530 Just an idea, but probably you could make a recursive template struct that generated the return type as an embedded typedef, and a separate recursive function that evaluated the sum. – Ross Bencina Oct 17 '15 at 15:03