2017-02-14 5 views
3

私はJuliaにいくつかの特別に定義された配列を持っています。これは多くの配列の単なる構成であると考えることができます。たとえば、次のように`setindex! 'のイテレーション

type CompositeArray{T} 
    x::Vector{T} 
    y::Vector{T} 
end 

インデックス方式に

getindex(c::CompositeArray,i::Int) = i <= length(c) ? c.x[i] : c.y[i-length(c.x)] 

私が持っている1つの警告:

getindex(c::CompositeArray,i::Int...) = c.x[i...] 

イテレータこれらのことが可能通じ:高いインデックス方式はちょうどx自体に行きますxのイテレータのチェーンとして簡単に作成し、次にyを作成します。これは、値を反復することで、ほとんど追加コストがかからなくなります。しかし、反復のために何か同様のことをsetindex!にすることはできますか?

私はy対ちょうどインデックスxためCartesianIndex{2}上の別々の発送とインデックスを持つことを考えて、どのようなCatViews.jl doesに似ているためeachindexイテレータを、構築されました。しかし、私はそれがi...ディスパッチとどのように相互作用するか、またはこの場合に役立つかどうかはわかりません。

さらに、ブロードキャストは、eachindex上に構築されている場合、この高速反復スキームを自動的に使用しますか?

編集:

実場合
length(c::CompositeArray) = length(c.x) + length(c.y) 

xができる任意AbstractArray(従って、線形インデックスを有する)が、唯一のため線形インデックスは、一人のユーザに面するgetindex機能を除いて(使用され)、問題は実際にベクトルをxでこれを行う方法を見つけることに本当に沸騰します。

+0

'length(c)'の定義は自然なものですが、 'i> length(c.x)+ length(c.y)'のときに 'getindex(c、i)'を実行するとどうなりますか?さらに、 'c.x [i ...]'は奇妙です。なぜなら、 'c.x'は次元1のベクトルですからです。あなたは質問をより明確にすることができますか? –

+0

ああ、インデックス作成にエラーがありました。一定。 –

答えて

7

X[CartesianIndex(2,1)]とは、X[2,1]とは異なる意味のものですが、確かにうまくいっていません。そして、私はX[100,1]X[100]と異なる何かを意味するかもしれないという事実、またはlength(X) != prod(size(X))であるという事実から、同様の問題を予想しています。あなたは自由にルールを破ることができますが、Baseや他のパッケージの関数があなたに従うことを期待すると、驚くべきではありません。

これを行うには、eachindex(::CompositeArray)を完全に制御するオブジェクトに対してカスタムイテレータを返すようにするのが安全な方法です。そのデータ構造が役立つ場合は、ラッパーを回してCartesianRangeCartesianIndex{2}に転送してください。次に、これらのカスタムインデックスタイプのいずれかを取得すると、SplitIndex(CartesianIndex(1,2))が実際に2番目の配列の最初の要素を参照しようとしていることがわかります。

+0

ああ、私は参照してください。 "これを行う安全な方法は、eachindex(:: CompositeArray)が完全に制御するオブジェクトに対してカスタムイテレータを返すようにすることです。"これにより、その型の不変の新しいgetindexを作成し、 'eachindex'でそれを使用することを意味しますか?それはうまくいくように聞こえる。 –

+0

うん、まさに。 - –

関連する問題