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

5.15.4 Archiving

GiNaC allows creating archives of expressions which can be stored to or retrieved from files. To create an archive, you declare an object of class archive and archive expressions in it, giving each expression a unique name:

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

int main()
{
    symbol x("x"), y("y"), z("z");

    ex foo = sin(x + 2*y) + 3*z + 41;
    ex bar = foo + 1;

    archive a;
    a.archive_ex(foo, "foo");
    a.archive_ex(bar, "the second one");
    // ...

The archive can then be written to a file:

 
    // ...
    ofstream out("foobar.gar");
    out << a;
    out.close();
    // ...

The file ‘foobar.gar’ contains all information that is needed to reconstruct the expressions foo and bar.

The tool viewgar that comes with GiNaC can be used to view the contents of GiNaC archive files:

 
$ viewgar foobar.gar
foo = 41+sin(x+2*y)+3*z
the second one = 42+sin(x+2*y)+3*z

The point of writing archive files is of course that they can later be read in again:

 
    // ...
    archive a2;
    ifstream in("foobar.gar");
    in >> a2;
    // ...

And the stored expressions can be retrieved by their name:

 
    // ...
    lst syms;
    syms = x, y;

    ex ex1 = a2.unarchive_ex(syms, "foo");
    ex ex2 = a2.unarchive_ex(syms, "the second one");

    cout << ex1 << endl;              // prints "41+sin(x+2*y)+3*z"
    cout << ex2 << endl;              // prints "42+sin(x+2*y)+3*z"
    cout << ex1.subs(x == 2) << endl; // prints "41+sin(2+2*y)+3*z"
}

Note that you have to supply a list of the symbols which are to be inserted in the expressions. Symbols in archives are stored by their name only and if you don't specify which symbols you have, unarchiving the expression will create new symbols with that name. E.g. if you hadn't included x in the syms list above, the ex1.subs(x == 2) statement would have had no effect because the x in ex1 would have been a different symbol than the x which was defined at the beginning of the program, although both would appear as ‘x’ when printed.

You can also use the information stored in an archive object to output expressions in a format suitable for exact reconstruction. The archive and archive_node classes have a couple of member functions that let you access the stored properties:

 
static void my_print2(const archive_node & n)
{
    string class_name;
    n.find_string("class", class_name);
    cout << class_name << "(";

    archive_node::propinfovector p;
    n.get_properties(p);

    size_t num = p.size();
    for (size_t i=0; i<num; i++) {
        const string &name = p[i].name;
        if (name == "class")
            continue;
        cout << name << "=";

        unsigned count = p[i].count;
        if (count > 1)
            cout << "{";

        for (unsigned j=0; j<count; j++) {
            switch (p[i].type) {
                case archive_node::PTYPE_BOOL: {
                    bool x;
                    n.find_bool(name, x, j);
                    cout << (x ? "true" : "false");
                    break;
                }
                case archive_node::PTYPE_UNSIGNED: {
                    unsigned x;
                    n.find_unsigned(name, x, j);
                    cout << x;
                    break;
                }
                case archive_node::PTYPE_STRING: {
                    string x;
                    n.find_string(name, x, j);
                    cout << '\"' << x << '\"';
                    break;
                }
                case archive_node::PTYPE_NODE: {
                    const archive_node &x = n.find_ex_node(name, j);
                    my_print2(x);
                    break;
                }
            }

            if (j != count-1)
                cout << ",";
        }

        if (count > 1)
            cout << "}";

        if (i != num-1)
            cout << ",";
    }

    cout << ")";
}

int main()
{
    ex e = pow(2, x) - y;
    archive ar(e, "e");
    my_print2(ar.get_top_node(0)); cout << endl;
    return 0;
}

This will produce:

 
add(rest={power(basis=numeric(number="2"),exponent=symbol(name="x")),
symbol(name="y")},coeff={numeric(number="1"),numeric(number="-1")},
overall_coeff=numeric(number="0"))

Be warned, however, that the set of properties and their meaning for each class may change between GiNaC versions.


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