|
Boost : |
From: Kresimir Fresl (fresl_at_[hidden])
Date: 2002-05-06 17:33:24
Joerg Walter wrote:
> But Toon is right, if he mentions, that
> ublas clear() doesn't have the same semantics as STL clear(). Shouldn't we
> better use the name zeroize() instead of clear()?
Ha! You have finally opened the Pandora's box ;o)
Let's see one small example:
==========================================
typedef numerics::vector<double> uvector;
typedef
numerics::vector< double, numerics::bounded_array<double, 16> > bvector;
typedef numerics::vector< double, std::vector<double> > svector;
int main() {
uvector uv (8);
bvector bv (8);
svector sv (8);
for (int i = 0; i < 8; ++i)
uv[i] = bv[i] = sv[i] = i+1;
cout << endl << "original:\n" << "uv: " << uv << endl;
cout << "bv: " << bv << endl;
cout << "sv: " << sv << endl;
uv.insert (4, 100);
bv.insert (4, 100);
sv.insert (4, 100);
cout << endl << "after insert():\n" << "uv: " << uv << endl;
cout << "bv: " << bv << endl;
cout << "sv: " << sv << endl;
uv.erase (4);
bv.erase (4);
sv.erase (4);
cout << endl << "after erase():\n" << "uv: " << uv << endl;
cout << "bv: " << bv << endl;
cout << "sv: " << sv << endl;
uv.resize (12);
bv.resize (12);
sv.resize (12);
cout << endl << "after resize():\n" << "uv: " << uv << endl;
cout << "bv: " << bv << endl;
cout << "sv: " << sv << endl << endl;
}
=========================================
The output is:
=========================================
original:
uv: [8](1,2,3,4,5,6,7,8)
bv: [8](1,2,3,4,5,6,7,8)
sv: [8](1,2,3,4,5,6,7,8)
after insert():
uv: [8](1,2,3,4,100,6,7,8)
bv: [8](1,2,3,4,100,6,7,8)
sv: [8](1,2,3,4,100,5,6,7)
after erase():
uv: [8](1,2,3,4,0,6,7,8)
bv: [8](1,2,3,4,0,6,7,8)
sv: [8](1,2,3,4,5,6,7,8)
after resize():
uv: [12](0,0,0,0,0,0,0,0,0,0,0,0)
bv: [12](1,2,3,4,0,6,7,8,4.85584e-270,4.92833e-270,2.81476,2.09812)
sv: [12](1,2,3,4,5,6,7,8,0,0,0,0)
==========================================
The behaviour of ublas::vector<>, when insert(), erase() or
resize() are called, depends on array_type, because
these functions call array_type's functions with same
names. And those have different semantics.
On the other hand, behaviour of clear() is always the
same, because ublas::vector<>::clear() does not
call array_type::clear() but std::fill().
This is rather confusing: behaviour of some functions
depends on underlying array_type and is the same
as corresponding array_type's function, while behaviour
of some other functions doesn't depend and is *different*
from the corresponding array_type's function.
I don't think that renaming is the cure.
ublas::vector<> should be regarded as adaptor/decorator
which adds linear algebra functionality to underlying `array_type'
(of course, this should be clearly and loudly stated in documentation)
and it should not change the behaviour of array_type's functions
with same names.
Concretely, ublas::vector<>::clear() should call
array_type::clear(), whatever it does.
Problem that results in current version of ublas::vector<>::clear()
was (thread `ublas & custom containers (2)'):
>> If a sparse matrix result is assigned to a dense matrix,
>> the assignment operation should be dispatched to
>> the sparse matrix logic: clear the dense matrix and insert
>> the rhs elements at the corresponding positions.
[...]
> `numerics::vector_assign<>::operator()' with `sparse_tag'
> uses `array_type::clear()' to clear `numerics::vector<>'
> before assignement, that is, before the call to
> `array_type::insert()'. But the behaviour and semantics of
> `numerics::unbounded_array<>::clear()' and
> `numerics::array_adaptor<>::clear()' is very different
> from the behaviour of `std::vector<>::clear()'.
> First two simply assign `0' to all elements. But
> `std::vector<>::clear()' really clears the vector,
> ie. it *removes* all elements
I proposed to call std::fill (v.begin(), v.end(), value_type());
in vector_assign<>::operator() (vct_t v, vct_expr, sparse_tag)
instead of ublas::vector::clear(). Joerg put std::fill() in
ublas::vector<>::clear() instead.
At that time I didn't see any reason to object, but now I think
that my proposal should be reconsidered.
Sincerely,
fres
PS. It should be noted that semantics of std::valarray<>::resize()
is different from std::vector<>::resize():
==========================================
std::vector<double> vct (4);
std::valarray<double> va (4);
for (int i = 0; i < 4; ++i)
vct[i] = va[i] = i;
vct.resize (6, 100);
va.resize (6, 100);
for (int i = 0; i < 6; ++i)
std::cout << vct[i] << " " << va[i] << "\n";
===========================================
Output is:
0 100
1 100
2 100
3 100
100 100
100 100
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk