|
Ublas : |
From: Russ (c.r.coggrave_at_[hidden])
Date: 2006-04-18 16:58:38
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.
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 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().
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.
Contributed code...
// 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
ublas::indirect_array<A> &ia)
{
typedef typename indirect_array<A>::size_type size_type;
size_type size = ia.size();
std::basic_ostringstream<E, T, std::allocator<E> > s;
s.flags (os.flags ());
s.imbue (os.getloc ());
s.precision (os.precision ());
s << '[' << size << "](";
if (size > 0)
s << ia(0);
for (size_type i = 1; i < size; ++ i)
s << ',' << ia(i);
s << ')';
return os << s.str ().c_str ();
}
// 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, ublas::
indirect_array<A> &ia)
{
typedef typename indirect_array<A>::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 ()) {
indirect_array<A> s (size);
if (is >> ch && ch != '(') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
for (size_type i = 0; i < size; i ++) {
if (is >> s (i) >> ch && ch != ',') {
is.putback (ch);
if (i < size - 1)
is.setstate (std::ios_base::failbit);
break;
}
}
if (is >> ch && ch != ')') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
}
}
if (! is.fail ())
v.swap (s);
}
return is;
}