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.
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/
Related
I'd like to write a function on an array, but I'd like to have a generic type. For argument, let's make it a sum.
proc mySum(x:[] int) {
return + reduce x;
}
proc mySum(x:[] real) {
return + reduce x;
}
What is the notation for a generic type? I thought it was something like proc mySum(x: [] <T>) {} but that does not work.
The easiest way is to just leave the element type off in the formal type declaration:
proc mySum(x:[]) {
return + reduce x;
}
writeln(mySum([1, 2, 3]));
writeln(mySum([1.0, 2.0, 3.0]));
which will give you:
6
6.0
If you want to have a way of referring to the type symbolically, you can also use the following syntax to query it and bind it to an identifier (t here):
proc mySum(x:[] ?t) {
writeln("I'm computing a reduction over an array of ", t:string);
return + reduce x;
}
writeln(mySum([1, 2, 3]));
writeln(mySum([1.0, 2.0, 3.0]));
which will give you:
I'm computing a reduction over an array of int(64)
6
I'm computing a reduction over an array of real(64)
6.0
(Of course, you could also do things like declare variables of type t, etc.)
I'm relatively new to C++. I just read about the auto keyword in regards to type deduction. I've tried implementing this in a couple functions only to find that it was causing all of kinds of issues when working with math operators. I believe what was happening was that my functions started implementing integer division when I actually needed float division (variables 'i' and 'avg'). I posted the code using the auto keywords below.
Now when I explicitly declared the variables as floats, the function worked fine.
So is this an example in which using auto would not be preferred? However, I can definitely see that they would help when generating the iterators.
namespace Probability
{
/* ExpectedValueDataSet - Calculates the expected value of a data set */
template <typename T, std::size_t N>
double ExpectedValueDataSet(const std::array<T, N>& data)
{
auto i = 0;
auto avg = 0;
for(auto it = data.begin(); it != data.end(); it++)
{
i = it - data.begin() + 1;
avg = ((i-1)/i)*avg + (*it)/i;
}
std::cout << avg << " \n";
return avg;
}
};
The literal 0 is of type int.
A variable auto avg = 0; therefore has type int.
The literal 0.0 (or e.g. 3.14) has type double, which is what you want.
As a general rule, use auto for a variable declaration where
the type is explicitly specified in the initializer, or
the type is awfully verbose, like some iterator type.
But don't use it without reason. :)
If for e.g. aesthetic reasons you want to keep i as an integer, then rewrite the computation
((i-1)/i)*avg + (*it)/i
to e.g.
((i-1)*avg + *it)/i
to avoid pure integer arithmetic for (i-1)/i.
I would like to build a space-efficient modular arithmetic class. The idea is that the modulus M is an immutable attribute that gets fixed during instantiation, so if we have a large array (std::vector or another container) of values with the same M, M only needs to be stored once.
If M can be fixed at compile time, this can be done using templates:
template <typename num, num M> class Mod_template
{
private:
num V;
public:
Mod_template(num v=0)
{
if (M == 0)
V = v;
else
{
V = v % M;
if (V < 0)
V += M;
}
}
// ...
};
Mod_template<int, 5> m1(2); // 2 mod 5
However, in my application, we should be able to express M runtime. What I have looks like this:
template <typename num> class Mod
{
private:
const num M;
num V;
public:
Mod(num m, num v=0): M(abs(m))
{
if (M == 0)
V = v;
else
{
V = v % M;
if (V < 0)
V += M;
}
}
// ...
};
Mod<int> m2(5, 2); // 2 mod 5
Mod<int> m3(3); // 0 mod 3
This works, but a large vector of mod M values uses 2x the space it needs to.
I think the underlying conceptual problem is that Mod's of different moduli are syntactically of the same type even though they "should" be different types. For example, a statement like
m2 = m3;
should raise a runtime error "naturally" (in my version, it does so "manually": check is built into the copy constructor, as well as every binary operator I implement).
So, is there a way to implement some kind of dynamic typing so that the Mod object's type remembers the modulus? I'd really appreciate any idea how to solve this.
This is a recurring problem for me with various mathematical structures (e.g. storing many permutations on the same set, elements of the same group, etc.)
EDIT: as far as I understand,
templates are types parametrized by a class or literal.
what I want: a type parametrized by a const object (const num in this case, const Group& or const Group *const for groups, etc.).
Is this possible?
It will be difficult to do it in zero storage space if the class needs to know what M should be without any outside help. Likely the best you can do is store a pointer to a shared M, which may be a little better depending on how large num is. But it's not as good as free.
It will be easier to design if M is a passed-in value to all the functions that need it. Then you can do things like make a pool of objects that all share the same M (there are plenty of easy ways to design this; e.g. map<num, vector<num> >) and only store M once for the pool. The caller will need to know which pool the Mod object came from, but that's probably something it knows anyway.
It's hard to answer this question perfectly in isolation... knowing more about the calling code would definitely help you get better answers.
I'm wondering how to properly use pointers in for and while loops in C++. Usually I write using C instead of C++. The only reason I'm using the C++ std library this time is so I can use the complex number functions required by other mathematical functions in the code.
As part of the assignment we were given the following function declaration. The part that I wrote is commented within the function.
typedef std::complex<double> complex;
// Evaluates a polynomial using Horner's approach.
// Inputs:
// [coeffs, coeffs_end) - polynomial coefficients, ordered by descending power
// x - point of evaluation
// Outputs:
// p - value of polynomial at x
// dp - value of polynomial derivative at x
// ddp - value of polynomials second derivative at x
//
template<typename T>
inline void poly_val(T const* coeffs, T const* coeffs_end, T x, T & p, T & dp, T & ddp)
{
//MY CODE HERE
int i = 0;
const T *pnt = coeffs;
while(pnt != coeffs_end){
//Evaluate coefficients for descending powers
p += coeffs(i)*pow(x,((coeffs_end-1)-i));
pnt++;
i++;
}
}
The function doesn't know the length of the array, so I'm guessing the stop condition is the pointer 'coeffs_end', which points to the last value in the array 'coeffs'. Can I use a pointer in a conditional this way? (traditionally I would have fed the length of the array into the function, but we cant modify the declarations)
If I do it this way I keep get an error when compiling (which I don't get):
C2064:term foes not evaluate to a function taking 1 arguments
for the following line:
p += coeffs(i)*pow(x,((coeffs_end-1)-i));
coeffs(i) is calling convention to a function that takes an integer argument. But in your case it is an pointer. So, you need to use [] operator to access the element at it's index.
Also ((coeffs_end-1)-i) resolves to an address location. You need to dereference it to get the value at the location.
Maybe it'd be more readable to write this in a cleaner fashion:
#include <cmath>
#include <iterator>
template<typename T>
inline void poly_val(T const* coeffs, T const* coeffs_end, T x, T & p, T & dp, T & ddp)
{
const std::size_t nterms = std::distance(coeffs, coeffs_end);
for (std::size_t i = 0; i != nterms; ++i)
{
p += coeffs[i] * std::pow(x, nterms - 1 - i);
}
}
Since raw pointers can be treated as iterators, we can use std::distance to determine the size of an array bounded by a range [first, last).
Edit: Acutally it can be done even easier:
for (const T * it = coeffs; it != coeffs_end; ++it)
{
p += *it * std::pow(x, std::distance(it, coeffs_end) - 1);
}
I have:
struct DoubleVec {
std::vector<double> data;
};
DoubleVec operator+(const DoubleVec& lhs, const DoubleVec& rhs) {
DoubleVec ans(lhs.size());
for(int i = 0; i < lhs.size(); ++i) {
ans[i] = lhs[i]] + rhs[i]; // assume lhs.size() == rhs.size()
}
return ans;
}
DoubleVec someFunc(DoubleVec a, DoubleVec b, DoubleVec c, DoubleVec d) {
DoubleVec ans = a + b + c + d;
}
Now, in the above, the "a + b + c + d" will cause the creation of 3 temporary DoubleVec's -- is there a way to optimize this away with some type of template magic ... i.e. to optimize it down to something equivalent to:
DoubleVec ans(a.size());
for(int i = 0; i < ans.size(); i++) ans[i] = a[i] + b[i] + c[i] + d[i];
You can assume all DoubleVec's have the same # of elements.
The high level idea is to have do some type of templateied magic on "+", which "delays the computation" until the =, at which point it looks into itself, goes hmm ... I'm just adding thes numbers, and syntheizes a[i] + b[i] + c[i] + d[i] ... instead of all the temporaries.
Thanks!
Yep, that's exactly what expression templates (see http://www.drdobbs.com/184401627 or http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template for example) are for.
The idea is to make operator+ return some kind of proxy object which represents the expression tree to be evaluated. Then operator= is written to take such an expression tree and evaluate it all at once, avoiding the creation of temporaries, and applying any other optimizations that may be applicable.
Have a look at Boost.Proto, which is a library for writing EDSL (embedded domain specific languages) directly in C++. There is even an example showing exactly what you need.
http://codeidol.com/cpp/cpp-template-metaprogramming/Domain-Specific-Embedded-Languages/-10.5.-Blitz-and-Expression-Templates/
If we had to boil the problem solved by Blitz++ down to a single sentence, we'd say, "A naive implementation of array math is horribly inefficient for any interesting computation." To see what we mean, take the boring statement
x = a + b + c;
The problem here is that the operator+ signature above is just too greedy: It tries to evaluate a + b just as soon as it can, rather than waiting until the whole expression, including the addition of c, is available.
In the expression's parse tree, evaluation starts at the leaves and proceeds upwards to the root. What's needed here is some way of delaying evaluation until the library has all of the expression's parts: that is, until the assignment operator is executed. The stratagem taken by Blitz++ is to build a replica of the compiler's parse tree for the whole expression, allowing it to manage evaluation from the top down
This can't be any ordinary parse tree, though: Since array expressions may involve other operations like multiplication, which require their own evaluation strategies, and since expressions can be arbitrarily large and nested, a parse tree built with nodes and pointers would have to be traversed at runtime by the Blitz++ evaluation engine to discover its structure, thereby limiting performance. Furthermore, Blitz++ would have to use some kind of runtime dispatching to handle the different combinations of operation types, again limiting performance.
Instead, Blitz++ builds a compile-time parse tree out of expression templates. Here's how it works in a nutshell: Instead of returning a newly computed Array, operators just package up references to their arguments in an Expression instance, labeled with the operation:
// operation tags
struct plus; struct minus;
// expression tree node
template <class L, class OpTag, class R>
struct Expression
{
Expression(L const& l, R const& r)
: l(l), r(r) {}
float operator[](unsigned index) const;
L const& l;
R const& r;
};
// addition operator
template <class L, class R>
Expression<L,plus,R> operator+(L const& l, R const& r)
{
return Expression<L,plus,R>(l, r);
}
Notice that when we write a + b, we still have all the information needed to do the computationit's encoded in the type Expressionand the data is accessible through the expression's stored references. When we write a + b + c, we get a result of type:
Expression<Expression<Array,plus,Array>,plus,Array>