[ < ] | [ > ] | [ << ] | [ 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] | [ ? ] |