Skip to content

Commit

Permalink
getting closer to JuliaLang/julia#7568
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonDanisch committed Jan 31, 2015
1 parent 9216430 commit 2e8fec6
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 22 deletions.
8 changes: 8 additions & 0 deletions src/FixedSizeArrays.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module FixedSizeArrays

include("core.jl")
include("staged.jl")
include("ops.jl")
include("array_of_fixedsize.jl")

end
37 changes: 27 additions & 10 deletions src/WIP/bench1.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
immutable FixedUnitRange{From, To} end
immutable FixedStepRange{From, Step, To} end
immutable LOL
x::Float32
abstract FixedSizeVector{T, N}

gen_fixedsizevector_type(name::DataType, T::Symbol, N::Int) = gen_fixedsizevector_type(symbol(string(name.name.name)), T, N)
function gen_fixedsizevector_type(name::Symbol, T::Symbol, N::Int)
fields = [Expr(:(::), symbol("I_$i"), T) for i = 1:N]
typename = symbol("FS$name")
eval(quote
immutable $(typename){$T} <: $(name){$T}
$(fields...)
end
end)
typename
end
Base.endof(a::LOL) = 1
Base.getindex{From, To}(a::LOL, b::FixedUnitRange{From, To}) = println(From, " ", To)
Base.getindex(a::LOL, b::UnitRange) = a[FixedUnitRange{first(b), last(b)}()]
a(x::Colon) = println(x)
a(:)
LOL(1f0)[:]

stagedfunction Base.call{T <: FixedSizeVector, ET}(t::Type{T}, data::ET...)
Tsuper, Nsuper = super(T).parameters
N = length(data)
@assert Nsuper == N "not the right dimension"
typename = gen_fixedsizevector_type(T, symbol(string(Tsuper.name)), N)
original_typename = t.name.name
:($(original_typename)($(typename)(data...)))
end

immutable LOL{T <: FixedSizeVector{Real, 3}} <: FixedSizeVector{Real, 3}
data::T
end

@show LOL(1,2,3)
6 changes: 0 additions & 6 deletions src/array_of_fixedsize.jl
Original file line number Diff line number Diff line change
@@ -1,6 +0,0 @@
immutable IMax <: Base.Func{2} end
call(::IMax, x, y) = max(x,y)
immutable IMin <: Base.Func{2} end
call(::IMin, x, y) = min(x,y)
Base.maximum{T}(v::Vector{Vector3{T}}) = reduce(IMax(), Vector3(typemin(T)), v)
Base.minimum{T}(v::Vector{Vector3{T}}) = reduce(IMin(), Vector3(typemax(T)), v)
29 changes: 27 additions & 2 deletions src/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ done (A::AbstractFixedArray, state::Integer) = length(A) < state


getindex (A::AbstractFixedArray, i::Real) = A.(i)
getindex{T,M,N} (A::AbstractFixedArray{T, M, N}, i::Real, j::Real) = A.(sub2ind((M,N), i, j))
getindex{T,SZ} (A::AbstractFixedArray{T, 2, SZ}, i::Real, j::Real) = A.(sub2ind(SZ, i, j))
getindex{T,SZ} (A::AbstractFixedArray{T, 3, SZ}, i::Real, j::Real, k::Real) = A.(sub2ind(SZ, i, j, k))
getindex{T,N,SZ}(A::AbstractFixedArray{T, N, SZ}, i::Real, j::Real, k::Real, inds::Real...) = A.(sub2ind(SZ, i, j, k, inds...))

Expand All @@ -63,7 +63,7 @@ function show{T <: AbstractFixedVector}(io::IO, F::T)
end)
println(io, "]")
end
function show{T <: AbstractFixedMatrix}(io::IO, F::T)
#=function show{T <: AbstractFixedMatrix}(io::IO, F::T)
println(io, T, "[")
for i=1:size(F, 1)
tmp = row(F, i)
Expand All @@ -73,7 +73,32 @@ function show{T <: AbstractFixedMatrix}(io::IO, F::T)
println(io, "")
end
println(io, "]")
end=#

