File:  [CENS] / python / pyGiNaC / test4 / test_archive_node.cpp
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Sat Aug 18 19:10:17 2001 UTC (16 years, 3 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
Impl. add,mul,power

#include <strstream>
#include <stdexcept>

#include <ginac/ginac.h>
#include <cln/output.h>
#include <cln/integer_io.h>
#include <cln/integer_ring.h>
#include <cln/rational_io.h>
#include <cln/rational_ring.h>
#include <cln/lfloat_class.h>
#include <cln/lfloat_io.h>
#include <cln/real_io.h>
#include <cln/real_ring.h>
#include <cln/complex_io.h>
#include <cln/complex_ring.h>
#include <cln/numtheory.h>

using namespace GiNaC;
using namespace std;

void numeric::archive(archive_node &n) const
{
  inherited::archive(n);
  
  std::ostrstream s;
  
  if (this->is_crational())
    s << cln::the<cln::cl_N>(value);
  else {
    // Non-rational numbers are written in an integer-decoded format
    // to preserve the precision
    if (this->is_real()) {
      cln::cl_idecoded_float re = cln::integer_decode_float(cln::the<cln::cl_F>(value));
      s << "R";
      s << re.sign << " " << re.mantissa << " " << re.exponent;
    } else {
      cln::cl_idecoded_float re = cln::integer_decode_float(cln::the<
							    cln::cl_F>(cln::realpart(cln::the<cln::cl_N>(value))));
      cln::cl_idecoded_float im = cln::integer_decode_float(cln::the<
							    cln::cl_F>(cln::imagpart(cln::the<cln::cl_N>(value))));
      s << "C";
      s << re.sign << " " << re.mantissa << " " << re.exponent << " ";
      s << im.sign << " " << im.mantissa << " " << im.exponent;
    }
  }
  n.add_string("number", s.str());
}


void archive_node::add_bool(const std::string &name, bool value)
{

  props.push_back(property(a.atomize(name), PTYPE_BOOL, value));
}


bool archive_node::find_string(const std::string &name, std::string &ret, unsigned index) const
 {

   archive_atom name_atom = a.atomize(name);
     std::vector<property>::const_iterator i = props.begin(), iend = props.end();
     unsigned found_index = 0;
     while (i != iend) {
         if (i->type == PTYPE_STRING && i->name == name_atom) {
             if (found_index == index) {
                 ret = a.unatomize(i->value);
                 return true;
             }
             found_index++;
         }
         i++;
     }
     return false;
 }

void archive_node::add_unsigned(const std::string &name, unsigned value)
 {

   props.push_back(property(a.atomize(name), PTYPE_UNSIGNED, value));
 }


void archive_node::add_ex(const std::string &name, const ex &value)
 {
   // Recursively create an archive_node and add its ID to the properties of this node

     archive_node_id id = a.add_node(archive_node(a, value));
     props.push_back(property(a.atomize(name), PTYPE_NODE, id));
 }
void archive_node::add_string(const std::string &name, const std::string &value)
{
  cout << "value=" << value << endl;
  props.push_back(property(a.atomize(name), PTYPE_STRING, a.atomize(value)));
}
 

void archive::archive_ex(const ex &e, const char *name)
{
  // Create root node (which recursively archives the whole expression tree)
  // and add it to the archive
  archive_node_id id = add_node(archive_node(*this, e));

  // Add root node ID to list of archived expressions
  archived_ex ae = archived_ex(atomize(name), id);
  exprs.push_back(ae);
}

archive_atom archive::atomize(const std::string &s) const
{
  // Search for string in atoms vector
  std::vector<std::string>::const_iterator i = atoms.begin(), iend = atoms.end();
  archive_atom id = 0;
  while (i != iend) {
    if (*i == s)
      return id;
    i++; id++;
  }
  // Not found, add to atoms vector
  atoms.push_back(s);
  return id;
}
 

const std::string &archive::unatomize(archive_atom id) const
{
  if (id >= atoms.size())
    throw (std::range_error("archive::unatomizee(): atom ID out of range"));

  return atoms[id];
}


int main(void)
{
    ex e = pow(200, 500);
    archive ar(e, "e");

    const archive_node &n = ar.get_top_node(0);
    //n.printraw(cout);
    //cout << endl;

    string x;
    n.find_string("number", x);
    cout << x << endl;
    cout << "length=" << x.length() << " (should be 1152)" << endl;

    return 0;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>