Boost C++ Libraries: Ticket #11295: Matrix Memory problem after using lu_factorize https://svn.boost.org/trac10/ticket/11295 <p> Discovered that after using lu_factorize the values of the matrix have changed! </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;boost/date_time/posix_time/posix_time.hpp&gt; #include &lt;boost/numeric/ublas/matrix.hpp&gt; #include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt; #include &lt;boost/numeric/ublas/vector.hpp&gt; #include &lt;boost/numeric/ublas/io.hpp&gt; #include &lt;boost/numeric/ublas/lu.hpp&gt; using namespace std; using namespace boost::numeric; int main() { ublas::matrix&lt;double&gt; X(3,3); X.clear(); X(0,0) = 0.995182407377577; X(0,1) =-0.006473367705848; X(0,2) =-0.002032391957706; X(1,0) =-0.006473367705848; X(1,1) = 0.995182407377577; X(1,2) =-0.002032391957706; X(2,0) =-0.002032391957706; X(2,1) =-0.002032391957706; X(2,2) = 0.936175146339137; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; cout&lt;&lt;ublas::lu_factorize(X)&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; cout&lt;&lt;ublas::lu_factorize(X)&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; } </pre><p> Output: </p> <pre class="wiki">[3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006473367705848,0.995182407377577,-0.002032391957706),(-0.002032391957706,-0.002032391957706,0.936175146339137)) 0 [3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006504704723334175,0.9951403000320849,-0.002045612067272957),(-0.002042230592742885,-0.002055601674665375,0.9361667907625133)) 0 [3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006536193440632496,0.9950979888485471,-0.002058896174255709),(-0.002052116855767581,-0.002079077442455779,0.9361583394521271)) </pre><p> Is this fixed in newer versions? </p> <p> Thanks </p> <p> Michael Cortis </p> <p> RA, Durham University </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11295 Trac 1.4.3 2015csb1032@… Fri, 31 Mar 2017 10:45:26 GMT <link>https://svn.boost.org/trac10/ticket/11295#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11295#comment:1</guid> <description> <p> You interpreted the function in the wrong way, that's what the lu_factorize function does. The return value, 0 or non 0 value which you see, only specifies whether the matrix is singular or not. The return value is 0 if the matix is singular, and non 0 if the matrix is non-singular. </p> <p> Now intuitively, you would think that lu_factorize should give two matrices L and U on decomposition. That's what is done in a way. </p> <p> The matrix which you pass in lu_factorize(X), here X is passed by reference to lu_factorize function,which will <strong>decompose X and now, X will contain the information of the two factorized matrix L and U. Hence X is changed.</strong><br /> If you don't want X to be changed. Then, create another matrix Y, do Y=X and then pass Y in lu_factorize : lu_factorize(Y) </p> <p> It's a typical approach in LU decomposition, that the diagonal elements of L contains 1. So, the two matrices L and U are fitted into 1 matrix Y, putting L in the lower part omitting the diagonal elements, and putting U in the upper part. L and U can be extracted from Y easily (shown in code). </p> <p> If, Y (after function ends) = <br /> y1 y2 y3<br /> y4 y5 y6<br /> y7 y8 y9<br /> </p> <p> Then, L=<br /> 1 0 0<br /> y4 1 0<br /> y7 y7 1<br /> </p> <p> and u =<br /> y1 y2 y3<br /> 0 y5 y6<br /> 0 0 y9<br /> </p> <p> You can run the following code, it will show what I'm trying to say above. </p> <pre class="wiki"> ublas::matrix&lt;double&gt; X(3,3); X.clear(); X(0,0) = 0.995182407377577; X(0,1) =-0.006473367705848; X(0,2) =-0.002032391957706; X(1,0) =-0.006473367705848; X(1,1) = 0.995182407377577; X(1,2) =-0.002032391957706; X(2,0) =-0.002032391957706; X(2,1) =-0.002032391957706; X(2,2) = 0.936175146339137; ublas::matrix&lt;double&gt; Y(3,3); Y=X; ublas::lu_factorize(Y); ublas::matrix&lt;double&gt; L(3,3); L.clear(); ublas::matrix&lt;double&gt; U(3,3); U.clear(); for (int i=0; i&lt;3; i++){ for (int j=0; j&lt;3; j++){ if (i&lt;j){ U(i,j) = Y(i,j); L(i,j) = 0; } else if (i&gt;j){ L(i,j) = Y(i,j); U(i,j) = 0; } else if (i==j){ L(i,j) = 1; U(i,j) = Y(i,j); } } } cout &lt;&lt; "The original matrix X :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl&lt;&lt;endl; cout &lt;&lt; "LU_decomposed matrix in 1 matrix :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;Y&lt;&lt;endl&lt;&lt;endl; cout &lt;&lt; "LU_decomposed matrices in 2 diff matrix, L :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;L&lt;&lt;endl&lt;&lt;endl; cout &lt;&lt; "LU_decomposed matrices in 2 diff matrix, U :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;U&lt;&lt;endl&lt;&lt;endl; ublas::matrix&lt;double&gt; Z(3,3); cout &lt;&lt; "The product Z=L*U, which should be equal to X (Z=L*U=X), Z:"&lt;&lt;endl; axpy_prod(L, U, Z, true); cout&lt;&lt;setprecision(16)&lt;&lt;Z&lt;&lt;endl&lt;&lt;endl; </pre><p> Also, run the code with </p> <pre class="wiki"> X(0,0) = 1.0; X(0,1) = 2.0; X(0,2) = 3.0; X(1,0) = 4.0; X(1,1) = 5.0; X(1,2) = 6.0; X(2,0) = 7.0; X(2,1) = 8.0; X(2,2) = 9.0; </pre><blockquote> <p> instead of X(0,0) = 0.995182407377577;... for better understanding. </p> </blockquote> <p> Replying to <a class="new ticket" href="https://svn.boost.org/trac10/ticket/11295" title="#11295: Bugs: Matrix Memory problem after using lu_factorize (new)">michael.cortis@…</a>: </p> <blockquote class="citation"> <p> Discovered that after using lu_factorize the values of the matrix have changed! </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;boost/date_time/posix_time/posix_time.hpp&gt; #include &lt;boost/numeric/ublas/matrix.hpp&gt; #include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt; #include &lt;boost/numeric/ublas/vector.hpp&gt; #include &lt;boost/numeric/ublas/io.hpp&gt; #include &lt;boost/numeric/ublas/lu.hpp&gt; using namespace std; using namespace boost::numeric; int main() { ublas::matrix&lt;double&gt; X(3,3); X.clear(); X(0,0) = 0.995182407377577; X(0,1) =-0.006473367705848; X(0,2) =-0.002032391957706; X(1,0) =-0.006473367705848; X(1,1) = 0.995182407377577; X(1,2) =-0.002032391957706; X(2,0) =-0.002032391957706; X(2,1) =-0.002032391957706; X(2,2) = 0.936175146339137; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; cout&lt;&lt;ublas::lu_factorize(X)&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; cout&lt;&lt;ublas::lu_factorize(X)&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; } </pre><p> Output: </p> <pre class="wiki">[3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006473367705848,0.995182407377577,-0.002032391957706),(-0.002032391957706,-0.002032391957706,0.936175146339137)) 0 [3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006504704723334175,0.9951403000320849,-0.002045612067272957),(-0.002042230592742885,-0.002055601674665375,0.9361667907625133)) 0 [3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006536193440632496,0.9950979888485471,-0.002058896174255709),(-0.002052116855767581,-0.002079077442455779,0.9361583394521271)) </pre><p> Is this fixed in newer versions? </p> <p> Thanks </p> <p> Michael Cortis </p> <p> RA, Durham University </p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Fri, 16 Jun 2017 11:49:54 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11295#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11295#comment:2</guid> <description> <p> Thanks for the explanation. Didn't realize that both L and U are combined into a single matrix. </p> <p> Thanks again, Michael </p> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/11295#comment:1" title="Comment 1">2015csb1032@…</a>: </p> <blockquote class="citation"> <p> You interpreted the function in the wrong way, that's what the lu_factorize function does. The return value, 0 or non 0 value which you see, only specifies whether the matrix is singular or not. The return value is 0 if the matix is singular, and non 0 if the matrix is non-singular. </p> <p> Now intuitively, you would think that lu_factorize should give two matrices L and U on decomposition. That's what is done in a way. </p> <p> The matrix which you pass in lu_factorize(X), here X is passed by reference to lu_factorize function,which will <strong>decompose X and now, X will contain the information of the two factorized matrix L and U. Hence X is changed.</strong><br /> If you don't want X to be changed. Then, create another matrix Y, do Y=X and then pass Y in lu_factorize : lu_factorize(Y) </p> <p> It's a typical approach in LU decomposition, that the diagonal elements of L contains 1. So, the two matrices L and U are fitted into 1 matrix Y, putting L in the lower part omitting the diagonal elements, and putting U in the upper part. L and U can be extracted from Y easily (shown in code). </p> <p> If, Y (after function ends) = <br /> y1 y2 y3<br /> y4 y5 y6<br /> y7 y8 y9<br /> </p> <p> Then, L=<br /> 1 0 0<br /> y4 1 0<br /> y7 y7 1<br /> </p> <p> and u =<br /> y1 y2 y3<br /> 0 y5 y6<br /> 0 0 y9<br /> </p> <p> You can run the following code, it will show what I'm trying to say above. </p> <pre class="wiki"> ublas::matrix&lt;double&gt; X(3,3); X.clear(); X(0,0) = 0.995182407377577; X(0,1) =-0.006473367705848; X(0,2) =-0.002032391957706; X(1,0) =-0.006473367705848; X(1,1) = 0.995182407377577; X(1,2) =-0.002032391957706; X(2,0) =-0.002032391957706; X(2,1) =-0.002032391957706; X(2,2) = 0.936175146339137; ublas::matrix&lt;double&gt; Y(3,3); Y=X; ublas::lu_factorize(Y); ublas::matrix&lt;double&gt; L(3,3); L.clear(); ublas::matrix&lt;double&gt; U(3,3); U.clear(); for (int i=0; i&lt;3; i++){ for (int j=0; j&lt;3; j++){ if (i&lt;j){ U(i,j) = Y(i,j); L(i,j) = 0; } else if (i&gt;j){ L(i,j) = Y(i,j); U(i,j) = 0; } else if (i==j){ L(i,j) = 1; U(i,j) = Y(i,j); } } } cout &lt;&lt; "The original matrix X :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl&lt;&lt;endl; cout &lt;&lt; "LU_decomposed matrix in 1 matrix :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;Y&lt;&lt;endl&lt;&lt;endl; cout &lt;&lt; "LU_decomposed matrices in 2 diff matrix, L :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;L&lt;&lt;endl&lt;&lt;endl; cout &lt;&lt; "LU_decomposed matrices in 2 diff matrix, U :"&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;U&lt;&lt;endl&lt;&lt;endl; ublas::matrix&lt;double&gt; Z(3,3); cout &lt;&lt; "The product Z=L*U, which should be equal to X (Z=L*U=X), Z:"&lt;&lt;endl; axpy_prod(L, U, Z, true); cout&lt;&lt;setprecision(16)&lt;&lt;Z&lt;&lt;endl&lt;&lt;endl; </pre><p> Also, run the code with </p> <pre class="wiki"> X(0,0) = 1.0; X(0,1) = 2.0; X(0,2) = 3.0; X(1,0) = 4.0; X(1,1) = 5.0; X(1,2) = 6.0; X(2,0) = 7.0; X(2,1) = 8.0; X(2,2) = 9.0; </pre><blockquote> <p> instead of X(0,0) = 0.995182407377577;... for better understanding. </p> </blockquote> <p> Replying to <a class="new ticket" href="https://svn.boost.org/trac10/ticket/11295" title="#11295: Bugs: Matrix Memory problem after using lu_factorize (new)">michael.cortis@…</a>: </p> <blockquote class="citation"> <p> Discovered that after using lu_factorize the values of the matrix have changed! </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;boost/date_time/posix_time/posix_time.hpp&gt; #include &lt;boost/numeric/ublas/matrix.hpp&gt; #include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt; #include &lt;boost/numeric/ublas/vector.hpp&gt; #include &lt;boost/numeric/ublas/io.hpp&gt; #include &lt;boost/numeric/ublas/lu.hpp&gt; using namespace std; using namespace boost::numeric; int main() { ublas::matrix&lt;double&gt; X(3,3); X.clear(); X(0,0) = 0.995182407377577; X(0,1) =-0.006473367705848; X(0,2) =-0.002032391957706; X(1,0) =-0.006473367705848; X(1,1) = 0.995182407377577; X(1,2) =-0.002032391957706; X(2,0) =-0.002032391957706; X(2,1) =-0.002032391957706; X(2,2) = 0.936175146339137; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; cout&lt;&lt;ublas::lu_factorize(X)&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; cout&lt;&lt;ublas::lu_factorize(X)&lt;&lt;endl; cout&lt;&lt;setprecision(16)&lt;&lt;X&lt;&lt;endl; } </pre><p> Output: </p> <pre class="wiki">[3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006473367705848,0.995182407377577,-0.002032391957706),(-0.002032391957706,-0.002032391957706,0.936175146339137)) 0 [3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006504704723334175,0.9951403000320849,-0.002045612067272957),(-0.002042230592742885,-0.002055601674665375,0.9361667907625133)) 0 [3,3]((0.995182407377577,-0.006473367705848,-0.002032391957706),(-0.006536193440632496,0.9950979888485471,-0.002058896174255709),(-0.002052116855767581,-0.002079077442455779,0.9361583394521271)) </pre><p> Is this fixed in newer versions? </p> <p> Thanks </p> <p> Michael Cortis </p> <p> RA, Durham University </p> </blockquote> </blockquote> </description> <category>Ticket</category> </item> </channel> </rss>