Boost :: ublas, how to get int matrix determinant?

I found a function that calculates the determinant of the boost :: ublas matrix:

template<typename ValType>
ValType det_fast(const ublas::matrix<ValType>& matrix)
{
    // create a working copy of the input 
    ublas::matrix<ValType> mLu(matrix);
    ublas::permutation_matrix<std::size_t> pivots(matrix.size1());

    auto isSingular = ublas::lu_factorize(mLu, pivots);
    if (isSingular)
        return static_cast<ValType>(0);

    ValType det = static_cast<ValType>(1);
    for (std::size_t i = 0; i < pivots.size(); ++i) 
    {
        if (pivots(i) != i)
            det *= static_cast<ValType>(-1);

        det *= mLu(i, i);
    }

    return det;
}

This function works fine, but only with non-integer types (it works fine with float and double). When I try to pass the matrix the same , but with type int, I got a compilation error:

Check for a failure in the file c: \ boost \ boost_1_58_0 \ boost \ numeric \ ublas \ lu.hpp on line 167: only! = 0 || detail :: expression_type_check (prod (triangular_adaptor (m), triangular_adaptor (m)), cm) unknown location (0): fatal error in "BaseTest": std :: logic_error: internal logic

Is this a boost error or is my function incorrect? What change could I make to avoid this error?

+4
1

, , , , UBLAS. , , .

#define BOOST_UBLAS_TYPE_CHECK 0

. !

#include <iostream>
#define BOOST_UBLAS_TYPE_CHECK 0
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/lu.hpp>
namespace ublas = boost::numeric::ublas;

template<typename ValType>
ValType det_fast(const ublas::matrix<ValType>& matrix)
{
    // create a working copy of the input 
    ublas::matrix<ValType> mLu(matrix);
    ublas::permutation_matrix<std::size_t> pivots(matrix.size1());

    auto isSingular = ublas::lu_factorize(mLu, pivots);
    if (isSingular)
        return static_cast<ValType>(0);

    ValType det = static_cast<ValType>(1);
    for (std::size_t i = 0; i < pivots.size(); ++i) 
    {
        if (pivots(i) != i)
            det *= static_cast<ValType>(-1);

        det *= mLu(i, i);
    }

    return det;
}

int main()
{
    ublas::matrix<int> m (3, 3);
    for (unsigned i = 0; i < m.size1 (); ++ i)
        for (unsigned j = 0; j < m.size2 (); ++ j)
            m (i, j) = 3 * i + j;
    std::cout << det_fast(m) << std::endl;
}

, m , int double, . int -48.

№ 1

, ublas::matrix<int> - ublas::matrix<float>. , - det_fast define.

int det_fast(const ublas::matrix<int>& matrix)
{
    return (int)det_fast(ublas::matrix<float>(matrix));
}

№ 2

, average time - ( int ) 5 .

size |  average time, ms
------------------------
     |    int      float
------------------------
100  |    9.0        9.0
200  |   46.6       46.8
300  |  156.4      159.4
400  |  337.4      331.4
500  |  590.8      609.2
600  |  928.2     1009.4
700  | 1493.8     1525.2
800  | 2162.8     2231.0
900  | 3184.2     3025.2

, int , . , float ( , 0-15 , ). , , , 3000 x 3000 ( 0-15 , ). (, 5000 x 5000 - 125 ). ! 1.0% int !

, Visual Studio 2013 1.58. clock. - Intel Xeon E5645 2.4GHz.

, , . , .

+2

Source: https://habr.com/ru/post/1584732/


All Articles