2016-09-12 12 views
0

私は現在、スパース行列を保存するためのstd ::マップを使用しています:私は私がやりたいのマトリックス(行列転置を*行列)を作成した後マップのイテレータを使用せずにキー値のペアにアクセスできますか?

std::map<std::pair<int, int>, double> matrix; 

は私が

matrix[std::make_pair(i,j)] = value; 

を行う挿入するには(00 * 00)+(10 * 10)+(20 * 20)(垂直列にアクセスする)...イテレータは(00)(01)(02)(アクセス水平列)からです。 ..私はstdイテレータを使用することはできません。 (00)*(00)+(10 * 10)+ ..私は、x1、y1、x2、y2を使って行列要素にアクセスするループを使用します。

だから私の質問は(私がやっていることが意味をなさない)イテレータを使わずにstd :: pairの最初と2番目のペアにアクセスするにはどうすればいいですか?

std::map<std::pair<int, int>, double> transpose(
    std::map<std::pair<int, int>, double> const& in 
) { 
    std::map<std::pair<int, int>, double> r; 
    for (auto&& e:in) 
    r[std::make_pair(e.first.second, e.first.first)] = e.second; 
    return r; 
} 

が、これは、ブランドの新しい行列を割り当てる必要があります。

+2

マップ内の要素をトラバースしたい順序で格納するカスタムコンパレータを記述できますか? – NathanOliver

+2

'std :: pair'の最初と2番目の値にアクセスするには、' first'と 'second'クラスのメンバーにアクセスします。 *肩をすくめる。あなたの質問は不明です。 –

+1

この構造の転置繰り返しは、実際には効率的ではありません。要素が存在するかどうかを確認するために、各インデックスのペアを一度に検索する以外の方法はありません。そのため、多くの疎なマトリックス・フレームワークは列ごとのリストを保管しています。しかし、あなたの質問は、あなたの説明に従っていないようです。全体を反復することはできないので、必要な要素を調べなければなりません。それはペアの値にアクセスすることと何が関係していますか? – Peter

答えて

2

これにアプローチする「簡単」な方法はtransposeを書くことです。

もう1つの方法は、マトリックスビューを使用することです。マトリックスビューは次のとおりです。

template<class R> using matrix_func = std::function< R(std::pair<int,int>) >; 
template<class R> 
struct matrix_view_base:matrix_func<R> { 
    std::pair<int, int> dimensions; 
    matrix_view(matrix_func<R> f, std::pair<int, int> d): 
    matrix_func<R>(std::move(f)), 
    dimensions(d) 
    {} 
}; 
using matrix_view = matrix_view_base<double&>; 
using matrix_const_view = matrix_view_base<double>; 

最大サイズの知識で倍精度にマップする関数です。

matrix_view view_of(matrix& m) { 
    return { 
    [&](std::pair<int, int> idx)->double& { 
     return m[idx]; 
    }, 
    // calculate dimensions 
    }; 
} 
matrix_const_view view_of(matrix const& m) { 
    return { 
    [&](std::pair<int, int> idx)->double { 
     auto it = m.find(idx); 
     if (it == m.end()) return 0.0; 
     return *it; 
    }, 
    // calculate dimensions 
    }; 
} 
matrix_const_view const_view_of(matrix const& m) { 
    return view_of(m); 
} 

今、あなただけのマトリックスビューの乗算書く必要があります:景色が言っ生成するために、いくつかの機能を

matrix_view invert(matrix_view in) { 
    return { 
    [in](std::pair<int, int> index)->double& { 
     return in(index.second, index.first); 
    }, 
    in.dimensions 
    }; 
} 
matrix_const_view invert(matrix_const_view in) { 
    return { 
    [in](std::pair<int, int> index)->double { 
     return in(index.second, index.first); 
    }, 
    in.dimensions 
    }; 
} 

matrix_const_view multiply(matrix_const_view lhs, matrix_const_view rhs) { 
    return { 
    [=](std::pair<int,int> idx)->double{ 
     // calculate value at idx using lhs(...) and rhs(...) return values 
    }, 
    // calculate dimensions 
    }; 
} 

私たちは、その後、inteverterを書きますこれは完璧ではありません。なぜなら、完全にあなたは0 2回のルックアップよりも高速です。しかし、考え方は、マトリックスへのビューを表現するビュー・クラスを作成し、そのビューに対する操作を行い、結果を格納する必要があるときには実際のマトリックスに固執するだけです。

これは、転置を安くすることを可能にする。

関連する問題