#=
stagedfunction call{T <: FixedSizeVector, N, ET}(t::Type{T}, data::ET...)
Tsuper, Nsuper = super(T).parameters
@assert Nsuper == N "not the right dimension"
typename = gen_fixedsizevector_type(T, Tsuper.name, N)
:($typename(data...))
end
gen_fixedsizevector_type(name::DataType, T::Symbol, N::Int) = gen_fixedsizevector_type(symbol(string(name.name.name)), T, N)
function gen_fixedsizevector_type(name::Symbol, T::Symbol, N::Int)
fields = [Expr(:(::), symbol("I_$i"), T) for i = 1:N]
typename = symbol("FS$name")
eval(quote
immutable $(typename){$T} <: $(name){$T}
$(fields...)
end
end)
typename
end
Base.call{FS <: AbstractFixedSizeArray, T, N}(::Type{FS}, a::Array{T, N}) = AbstractFixedSizeArray{T, N, size(a)}(a...)
Base.call{FS <: AbstractFixedSizeArray, T, N}(::Type{FS}, a::Array{T, N}) = AbstractFixedSizeArray{T, N, size(a)}(a...)
nvec{T, N}(x::Array{T,N}) = AbstractFixedSizeArray(x)
=#
44 changes: 40 additions & 4 deletions src/ops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,16 @@ function convert{T1 <: AbstractFixedArray, T2 <: AbstractFixedArray}(a::Type{T1}
@assert sizeof(a) == sizeof(b) "Type $a ($(sizeof(a))) doesn't have the same bit size as type $b ($(sizeof(b)))"
reinterpret(a, [b])[1]
end


dot(a::AbstractFixedVector, b::AbstractFixedVector) = sum(a.*b)
function convert{T1 <: AbstractFixedArray, T2 <: AbstractFixedArray}(a::Type{T1}, b::Array{T2})
@assert sizeof(b) % sizeof(a) == 0 "Type $a ($(sizeof(a))) doesn't have the same bit size as type $b ($(sizeof(b)))"
println(a)
reinterpret(a, b, (div(sizeof(b), sizeof(a)),))
end


dot(a::AbstractFixedVector, b::AbstractFixedVector) = sum(a.*b)

# Matrix
stagedfunction (*){T, M, N, K}(a::AbstractFixedMatrix{T, M, N}, b::AbstractFixedMatrix{T, N, K})
Expand All @@ -98,13 +100,42 @@ immutable Vec3{T} <: AbstractFixedVector{T, 3}
y::T
z::T
end
immutable Vec4{T} <: AbstractFixedVector{T, 4}
x::T
y::T
z::T
w::T
end
immutable Vec2{T} <: AbstractFixedVector{T, 2}
x::T
y::T
end
a = RGB(1f0,2f0,3f0)

immutable Mat4x4{T} <: AbstractFixedMatrix{T, 4,4}
c1::T
c2::T
c3::T
c4::T
c5::T
c6::T
c7::T
c8::T
c9::T
c10::T
c11::T
c12::T
c13::T
c14::T
c15::T
c16::T
end

dot(a::RGB, b::RGB) = a.r*b.r + a.g*b.g + a.b*b.b


const a = RGB(1f0,2f0,3f0)
b = RGB(7f0,3f0,0f0)
c = Vec3(7f0,3f0,0f0)
const c = Vec3(7f0,3f0,0f0)
println(a+a)
println(max(a,b))
println(maximum(a))
Expand All @@ -114,5 +145,10 @@ println(rand(RGB{Float32}))
@show convert(Vec3{Float32}, a)
@show convert(RGB{Float32}, c)
@show convert(RGB{Float32}, Vec3{Float32}[c for i=1:10])
@show dot(a,a)

@show const A = Mat4x4(ntuple(x->float32(x), 16)...)
@show const p = Vec4(1f0,2f0,4f0,1f0)
@show A[1,2]
@show A*A

@show b[RGB(1,1,1)]
78 changes: 78 additions & 0 deletions src/wip.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
mportall Base

abstract FixedSizeArray{T, SZ, N}
abstract FixedSizeVector{T, N} <: FixedSizeArray{T, (N,), 1}

#Constructor
call{T <: FixedSizeVector, ET}(t::Type{T}, data::ET...) = t(ntuple(x->data[x], length(data)))
stagedfunction call{T <: FixedSizeVector, N, ET}(t::Type{T}, data::NTuple{N, ET})
Tsuper, Nsuper = super(T).parameters
@assert Nsuper == N "not the right dimension"
typename = gen_fixedsizevector_type(T, Tsuper.name, N)
:($typename(data...))
end
gen_fixedsizevector_type(name::DataType, T::Symbol, N::Int) = gen_fixedsizevector_type(symbol(string(name.name.name)), T, N)
function gen_fixedsizevector_type(name::Symbol, T::Symbol, N::Int)
fields = [Expr(:(::), symbol("I_$i"), T) for i = 1:N]
typename = symbol("FS$name")
eval(quote
immutable $(typename){$T} <: $(name){$T}
$(fields...)
end
end)
typename
end

# Usual functions
getindex{T <: FixedSizeVector}(c::T, i::Int) = c.(i)
# Ugly workaround for not having triangular dispatch:
eltype{T <: FixedSizeVector}(A::Type{T}) = A.types[1]
length{T <: FixedSizeVector}(A::Type{T}) = length(A.types)
ndims{T <: FixedSizeVector}(A::Type{T}) = 1
size{T <: FixedSizeVector}(A::Type{T}) = (length(A),)
size{T <: FixedSizeVector}(A::Type{T}, d::Integer) = (length(A),) # should throw an error!?

# The usual vector functions
abstract Func{Name, N}
stagedfunction map{T <: FixedSizeVector}(f::Func{1}, a::T)
typename = symbol("$(a.name.name)")
arguments = [:(f(a.($i))) for i=1:length(T)]
:($typename($(arguments...)))
end
stagedfunction map{T <: FixedSizeVector, FName}(f::Func{FName, 2}, a::T, b::T)
typename = symbol("$(a.name.name)")
arguments = [:($FName(a.($i), b.($i))) for i=1:length(T)]
:($typename($(arguments...)))
end

const binaryOps = (:.+, :.-,:.*, :./, :.\, :.^,:*,:/,
:.==, :.!=, :.<, :.<=, :.>, :.>=, :+, :-,
:min, :max,
:div, :fld, :rem, :mod, :mod1, :cmp,
:atan2, :besselj, :bessely, :hankelh1, :hankelh2,
:besseli, :besselk, :beta, :lbeta)
for op in binaryOps
const unicsymb = gensym()
eval(quote
immutable $unicsymb <: Func{symbol(string($op)), 2} end
$op{T <: FixedSizeVector}(x::T, y::T) = map($unicsymb(), x, y)
end)
end

# Some syntactic sugar for accessing named dimensions
abstract Dimension{T} <: Number
stagedfunction getindex{FT <: FixedSizeVector, T <: Dimension}(a::FT, key::Type{T})
index = fieldindex(a, T)
:(T(a[$index]))
end
macro accessors(typ, fields)
result = Any[]
for elem in fields.args
push!(result, quote
fieldindex{T <: $typ}(::Type{T}, ::Type{$(elem.args[1])}) = $(elem.args[2])
end)
end
esc(Expr(:block, result...))
end


68 changes: 68 additions & 0 deletions test/ops.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using FixedSizeArrays


square(x) = x*x

const unaryOps = (-, ~, conj, abs,
sin, cos, tan, sinh, cosh, tanh,
asin, acos, atan, asinh, acosh, atanh,
sec, csc, cot, asec, acsc, acot,
sech, csch, coth, asech, acsch, acoth,
sinc, cosc, cosd, cotd, cscd, secd,
sind, tand, acosd, acotd, acscd, asecd,
asind, atand, radians2degrees, degrees2radians,
log, log2, log10, log1p, exponent, exp,
exp2, expm1, cbrt, sqrt, square, erf,
erfc, erfcx, erfi, dawson, ceil, floor,
trunc, round, significand, lgamma, hypot,
gamma, lfact, frexp, modf, airy, airyai,
airyprime, airyaiprime, airybi, airybiprime,
besselj0, besselj1, bessely0, bessely1,
eta, zeta, digamma)

# vec-vec and vec-scalar
const binaryOps = (.+, .-,.*, ./, .\, .^,*,/,
.==, .!=, .<, .<=, .>, .>=, +, -,
min, max,
div, fld, rem, mod, mod1, cmp,
atan2, besselj, bessely, hankelh1, hankelh2,
besseli, besselk, beta, lbeta)

const reductions = (sum, prod, minimum,(maximum)
testresult = Dict{Function, Any}()

function Base.filter(fun, x...)
result = []
@assert length(unique(map(length, x))) == 1 "all iterables need to have the same length. Lengths given: $(map(length, x))"
for i=1:length(x[1])
args = ntuple(j-> x[j][i], length(x))
fun(args...) && push!(result, args)
end
result
end

@show filter(!=, [2,3,4,5], [2,1,4,7])

Base.call{FS <: AbstractFixedSizeArray, T, N}(::Type{FS}, a::Array{T, N}) = AbstractFixedSizeArray{T, N, size(a)}(a...)
Base.call{FS <: AbstractFixedSizeArray, T, N}(::Type{FS}, a::Array{T, N}) = AbstractFixedSizeArray{T, N, size(a)}(a...)



nvec{T, N}(x::Array{T,N}) = AbstractFixedSizeArray(x)


function testunaray()
baseline = Any[rand(2), rand(3), rand(3,7), rand(7,2), rand(Float32, 4, 1), rand(Float32, 4), rand(Float64, 4,4)]
test = map(nvec, baseline)
for op in unaryOps
baeline_result = map(op, baseline)
test_result = map(op, test)

if all(map(==, baeline_result, test_result))
testresult[op] = "passed"
else
testresult[op] = ["didn't pass: ", filter(!=, baseline_result, test_result)]
end
end

end

0 comments on commit 2e8fec6

Please sign in to comment.