File:  [CENS] / python / pyGiNaC / wrappers3 / lst_py.cpp
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Wed May 16 05:49:32 2001 UTC (16 years, 6 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
Added some get_*() methods. Introduced function().

/*
# This file is part of the PyGiNaC package.
# http://cens.ioc.ee/projects/pyginac/
#
# $Revision: 1.5 $
# $Id: lst_py.cpp,v 1.5 2001-05-16 05:49:32 pearu Exp $
#
# Copyright 2001 Pearu Peterson all rights reserved,
# Pearu Peterson <pearu@cens.ioc.ee>
# Permission to use, modify, and distribute this software is given under the
# terms of the LGPL.  See http://www.fsf.org
#
# NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
#
*/
/*DT
  Lst
  ------

  Create GiNaC list from Python objects:
  >>> from ginac import lst,is_lst, numeric
  >>> lst()
  lst([])
  >>> lst([])
  lst([])
  >>> lst(2)
  lst([numeric('2')])
  >>> lst([2,[]])
  lst([numeric('2'), lst([])])
  >>> lst(lst([2,3]))
  lst([numeric('2'), numeric('3')])

  Check if object is lst:
  >>> is_lst(lst()), is_lst([])
  (1, 0)
  >>> lst().is_lst(), numeric().is_lst()
  (1, 0)

  Slicing:
  >>> a = lst(range(6))
  >>> print a[1]
  1
  >>> print a[1:4]
  [1, 2, 3]
  >>> print a[5:1:-1]
  [5, 4, 3, 2]

  Modifying in-place:
  >>> a[1] = 11
  >>> a[3:] = [33,44,55]
  >>> print a
  [0, 11, 2, 33, 44, 55]

*/


#ifdef PYGINAC_DEFS
this_module.def(&lst_0, "lst");
this_module.def(&lst_1, "lst");
this_module.def(&ex::is_lst, "is_lst");
this_module.def(&return_false, "is_lst");
ex_class.def(&ex::is_lst, "is_lst");
ex_class.def(&ex::append_1, "append");
ex_class.def(&ex::prepend_1, "prepend");
ex_class.def(&ex::index_1, "index");

#else
#ifdef PYGINAC_EX_PROTOS
#define PYGINAC_PROTOS
#endif
#ifdef PYGINAC_PROTOS
#ifdef PYGINAC_EX_PROTOS
bool is_lst(void) const;
void append_1(py::ref obj);
void prepend_1(py::ref obj);
long index_1(py::ref obj) const;
#else // PYGINAC_EX_PROTOS
#include "slice.h"
GiNaC::ex lst_0(void);
GiNaC::ex lst_1(const GiNaC::lst & l);
PyObject* basic_getitem(const GiNaC::basic & m, py::ref index);
void basic_setitem(GiNaC::basic & m, py::ref index, py::ref other);
void lst_delitem(GiNaC::lst & m, py::ref index);
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
GiNaC::lst from_python (PyObject* o, py::type<const GiNaC::lst &>);
GiNaC::lst & from_python (PyObject* o, py::type<GiNaC::lst &>);
BOOST_PYTHON_END_CONVERSION_NAMESPACE
#endif // !PYGINAC_EX_PROTOS
#else  // PYGINAC_PROTOS
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
GiNaC::lst from_python (PyObject* o, py::type<const GiNaC::lst &>) {
  if (ExInstance_Check(o)) {
    GiNaC::ex & e = from_python(o, py::type<GiNaC::ex &>());
    if (is_ex_exactly_of_type(e, lst))
      return ex_to_lst(e);
    return GiNaC::lst(e);
  }
  return GiNaC::lst(BOOST_PYTHON_CONVERSION::from_python(o, py::type<const GiNaC::exlist &>()));
}
GiNaC::lst & from_python (PyObject* o, py::type<GiNaC::lst &>) {
  if (ExInstance_Check(o)) {
    GiNaC::ex e = from_python(o, py::type<GiNaC::ex &>());
    if (is_ex_exactly_of_type(e, lst))
      return (GiNaC::lst &)*e.bp;
  }
  PYGINAC_FROMPYTHON_TYPEERROR(&lst,ex(lst));
}
BOOST_PYTHON_END_CONVERSION_NAMESPACE

/*F_DT is_lst(obj)
  Check if `obj' is lst.
*/
/*M_DT is_lst(self)
  Check if object is lst.
*/
bool ex::is_lst(void) const { return is_ex_exactly_of_type(*this, lst); }

/*F_DT lst(seq=[])
  Return GiNaC list of expressions.
  lst(lst(...)) -> lst(...)
 */
GiNaC::ex lst_0(void) {
  return GiNaC::lst();
}
GiNaC::ex lst_1(const GiNaC::lst & l) {
  return l;
}
PyObject* basic_getitem(const GiNaC::basic & m, py::ref index) {
  PyObject * o = index.get();
  int l = m.nops();
  int start, step_size, n_steps;
  start = parse_subindex(o, &step_size, &n_steps, l);
  if (start < 0)
    throw py::error_already_set();
  if (n_steps==PseudoIndex || n_steps==RubberIndex) {
    std::ostrstream os;
    os << "ex.getitem() PseudoIndex|RubberIndex for " << m.class_name() << std::ends;
    PyErr_SetString(PyExc_NotImplementedError, os.str());
    throw py::error_already_set();
  }
  if (n_steps==SingleIndex)
    return BOOST_PYTHON_CONVERSION::to_python(m.op(start));
  if (is_exactly_of_type(m, lst)) {
    GiNaC::lst v;
    int k = start;
    for (int i=0;i<n_steps;++i,k += step_size)
      v.append(m.op((k==l)?0:k));
    return BOOST_PYTHON_CONVERSION::to_python(v);
  }
  if (is_exactly_of_type(m, add)) {
    GiNaC::exvector &v = *new GiNaC::exvector();
    int k = start;
    for (int i=0;i<n_steps;++i,k += step_size)
      v.push_back(m.op((k==l)?0:k));
    return BOOST_PYTHON_CONVERSION::to_python(GiNaC::add(v));
  }
  if (is_exactly_of_type(m, mul)) {
    GiNaC::exvector &v = *new GiNaC::exvector();
    int k = start;
    for (int i=0;i<n_steps;++i,k += step_size)
      v.push_back(m.op((k==l)?0:k));
    return BOOST_PYTHON_CONVERSION::to_python(GiNaC::mul(v));
  }
  if (is_exactly_of_type(m, ncmul)) {
    GiNaC::exvector &v = *new GiNaC::exvector();
    int k = start;
    for (int i=0;i<n_steps;++i,k += step_size)
      v.push_back(m.op((k==l)?0:k));
    return BOOST_PYTHON_CONVERSION::to_python(GiNaC::ncmul(v, true));
  }
  std::ostrstream os;
  os << "ex.getitem() slice for " << m.class_name() << std::ends;
  PyErr_SetString(PyExc_NotImplementedError, os.str());
  throw py::error_already_set();
}

void basic_setitem(GiNaC::basic & m, py::ref index, py::ref other) {
  PyObject * o = index.get();
  PyObject * oo = other.get();
  int l = m.nops();
  int start, step_size, n_steps;
  start = parse_subindex(o, &step_size, &n_steps, l);
  if (start == -1)
    throw py::error_already_set();
  if (n_steps==PseudoIndex || n_steps==RubberIndex) {
    PyErr_SetString(PyExc_NotImplementedError, "basic_setitem() PseudoIndex|RubberIndex");
    throw py::error_already_set();
  }
  if (n_steps==SingleIndex) {
    m.let_op(start) = ex_from_ref(other);
  } else {
    if (is_exactly_of_type(m, lst)) {
      GiNaC::lst v = BOOST_PYTHON_CONVERSION::from_python(oo, py::type<const GiNaC::lst &>());
      if (n_steps != int(v.nops())) {
         PyErr_SetString(PyExc_IndexError, "basic_setitem() not matching index vectors");
         throw py::error_already_set();
      }
      int k = start;
      for (int i=0;i<n_steps;++i,k += step_size)
        m.let_op((k==l)?0:k) = v[i];
    } else {
      std::ostrstream os;
      os << "basic_setitem() slice for " << m.class_name() << std::ends;
      PyErr_SetString(PyExc_NotImplementedError, os.str());
      throw py::error_already_set();
    }
  }
}

void lst_delitem(GiNaC::lst & m, py::ref index) {
  PyObject * o = index.get();
  int l = m.nops();
  int start, step_size, n_steps;
  start = parse_subindex(o, &step_size, &n_steps, l);
  if (start < 0)
    throw py::error_already_set();
  if (n_steps==PseudoIndex || n_steps==RubberIndex) {
    PyErr_SetString(PyExc_NotImplementedError, "lst_delitem() PseudoIndex|RubberIndex");
    throw py::error_already_set();
  }
  /*TODO del lst (need access to lst::seq which is protected)*/
  /*
  GiNaC::exlist::iterator viter = m.seq.begin();
  if (n_steps==SingleIndex) {
    for(int i = 0; i < start; ++i,++viter);
    m.seq.erase(viter);
  } else {
    PyErr_SetString(PyExc_NotImplementedError, "lst_delitem() slice");
    throw py::error_already_set();
    }
  */
}
/*M_DT append(self, obj)
  Append `obj' to end. `self' must be ex(lst).
 */
void ex::append_1(py::ref obj) {
  if (is_lst())
    ex_to_nonconst_lst(*this).append(ex_from_ref(obj));
  else {
    PyErr_SetString(PyExc_NotImplementedError, "ex.append() can be used only for ex(lst)");
    throw py::error_already_set();
  }
}
/*M_DT prepend(self, obj)
  Prepend `obj' to beginning. `self' must be ex(lst).
 */
void ex::prepend_1(py::ref obj) {
  if (is_lst())
    ex_to_nonconst_lst(*this).prepend(ex_from_ref(obj));
  else {
    PyErr_SetString(PyExc_NotImplementedError, "ex.prepend() can be used only for ex(lst)");
    throw py::error_already_set();
  }
}
/*M_DT index(self, obj)
  Return index of first occurrence of `obj'.
 */
long ex::index_1(py::ref obj) const {
  GiNaC::ex e = ex_from_ref(obj);
  long n = nops_0();
  for (long i=0;i<n;++i)
    if (e.is_equal(op_1(i)))
      return i;
  PyErr_SetString(PyExc_ValueError, "ex.index(obj): obj not in ex");
  throw py::error_already_set();
}

#endif // !PYGINAC_PROTOS
#endif // !PYGINAC_DEFS




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