[GAP Forum] New (in development) package : gapcpp
Christopher Jefferson
caj21 at st-andrews.ac.uk
Wed Apr 1 12:20:53 BST 2015
Ever wish you could just write C and C++ code in GAP? Well now you can,
with the gapcpp package from: https://github.com/ChrisJefferson/gapcpp
After running './configure' in the packages directory and loading it, you
will find one method, 'CompileMethod', which accepts C++ (or C) code, the
name of your function and it's number of arguments. The function is then
automatically linked into GAP, and GAP types turned into C++ types (and
vice versa).
Here's an easy example:
gap> fun := CompileMethod("int f(int X) { return X; }", "f", 1);;
gap> fun(3);
3
That's fairly boring however. Let's consider something more interesting!
Perhaps we want to sort a list of integers by their last digit:
gap> SortBy([1..1000000], x -> x mod 10);;
gap> time;
548
Hmm.. Lets give that 'mod' function some C++ power!
gap> m := CompileMethod("int f(int X) { return X % 10; }", "f", 1);;
gap> SortBy([1..1000000], m);;
gap> time
487
Hmm, a little speedup, but not as much as we would like. Let's push the
whole thing into C++, using new 'triple quotes' to make the code easier
to write (in the master branch of GAP, not package specific!)
gap> x := CompileMethod("""
bool comp(int i, int j)
{ return i%10 < j%10; }
std::vector<int> sb(std::vector<int> i)
{ std::sort(i.begin(), i.end(),comp); return i; }""", "sb", 1);
gap> x([1..1000000]);;
gap> time;
48
Wow, 10x speedup!
Of course, C++ lets us do new things. Perhaps we really wish we had a
stable sort? No problem!
gap> x := CompileMethod("""
bool comp(int i, int j)
{ return i%10 < j%10; }
std::vector<int> sb(std::vector<int> i)
{ std::stable_sort(i.begin(), i.end(),comp); return i; }""", "sb", 1);
gap> x([1..1000000]);;
gap> time;
124
A little slower, but with the bonus of being stable!
Let's try some more things:
gap> PartialSums([1..50000]);;
gap> time;
26021
gap> x := CompileMethod("""
#include <numeric>
std::vector<int> sums(std::vector<int> v)
{
std::vector<int> out(v.size());
// r means 'reverse', we do this to agree with GAP's order
std::partial_sum(v.rbegin(), v.rend(), out.rbegin());
return out;
}""", "sums", 1);;
gap> PartialSums([1..50000]);;
gap> time;
1
The following C++ types are currently supported (recursively). More types
can be added on request!
std::vector
std::list
std::deque
std::pair
std::string
int
Bool
vec1 (a custom vector type which is 1-indexed, for each GAP<->C++
integration)
optional (a way of marking missing values, so std::vector<optional<int> >
supports lists with missing values, unlike std::vector<int>)
If you understand GAP, You can also use Obj and all the normal GAP method
to access objects. There is also initial support for gap records (see the
tests for examples).
I am interested in any requests for improvements, or usage of this package
(or wished usages of this package).
Chris
More information about the Forum
mailing list