|
Ublas : |
From: Russ (c.r.coggrave_at_[hidden])
Date: 2006-04-24 05:50:36
Michael Stevens <mail <at> michael-stevens.de> writes:
>
> On Tuesday, 18. April 2006 22:58, Russ wrote:
> > I would like to contribute the following input and output operators for
> > indirect_array objects (see below). Hopefully this code can be added to
> > io.hpp.
>
> I am wondering if a special IO implmentation just for indirect_array objects
> is the right way to go. range and slice are already defined in the uBLAS
> documentation as models of an STL Revisible Container. I think indirect_array
> would also be modeled as such.
>
> Since Revisible Container provides enough functionality to write generic IO
> functions. One could therefore right a generic formated stream reader and
> writter for these containers and them simply tie them simply provide operator
> << and >> overloads for the types.
I have reimplemented the IO implementation as generic functions for objects that
model the reversible container concept. I would be grateful if you could comment
on whether this is the way in which you were proposing to proceed...
// Output operator for objects that model STL Reversible Container Concept
template<class E, class T, class C>
BOOST_UBLAS_INLINE
std::basic_ostream<E, T> &output_op (std::basic_ostream<E, T> &os, const C &c)
{
// Check that container C models the Reversible Container Concept
boost::function_requires< boost::ReversibleContainerConcept< C > >();
typedef typename C::size_type size_type;
size_type size = c.size();
std::basic_ostringstream<E, T, std::allocator<E> > s;
s.flags (os.flags ());
s.imbue (os.getloc ());
s.precision (os.precision ());
// Output size of container
s << '[' << size << "](";
// Initialise iterators
C::const_iterator it( c.begin () );
C::const_iterator it_end( c.end() );
// Output first entry
if (size > 0) {
s << *it;
++it;
}
// Output comma seperated list of remaining entries
while (it != it_end) {
s << ',' << *it;
++it;
}
s << ')';
return os << s.str ().c_str ();
}
// Input operator for indirect_array<A> objects
template<class E, class T, class C>
BOOST_UBLAS_INLINE
std::basic_istream<E, T> &input_op (std::basic_istream<E, T> &is, const C &c)
{
// Check that container C models the Reversible Container Concept
boost::function_requires< boost::ReversibleContainerConcept< C > >();
typedef typename C::size_type size_type;
E ch;
size_type size;
if (is >> ch && ch != '[') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (is >> size >> ch && ch != ']') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
C s (size);
if (is >> ch && ch != '(') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
C::iterator it = s.begin();
C::iterator it_end = s.end();
size_type i = 0;
while (it != it_end) {
if (is >> *it >> ch && ch != ',') {
is.putback (ch);
if (i < size - 1)
is.setstate (std::ios_base::failbit);
break;
}
i++;
}
if (is >> ch && ch != ')') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
}
}
if (! is.fail ())
c.swap (s);
}
return is;
}
// Output operator for indirect_array<A> objects
template<class E, class T, class A>
std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os, const
boost::numeric::ublas::indirect_array<A> &ia)
{
return output_op( os, ia);
}
// Input operator for indirect_array<A> objects
template<class E, class T, class A>
std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is, const
boost::numeric::ublas::indirect_array<A> &ia)
{
return input_op( is, ia );
}
>
> > In addition, I would like to ask a quick question...
> >
> > Background: I am trying to write some code that performs a similar
> > operation to the Matlab find() function - e.g. returns row and column
> > indices of non-zero matrix elements. The indirect_array class seems ideal
> > for storing the indices, since in addition to normal array properties, they
> > can also be used to create a matrix_vector_indirect proxy object. However,
> > I appreciate that the indirect_array class is undocumented and its future
> > is unknown.
> >
> > Is there any reason why there is no resize() method for the indirect_array
> > templated class? Would anyone mind if I added one?
> I think resize() would be nice BUT. To be consistent with people expectations
> it might be good to go all the way and define insert and erase operations.
>
> > I propose that the size_
> > attribute is removed, and that the array size is determined as the
> > data_.size(). New resize() methods would call data_.resize().
> Sound good.
>
> > If the resize() method were added then it would be possible define a free
> > function that returns info about the non-zero elements as follows:
> >
> > template< class M, class IA >
> > void Find( M Matrix, IA &RowIndices, IA &ColIndices )
> >
> > where IA = indirect_array<>. The Find function could then resize the
> > indirect_arrays to the number of non-zero elements found in M.
>
> We will need to find a place to but all these non BLAS free functions
>
> Michael
I have added the resize() methods, however, will hold off preparing a patch
until I have had a chance to look at modeling the insert and erase opertions.
Regards,
Russ