2017-04-21 13 views
3

2つの配列が同じメモリブロックを指しているかどうかをテストするにはどうすればよいですか? 例えば、私はこのように働くだろう機能fooたい:2つの配列が同じメモリブロックを共有しているかどうかをテストする方法は?

a = rand(10) # Float64 array with 10 elements 
b = copy(a) # b == a is true, but b === a is false 
ar = reinterpret(Float32,a) 
foo(ar,a) # I'd like this to return true 
foo(reinterpret(Float64,ar),b) # I'd like this to return false, even if reinterpret(Float64,ar) == b 

を私はreinterpret(Float64,ar) === aをテストしてみたが、それはfalseを返します。

サブアレイの場合、これはparent(subofA) === Aによって実現され、trueを返します。しかし、私は再解釈された配列に対して同じ結果を引き起こす可能性があります。

答えて

7

reinterpretは同じメモリブロックの型解釈を変更するだけなので、解決策はポインタを比較することです:foo(x,y) = pointer(x) == pointer(y)

4

A少しより堅牢なソリューションです:

data_id(A::StridedArray) = A === parent(A) ? UInt(pointer(A)) : data_id(parent(A)) 
data_id(A::AbstractArray) = A === parent(A) ? object_id(A) : data_id(parent(A)) 
might_share_data(A, B) = data_id(A) == data_id(B) 

これはまだArrayを比較するために、ポインタを使用しますが、それはまた、最初の要素がオフセットされたサブアレイを処理します。ただ、いくつかの偽陰性を持つことになりますpointer Sを比較するのに対し

julia> A = rand(3,4) 
     B = view(A, 2:3, 2:3); 

julia> pointer(A) == pointer(B) 
false 

julia> might_share_data(A, B) 
true 

、この方法は、いくつかの偽陽性を持っています。このアプローチはの配列タイプでも有効です。いくつかの配列はポインタを実装せず、使用しようとするとエラーをスローします。

julia> C = view(A, [2,3], [2,3]); 

julia> pointer(C) 
ERROR: conversion to pointer not defined for SubArray{Float64,2,Array{Float64,2},Tuple{Array{Int64,1},Array{Int64,1}},false} 
in pointer(::SubArray{Float64,2,Array{Float64,2},Tuple{Array{Int64,1},Array{Int64,1}},false}) at ./abstractarray.jl:736 

julia> might_share_data(A, C) 
true 
+2

これは、実際にはこれを行うための機能が必要なほど複雑です。 – StefanKarpinski

関連する問題