[uBLAS] array_adaptor, shallow_array_adaptor, interoperability and bugs

It is my first post. I still write worst in English than in C++. I hope don't mess it up… INTEROPERABILITY I'm been trying to use array_adaptor and shallow_array_adaptor to modify data with uBLAS. Yes, both classes are undocumented but it is useful (not this implementation) in some cases to have this kind of adaptor. For example: // Statistics accumulator for regression, correlation, etc. struct simple_regression { void operator()(double x, double y) { … } double mean_x; double var_x; double mean_y; double var_y; double covar; vector_wrapper<double> v() { … } // Return vector with a reference array adapter }; Now, you need (for example) to interpolate two accumulators. Then you should to be able to do: simple_regression sr, sr1, sr2; … double w = 0.5; sr.v() = sr1.v()*w+sr2.v()*(1-w); And you don't want that uBLAS copies data from you objects to inner containers continuously. UNDOCUMENTED ATTEMPT array_adaptor<T> has deep copy semantics. You can to construct an array_adaptor that use the external data, but vector call to copy constructor and this makes a copy: struct point { double x; double y; double z; }; point p = { 1, 2, 3 } array_adaptor<double> a(3, &p.x); // Ok, a holds p address vector<double, array_adaptor<double> > v(a); // v now holds a new address! Well, a bit confusing class. If the only purpose of this class template is to pass plain data as arguments. Why not to put that constructor in unbounded_array and bounded_array? unbounded_array(size_t size, T* data) : size_(size), data_(new value_type[size]) { std::copy(data, data+size, data_); } Then, I found shallow_adaptor_array, more dangerous and funny. It has shallow copy semantics and a dummy shared_array with reference counting... ¿? // Yes, I want troubles… #define BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR struct point { double x; double y; double z; }; void test() { point p = { 1, 2, 3 } shallow_array_adaptor<double> a(3, &p.x); // Ok, a holds p address vector<double, shallow_array_adaptor<double> > v(a); // Ok, v holds p address v += v; // Ok, now p = { 2, 4, 6 } v /= 2; // Ok, now p = { 1, 2, 3 } v = 2*v; // ¡¡¡What!!! p = { 1, 2, 3 } } // Dummy functor of shared_array in shallow_array_adaptor called, ok. When you assign v with an expression, this constructs a temporary and then swaps between the temporary and v. Here is the issue: class shallow_array_adaptor<T> : … { ... // Swapping BOOST_UBLAS_INLINE void swap (shallow_array_adaptor &a) { if (this != &a) { std::swap (size_, a.size_); std::swap (own_, a.own_); std::swap (data_, a.data_); // This is definitely infidelity } } ... }; This is not a good idea. This member function should have a dual behavior: class shallow_array_adaptor<T> : … { ... // Swapping BOOST_UBLAS_INLINE void swap (array_adaptor& a) { if (own_ && a.own_) { // If they own the data do wife-swapping if (this != &a) { std::swap(size_, a.size_); std::swap(own_, a.own_); std::swap(data_, a.data_); } } else if (&data_[0] != &a.data_[0]) std::swap_ranges(data_, data_+size_, a.data_); // Childs is another thing } ... }; Modifying this function I get: void test() { point p = { 1, 2, 3 } shallow_array_adaptor<double> a(3, &p.x); // Ok, a holds p address vector<double, shallow_array_adaptor<double> > v(a); // Ok, v holds p address v = 2*v; // Ok, now p = { 2, 4, 6 } and v holds p address } // 0kills of dynamic memory WHY NOT? 1. An unbounded_array and bounded_array constructor for C plain arrays and copy semantics. 2. To discontinue this adaptor_array (with a #ifndef) or modify. Its behavior can do it point nº1. 3. To fix, test and document shallow_array_adaptor (or another name). It should be useful. Yes, I know about memory leaks. But there are things like vector proxies, iterator ranges, etc. The problem comes when you have not a clear semantic. Regards, Guillermo Ruiz Troyano.

Guillermo Ruiz Troyano wrote:
It is my first post. I still write worst in English than in C++. I hope don't mess it up…
There is a special mailing list for ublas, see <http://lists.boost.org/mailman/listinfo.cgi/ublas>
I'm been trying to use array_adaptor and shallow_array_adaptor to modify data with uBLAS. Yes, both classes are undocumented but it is useful (not this implementation) in some cases to have this kind of adaptor.
I regularly use "shallow_array_adaptor", especially I also have the "#define BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR" in my code. I haven't thought about whether there would be a way to fix the potential issues.
WHY NOT?
1. An unbounded_array and bounded_array constructor for C plain arrays and copy semantics. 2. To discontinue this adaptor_array (with a #ifndef) or modify. Its behavior can do it point nº1. 3. To fix, test and document shallow_array_adaptor (or another name). It should be useful.
Yes, I know about memory leaks. But there are things like vector proxies, iterator ranges, etc. The problem comes when you have not a clear semantic.
Sorry, I haven't tried to follow your description and reasoning in detail. I suggest you repost this to the ublas mailing list, then we can see who "will" take the time to think through this (and eventually work on patches). Regards, Thomas

Thanks, I will try there. El 26/02/2012, a las 12:26, Thomas Klimpel escribió:
Guillermo Ruiz Troyano wrote:
It is my first post. I still write worst in English than in C++. I hope don't mess it up…
There is a special mailing list for ublas, see <http://lists.boost.org/mailman/listinfo.cgi/ublas>
I'm been trying to use array_adaptor and shallow_array_adaptor to modify data with uBLAS. Yes, both classes are undocumented but it is useful (not this implementation) in some cases to have this kind of adaptor.
I regularly use "shallow_array_adaptor", especially I also have the "#define BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR" in my code. I haven't thought about whether there would be a way to fix the potential issues.
WHY NOT?
1. An unbounded_array and bounded_array constructor for C plain arrays and copy semantics. 2. To discontinue this adaptor_array (with a #ifndef) or modify. Its behavior can do it point nº1. 3. To fix, test and document shallow_array_adaptor (or another name). It should be useful.
Yes, I know about memory leaks. But there are things like vector proxies, iterator ranges, etc. The problem comes when you have not a clear semantic.
Sorry, I haven't tried to follow your description and reasoning in detail. I suggest you repost this to the ublas mailing list, then we can see who "will" take the time to think through this (and eventually work on patches).
Regards, Thomas
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Guillermo Ruiz Troyano
-
Thomas Klimpel