Разреженный матричный класс с параметризуемым "нулем"
Я делаю некоторые вычисления на разреженной матрице float в лог-домене, поэтому "пустые" записи на самом деле -Inf (с использованием -FLT_MAX). Сейчас я использую настраиваемый разреженный матричный класс, но я хочу заменить его на замену.
Это на С++. Мои наклонности состояли в том, чтобы посмотреть на сжатые столбчатые матрицы в Eigen и Boost uBlas. Однако неясно, поддерживает ли пользовательское значение "нуль" (возможно, задается параметром шаблона). Кто-нибудь имеет предложение?
Разъяснение:
Что я хочу, так это: для любой ячейки (i, j), которая ранее не была установлена, я бы хотел, чтобы mat [i, j] возвращал -Inf... так что это, пожалуй, лучше описано как "default" значение для "пустых" записей разреженной матрицы.
Я использую это для выполнения рекурсий HMM (Viterbi, sum-product) с вероятностями, хранящимися в лог-домене, чтобы избежать переполнения.
Я не делаю никаких матричных операций... Я просто заполняю таблицу динамического программирования. Я хочу использовать разреженный матричный класс, потому что я только заполняю полосу матрицы, и мне бы хотелось использовать эффективную память. Сжатые матричные матрицы дают хорошую производительность, так как я заполняю матрицу "по порядку".
Ответы
Ответ 1
Решение, которое я сейчас приготовил, - это. Определите класс lfloat
:
class lfloat {
float value;
public:
lfloat(float f=-FLT_MAX)
{
value = f;
}
lfloat& operator=(float f)
{
value = f;
return *this;
}
operator float() { return value; }
};
и используйте его так:
compressed_matrix<lfloat> M1(3,3);
Таким образом, мы не переписываем какую-либо функциональность в классах матрицы boost, но мы должны получить желаемый результат.
Ответ 2
Как насчет чего-то подобного?
class compressed_matrix_nonzero_default : public boost::numeric::ublas::compressed_matrix<double>
{
double def;
public:
compressed_matrix_nonzero_default( int s1, int s2 )
: boost::numeric::ublas::compressed_matrix<double>(s1,s2)
, def(0)
{
}
void setDefault( double d ) { def = d; }
double value( int i, int j )
{
typedef boost::numeric::ublas::compressed_matrix<double>::iterator1 it1_t;
typedef boost::numeric::ublas::compressed_matrix<double>::iterator2 it2_t;
for (it1_t it1 = begin1(); it1 != end1(); it1++)
{
if( it1.index1() < i )
continue;
if( it1.index1() > i ) {
return def;
}
for (it2_t it2 = it1.begin(); it2 != it1.end(); it2++)
{
if( it2.index2() < j )
continue;
if( it2.index2() == j )
return *it2;
if( it2.index2() > j )
return def;
}
}
return def;
}
};
Использование
compressed_matrix_nonzero_default MNZ(3,3);
MNZ.setDefault(-100);
MNZ (1,1) = 45;
for( int i = 0; i < 3; i++ ) {
for( int j = 0; j < 3; j++ ) {
std::cout << MNZ.value(i,j) << ",";
}
std::cout << "\n";
}