Skip to content

Commit

Permalink
Redesign and other improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
scheinerman committed Jul 5, 2020
1 parent 73b7439 commit b27aeac
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Bijections"
uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04"
version = "0.1.0"
version = "0.1.1"

[compat]
julia = "1"
Expand Down
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ There are two functions that take a `Bijection` and return a new
`Bijection` that is the functional inverse of the original:
`inv` and `active_inv`.

#### Independent inverse: `inv`
### Independent inverse: `inv`
Given a `Bijection` `b`, calling `inv(b)` creates a new `Bijection`
that is an inverse of `b`. The new `Bijection` is completely independent
of the original, `b`. Changes to one do *not* affect the other:
that is the inverse of `b`. The new `Bijection` is completely independent
of the original, `b`. Changes to one do not affect the other:
```
julia> b = Bijection{Int,String}()
Bijection{Int64,String} (with 0 pairs)
Expand All @@ -135,7 +135,7 @@ julia> bb["gamma"]
ERROR: KeyError: key "gamma" not found
```

#### Active inverse: `active_inv`
### Active inverse: `active_inv`

The `active_inv` function also creates an inverse `Bijection`, but in this
case the original and the inverse are actively tied together.
Expand All @@ -160,6 +160,18 @@ julia> bb["gamma"]
3
```

## Iteration

`Bijection`s can be used in a `for` statement just like Julia
dictionaries:
```
julia> for (x,y) in b; println("$x --> $y"); end
2 --> beta
3 --> gamma
1 --> alpha
```



## Inspection

Expand Down Expand Up @@ -196,7 +208,3 @@ contains no pairs:
julia> isempty(b)
false
```

## To do list

* A `Bijection` ought to be iterable, but that's not implemented yet.
25 changes: 21 additions & 4 deletions src/Bijections.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
module Bijections

import Base.delete!, Base.length
import Base.isempty, Base.collect, Base.setindex!, Base.getindex
import Base.show, Base.display, Base.==
import Base: delete!, length, isempty, collect, setindex!, getindex
import Base: show, display, ==, iterate

# import Base.isempty, Base.collect, Base.setindex!, Base.getindex
# import Base.show, Base.display, Base.==

export Bijection, setindex!, getindex, inverse, length
export isempty, collect, domain, image, show, display

mutable struct Bijection{S,T} <: AbstractDict{S,T}
struct Bijection{S,T} <: AbstractDict{S,T}
domain::Set{S} # domain of the bijection
range::Set{T} # range of the bijection
f::Dict{S,T} # map from domain to range
finv::Dict{T,S} # inverse map from range to domain

# standard constructor
function Bijection{S,T}() where {S,T}
D = Set{S}()
R = Set{T}()
F = Dict{S,T}()
G = Dict{T,S}()
new(D,R,F,G)
end

# private, unsafe constructor
function Bijection{S,T}(D::Set{S},R::Set{T},F::Dict{S,T},G::Dict{T,S}) where {S,T}
new(D,R,F,G)
end
end

# Default constructor is a bijection from Any to Any
Expand Down Expand Up @@ -135,6 +144,14 @@ domain(b::Bijection) = copy(b.domain)
image(b::Bijection) = copy(b.range)


iterate(b::Bijection{S,T},s::Int) where {S,T} = iterate(b.f,s)
iterate(b::Bijection{S,T}) where {S,T} = iterate(b.f)

# convert a Bijection into a Dict; probably not useful
Dict(b::Bijection) = copy(b.f)



include("inversion.jl")

end # end of module Bijections
10 changes: 2 additions & 8 deletions src/inversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ See also `active_inv`.
"""
function inv(b::Bijection{S,T}) where {S,T}
bb = Bijection{T,S}()
for x in b.domain
y = b[x]
for (x,y) in b
bb[y] = x
end
return bb
Expand All @@ -29,10 +28,5 @@ perpetuity.
See also `inv`.
"""
function active_inv(b::Bijection{S,T}) where {S,T}
bb = Bijection{T,S}()
bb.domain = b.range
bb.range = b.domain
bb.f = b.finv
bb.finv = b.f
return bb
return Bijection{T,S}(b.range, b.domain, b.finv, b.f)
end
8 changes: 8 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,11 @@ bb = active_inv(b)
b[0] = "Ciao"
@test bb["Ciao"] == 0
@test inv(bb) == b

# iteration test
dom_list = [x for (x,y) in b]
@test Set(dom_list) == domain(b)

# conversion to a Dict
d = Dict(b)
@test d[0] == b[0]

0 comments on commit b27aeac

Please sign in to comment.