fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
This commit is contained in:
298
julia-0.6.3/share/julia/base/linalg/bitarray.jl
Normal file
298
julia-0.6.3/share/julia/base/linalg/bitarray.jl
Normal file
@@ -0,0 +1,298 @@
|
||||
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
||||
|
||||
function dot(x::BitVector, y::BitVector)
|
||||
# simplest way to mimic Array dot behavior
|
||||
length(x) == length(y) || throw(DimensionMismatch())
|
||||
s = 0
|
||||
xc = x.chunks
|
||||
yc = y.chunks
|
||||
@inbounds for i = 1:length(xc)
|
||||
s += count_ones(xc[i] & yc[i])
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
## slower than the unpacked version, which is MUCH slower
|
||||
# than blas'd (this one saves storage though, keeping it commented
|
||||
# just in case)
|
||||
#function aTb(A::BitMatrix, B::BitMatrix)
|
||||
#(mA, nA) = size(A)
|
||||
#(mB, nB) = size(B)
|
||||
#C = falses(nA, nB)
|
||||
#if mA != mB; throw(DimensionMismatch()) end
|
||||
#if mA == 0; return C; end
|
||||
#col_ch = num_bit_chunks(mA)
|
||||
## TODO: avoid using aux chunks and copy (?)
|
||||
#aux_chunksA = zeros(UInt64, col_ch)
|
||||
#aux_chunksB = [zeros(UInt64, col_ch) for j=1:nB]
|
||||
#for j = 1:nB
|
||||
#Base.copy_chunks!(aux_chunksB[j], 1, B.chunks, (j-1)*mA+1, mA)
|
||||
#end
|
||||
#for i = 1:nA
|
||||
#Base.copy_chunks!(aux_chunksA, 1, A.chunks, (i-1)*mA+1, mA)
|
||||
#for j = 1:nB
|
||||
#for k = 1:col_ch
|
||||
## TODO: improve
|
||||
#C[i, j] += count_ones(aux_chunksA[k] & aux_chunksB[j][k])
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#C
|
||||
#end
|
||||
|
||||
#aCb{T, S}(A::BitMatrix{T}, B::BitMatrix{S}) = aTb(A, B)
|
||||
|
||||
function triu(B::BitMatrix, k::Integer=0)
|
||||
m,n = size(B)
|
||||
A = falses(m,n)
|
||||
Ac = A.chunks
|
||||
Bc = B.chunks
|
||||
for i = max(k+1,1):n
|
||||
j = clamp((i - 1) * m + 1, 1, i * m)
|
||||
Base.copy_chunks!(Ac, j, Bc, j, min(i-k, m))
|
||||
end
|
||||
A
|
||||
end
|
||||
|
||||
function tril(B::BitMatrix, k::Integer=0)
|
||||
m,n = size(B)
|
||||
A = falses(m, n)
|
||||
Ac = A.chunks
|
||||
Bc = B.chunks
|
||||
for i = 1:min(n, m+k)
|
||||
j = clamp((i - 1) * m + i - k, 1, i * m)
|
||||
Base.copy_chunks!(Ac, j, Bc, j, max(m-i+k+1, 0))
|
||||
end
|
||||
A
|
||||
end
|
||||
|
||||
## diff and gradient
|
||||
|
||||
# TODO: this could be improved (is it worth it?)
|
||||
gradient(F::BitVector) = gradient(Array(F))
|
||||
gradient(F::BitVector, h::Real) = gradient(Array(F), h)
|
||||
gradient(F::Vector, h::BitVector) = gradient(F, Array(h))
|
||||
gradient(F::BitVector, h::Vector) = gradient(Array(F), h)
|
||||
gradient(F::BitVector, h::BitVector) = gradient(Array(F), Array(h))
|
||||
|
||||
## diag and related
|
||||
|
||||
function diag(B::BitMatrix)
|
||||
n = minimum(size(B))
|
||||
v = similar(B, n)
|
||||
for i = 1:n
|
||||
v[i] = B[i,i]
|
||||
end
|
||||
v
|
||||
end
|
||||
|
||||
function diagm(v::Union{BitVector,BitMatrix})
|
||||
isa(v, BitMatrix) && size(v,1)==1 || size(v,2)==1 || throw(DimensionMismatch())
|
||||
n = length(v)
|
||||
a = falses(n, n)
|
||||
for i=1:n
|
||||
a[i,i] = v[i]
|
||||
end
|
||||
a
|
||||
end
|
||||
|
||||
## norm and rank
|
||||
|
||||
svd(A::BitMatrix) = svd(float(A))
|
||||
qr(A::BitMatrix) = qr(float(A))
|
||||
|
||||
## kron
|
||||
|
||||
function kron(a::BitVector, b::BitVector)
|
||||
m = length(a)
|
||||
n = length(b)
|
||||
R = falses(n * m)
|
||||
Rc = R.chunks
|
||||
bc = b.chunks
|
||||
for j = 1:m
|
||||
a[j] && Base.copy_chunks!(Rc, (j-1)*n+1, bc, 1, n)
|
||||
end
|
||||
R
|
||||
end
|
||||
|
||||
function kron(a::BitMatrix, b::BitMatrix)
|
||||
mA,nA = size(a)
|
||||
mB,nB = size(b)
|
||||
R = falses(mA*mB, nA*nB)
|
||||
|
||||
for i = 1:mA
|
||||
ri = (1:mB)+(i-1)*mB
|
||||
for j = 1:nA
|
||||
if a[i,j]
|
||||
rj = (1:nB)+(j-1)*nB
|
||||
R[ri,rj] = b
|
||||
end
|
||||
end
|
||||
end
|
||||
R
|
||||
end
|
||||
|
||||
## Structure query functions
|
||||
|
||||
issymmetric(A::BitMatrix) = size(A, 1)==size(A, 2) && countnz(A - A.')==0
|
||||
ishermitian(A::BitMatrix) = issymmetric(A)
|
||||
|
||||
function nonzero_chunks(chunks::Vector{UInt64}, pos0::Int, pos1::Int)
|
||||
k0, l0 = Base.get_chunks_id(pos0)
|
||||
k1, l1 = Base.get_chunks_id(pos1)
|
||||
|
||||
delta_k = k1 - k0
|
||||
|
||||
z = UInt64(0)
|
||||
u = ~z
|
||||
if delta_k == 0
|
||||
msk_0 = (u << l0) & ~(u << l1 << 1)
|
||||
else
|
||||
msk_0 = (u << l0)
|
||||
msk_1 = ~(u << l1 << 1)
|
||||
end
|
||||
|
||||
@inbounds begin
|
||||
(chunks[k0] & msk_0) == z || return true
|
||||
delta_k == 0 && return false
|
||||
for i = k0 + 1 : k1 - 1
|
||||
chunks[i] == z || return true
|
||||
end
|
||||
(chunks[k1] & msk_1)==z || return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function istriu(A::BitMatrix)
|
||||
m, n = size(A)
|
||||
for j = 1:min(n,m-1)
|
||||
stride = (j-1) * m
|
||||
nonzero_chunks(A.chunks, stride+j+1, stride+m) && return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function istril(A::BitMatrix)
|
||||
m, n = size(A)
|
||||
(m == 0 || n == 0) && return true
|
||||
for j = 2:n
|
||||
stride = (j-1) * m
|
||||
nonzero_chunks(A.chunks, stride+1, stride+min(j-1,m)) && return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function findmax(a::BitArray)
|
||||
isempty(a) && throw(ArgumentError("BitArray must be non-empty"))
|
||||
m, mi = false, 1
|
||||
ti = 1
|
||||
ac = a.chunks
|
||||
for i = 1:length(ac)
|
||||
@inbounds k = trailing_zeros(ac[i])
|
||||
ti += k
|
||||
k == 64 || return (true, ti)
|
||||
end
|
||||
return m, mi
|
||||
end
|
||||
|
||||
function findmin(a::BitArray)
|
||||
isempty(a) && throw(ArgumentError("BitArray must be non-empty"))
|
||||
m, mi = true, 1
|
||||
ti = 1
|
||||
ac = a.chunks
|
||||
for i = 1:length(ac)-1
|
||||
@inbounds k = trailing_ones(ac[i])
|
||||
ti += k
|
||||
k == 64 || return (false, ti)
|
||||
end
|
||||
l = Base._mod64(length(a)-1) + 1
|
||||
@inbounds k = trailing_ones(ac[end] & Base._msk_end(l))
|
||||
ti += k
|
||||
k == l || return (false, ti)
|
||||
return m, mi
|
||||
end
|
||||
|
||||
# fast 8x8 bit transpose from Henry S. Warrens's "Hacker's Delight"
|
||||
# http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt
|
||||
function transpose8x8(x::UInt64)
|
||||
y = x
|
||||
t = xor(y, y >>> 7) & 0x00aa00aa00aa00aa
|
||||
y = xor(y, t, t << 7)
|
||||
t = xor(y, y >>> 14) & 0x0000cccc0000cccc
|
||||
y = xor(y, t, t << 14)
|
||||
t = xor(y, y >>> 28) & 0x00000000f0f0f0f0
|
||||
return xor(y, t, t << 28)
|
||||
end
|
||||
|
||||
function form_8x8_chunk(Bc::Vector{UInt64}, i1::Int, i2::Int, m::Int, cgap::Int, cinc::Int, nc::Int, msk8::UInt64)
|
||||
x = UInt64(0)
|
||||
|
||||
k, l = Base.get_chunks_id(i1 + (i2 - 1) * m)
|
||||
r = 0
|
||||
for j = 1:8
|
||||
k > nc && break
|
||||
x |= ((Bc[k] >>> l) & msk8) << r
|
||||
if l + 8 >= 64 && nc > k
|
||||
r0 = 8 - Base._mod64(l + 8)
|
||||
x |= (Bc[k + 1] & (msk8 >>> r0)) << (r + r0)
|
||||
end
|
||||
k += cgap + (l + cinc >= 64 ? 1 : 0)
|
||||
l = Base._mod64(l + cinc)
|
||||
r += 8
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
# note: assumes B is filled with 0's
|
||||
function put_8x8_chunk(Bc::Vector{UInt64}, i1::Int, i2::Int, x::UInt64, m::Int, cgap::Int, cinc::Int, nc::Int, msk8::UInt64)
|
||||
k, l = Base.get_chunks_id(i1 + (i2 - 1) * m)
|
||||
r = 0
|
||||
for j = 1:8
|
||||
k > nc && break
|
||||
Bc[k] |= ((x >>> r) & msk8) << l
|
||||
if l + 8 >= 64 && nc > k
|
||||
r0 = 8 - Base._mod64(l + 8)
|
||||
Bc[k + 1] |= ((x >>> (r + r0)) & (msk8 >>> r0))
|
||||
end
|
||||
k += cgap + (l + cinc >= 64 ? 1 : 0)
|
||||
l = Base._mod64(l + cinc)
|
||||
r += 8
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
function transpose(B::BitMatrix)
|
||||
l1 = size(B, 1)
|
||||
l2 = size(B, 2)
|
||||
Bt = falses(l2, l1)
|
||||
|
||||
cgap1, cinc1 = Base._div64(l1), Base._mod64(l1)
|
||||
cgap2, cinc2 = Base._div64(l2), Base._mod64(l2)
|
||||
|
||||
Bc = B.chunks
|
||||
Btc = Bt.chunks
|
||||
|
||||
nc = length(Bc)
|
||||
|
||||
for i = 1:8:l1
|
||||
msk8_1 = UInt64(0xff)
|
||||
if (l1 < i + 7)
|
||||
msk8_1 >>>= i + 7 - l1
|
||||
end
|
||||
|
||||
for j = 1:8:l2
|
||||
x = form_8x8_chunk(Bc, i, j, l1, cgap1, cinc1, nc, msk8_1)
|
||||
x = transpose8x8(x)
|
||||
|
||||
msk8_2 = UInt64(0xff)
|
||||
if (l2 < j + 7)
|
||||
msk8_2 >>>= j + 7 - l2
|
||||
end
|
||||
|
||||
put_8x8_chunk(Btc, j, i, x, l2, cgap2, cinc2, nc, msk8_2)
|
||||
end
|
||||
end
|
||||
return Bt
|
||||
end
|
||||
|
||||
ctranspose(B::Union{BitMatrix,BitVector}) = transpose(B)
|
||||
Reference in New Issue
Block a user