manpagez: man pages & more
info ginac
Home | html | info | man
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.4.1 Example: scalar products

Let's suppose that we need a way to handle some kind of abstract scalar product of the form ‘<x|y>’ in expressions. Objects of the scalar product class have to store their left and right operands, which can in turn be arbitrary expressions. Here is a possible way to represent such a product in a C++ struct:

 
#include <iostream>
using namespace std;

#include <ginac/ginac.h>
using namespace GiNaC;

struct sprod_s {
    ex left, right;

    sprod_s() {}
    sprod_s(ex l, ex r) : left(l), right(r) {}
};

The default constructor is required. Now, to make a GiNaC class out of this data structure, we need only one line:

 
typedef structure<sprod_s> sprod;

That's it. This line constructs an algebraic class sprod which contains objects of type sprod_s. We can now use sprod in expressions like any other GiNaC class:

 
...
    symbol a("a"), b("b");
    ex e = sprod(sprod_s(a, b));
...

Note the difference between sprod which is the algebraic class, and sprod_s which is the unadorned C++ structure containing the left and right data members. As shown above, an sprod can be constructed from an sprod_s object.

If you find the nested sprod(sprod_s()) constructor too unwieldy, you could define a little wrapper function like this:

 
inline ex make_sprod(ex left, ex right)
{
    return sprod(sprod_s(left, right));
}

The sprod_s object contained in sprod can be accessed with the GiNaC ex_to<>() function followed by the -> operator or get_struct():

 
...
    cout << ex_to<sprod>(e)->left << endl;
     // -> a
    cout << ex_to<sprod>(e).get_struct().right << endl;
     // -> b
...

You only have read access to the members of sprod_s.

The type definition of sprod is enough to write your own algorithms that deal with scalar products, for example:

 
ex swap_sprod(ex p)
{
    if (is_a<sprod>(p)) {
        const sprod_s & sp = ex_to<sprod>(p).get_struct();
        return make_sprod(sp.right, sp.left);
    } else
        return p;
}

...
    f = swap_sprod(e);
     // f is now <b|a>
...

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]
© manpagez.com 2000-2024
Individual documents may contain additional copyright information.