12

ログドメインのfloatのスパース行列でいくつかの計算を行っているため、「空の」エントリは実際には-Infです(-FLT_MAXを使用)。現在、カスタムのスパース行列クラスを使用していますが、既成の代替品に交換したいと思っています。

これはC++です。私の傾向は、EigenとBoostuBlasの圧縮された列マトリックスを調べることでした。ただし、どちらも「ゼロ」のカスタム値をサポートしていることは明らかではありません(おそらくテンプレートパラメータによって提供されます)。誰か提案がありますか?

明確化

私が欲しいのはこれです:以前に「設定」されていないセル(i、j)については、mat [i、j]に-Inf ...を返してもらいたいので、これはおそらく「デフォルト」としてより適切に説明されます。スパース行列の「空の」エントリの値。

これを使用して、アンダーフローを回避するためにログドメインに保持された確率でHMM再帰(Viterbi、sum-product)を実行しています。

私は行列演算を行っていません...基本的に、動的計画法のタブローを埋めているだけです。行列のバンドのみを入力していて、メモリを効率的に使用したいので、スパース行列クラスを使用したいと思います。圧縮された帯行列は、行列を「順番に」入力しているので、良好なパフォーマンスが得られます。

4

2 に答える 2

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";
}
于 2011-08-31T20:40:02.363 に答える
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);

この方法では、ブースト マトリックス クラスの機能を書き直すことはありませんが、目的の結果が得られるはずです。

于 2011-09-01T15:46:01.067 に答える