Boost C++ Libraries: Ticket #10127: coordinate_matrix sort() fails on to std::swap https://svn.boost.org/trac10/ticket/10127 <p> Orginally posted here: </p> <p> <a class="ext-link" href="http://stackoverflow.com/questions/24228772/c11-compatibility-of-sparse-matrix-implementations"><span class="icon">​</span>http://stackoverflow.com/questions/24228772/c11-compatibility-of-sparse-matrix-implementations</a> </p> <p> The following program does not compile with gcc 4.8 or clang 3.4 when --std=c++11 is set: </p> <pre class="wiki">#include &lt;boost/numeric/ublas/io.hpp&gt; #include &lt;boost/numeric/ublas/matrix_sparse.hpp&gt; using namespace boost::numeric::ublas; int main(int argc, char** argv) { coordinate_matrix&lt;int&gt; m1(100, 100, 100); for (int i = 0; i &lt; 100; i++) m1.insert_element(i,i,i); compressed_matrix&lt;int&gt; m2(m1, 100); } </pre><p> We can solve the issue by providing a swap() routine: </p> <pre class="wiki">#include &lt;boost/numeric/ublas/io.hpp&gt; #include &lt;boost/numeric/ublas/matrix_sparse.hpp&gt; using namespace boost::numeric::ublas; namespace std { template&lt;class M&gt; inline void swap (boost::numeric::ublas::index_triple&lt;M&gt; i1, boost::numeric::ublas::index_triple&lt;M&gt; i2) { i1.swap (i2); } } int main(int argc, char** argv) { coordinate_matrix&lt;int&gt; m1(100, 100, 100); for (int i = 0; i &lt; 100; i++) m1.insert_element(i,i,i); compressed_matrix&lt;int&gt; m2(m1, 100); } </pre><p> I am not an expert C++ template programmer, so I am unable to decide what is the cause here, but the C++ reference on std::sort explicitly mentions a swap() method. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10127 Trac 1.4.3 Casey Carter <Casey@…> Mon, 16 Jun 2014 15:01:26 GMT <link>https://svn.boost.org/trac10/ticket/10127#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10127#comment:1</guid> <description> <p> Test case can be minimized to: </p> <pre class="wiki">#include &lt;boost/numeric/ublas/matrix_sparse.hpp&gt; int main() { boost::numeric::ublas::coordinate_matrix&lt;int&gt; m1(1, 1, 1); m1.insert_element(0, 0, 0); } </pre><p> The problem seems to be that when BOOST_UBLAS_STRICT_MATRIX_SPARSE is defined, coordinate_matrix and its iterator types use a proxy class as their reference type: </p> <pre class="wiki">#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE typedef T &amp;reference; #else typedef sparse_matrix_element&lt;self_type&gt; reference; #endif </pre><p> which violates the C++ standard's requirement that the reference type for forward iterators is a true reference. C++11 [forward.iterators]/1 states: "A class or pointer type X satisfies the requirements of a forward iterator if ... <strong>if X is a mutable iterator, reference is a reference to T; if X is a const iterator, reference is a reference to const T,</strong> ...". </p> </description> <category>Ticket</category> </item> <item> <author>Andrew Medlin <amedlin@…></author> <pubDate>Fri, 27 Jun 2014 06:25:54 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10127#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10127#comment:2</guid> <description> <p> This also affects version 1.55.0 sparse vectors, which breaks the LU substitution. </p> <p> For example, the following code produces incorrect output. It should swap the 2nd and 3rd elements, producing </p> <blockquote> <p> 1.000000, 3.000000, 2.000000 </p> </blockquote> <p> but instead it produces </p> <blockquote> <p> 1.000000, 3.000000, 3.000000 </p> </blockquote> <p> It is fixed by uncommenting the #define BOOST_UBLAS_NO_ELEMENT_PROXIES </p> <pre class="wiki">//#define BOOST_UBLAS_NO_ELEMENT_PROXIES #include &lt;boost/numeric/ublas/vector_sparse.hpp&gt; #include &lt;boost/numeric/ublas/lu.hpp&gt; using namespace boost::numeric::ublas; int main() { mapped_vector&lt;float&gt; y; y(0) = 1.0f; y(1) = 2.0f; y(2) = 3.0f; LOG("Initial vector is: " &lt;&lt; y); permutation_matrix&lt;std::size_t&gt; perm(y.size()); perm(0) = 0; perm(1) = 2; perm(2) = 2; swap_rows(perm, y); LOG("Swapped vector is: " &lt;&lt; y); } </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sun, 06 Jul 2014 09:55:59 GMT</pubDate> <title>component changed; owner set https://svn.boost.org/trac10/ticket/10127#comment:3 https://svn.boost.org/trac10/ticket/10127#comment:3 <ul> <li><strong>owner</strong> set to <span class="trac-author">Gunter</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">uBLAS</span> </li> </ul> Ticket eg@… Tue, 25 Nov 2014 16:16:31 GMT <link>https://svn.boost.org/trac10/ticket/10127#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10127#comment:4</guid> <description> <p> Hi, any chance to get this ticket solved in the next release ? version 1.57 doesn't seem to offer a fix for this issue, as far as I know. </p> </description> <category>Ticket</category> </item> <item> <author>Andrew Medlin <amedlin@…></author> <pubDate>Wed, 26 Nov 2014 01:02:16 GMT</pubDate> <title>severity, milestone changed https://svn.boost.org/trac10/ticket/10127#comment:5 https://svn.boost.org/trac10/ticket/10127#comment:5 <ul> <li><strong>severity</strong> <span class="trac-field-old">Problem</span> → <span class="trac-field-new">Showstopper</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.58.0</span> </li> </ul> <p> I think this bug represents a fundamental break in core functionality, so I am raising the severity. I believe this should be fixed with priority. </p> Ticket eg@… Wed, 26 Nov 2014 15:16:35 GMT keywords set https://svn.boost.org/trac10/ticket/10127#comment:6 https://svn.boost.org/trac10/ticket/10127#comment:6 <ul> <li><strong>keywords</strong> c++11 swap sort matrix reference added </li> </ul> Ticket