Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function test_required(f::Function, @nospecialize(TN), @nospecialize(Ts=nothing)
lo, hi = 1/3, nextfloat(2/3)
x = f(TN, lo, hi)
@test typeof(x) <: TN
@test isthick(TN)
@test lo ∈ x
@test hi ∈ x
@test lo ≈ loval(x)
Expand Down
18 changes: 18 additions & 0 deletions docs/src/developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,21 @@ be sure to use `[compat]` bounds to specify the major version number of `ThickNu
## Features provided by subtyping ThickNumber

See the [User API](@ref).

## Implementing the interface without subtyping

Subtype `ThickNumber` to inherit the generic methods in the [User API](@ref).

A type with another supertype can implement the interface by defining [`isthick`](@ref):

```julia
ThickNumbers.isthick(::Type{<:MyType}) = true
```

It must implement [`loval`](@ref), [`hival`](@ref), [`lohi`](@ref), [`basetype`](@ref),
supported arithmetic, and any needed derived methods. These may include [`mid`](@ref),
[`wid`](@ref), [`rad`](@ref), [`mag`](@ref), [`mig`](@ref), [`hull`](@ref),
[`emptyset`](@ref), [`isempty_tn`](@ref), [`isnan_tn`](@ref), [`isinf_tn`](@ref),
[`isfinite_tn`](@ref), and `iszero`.

Use `isthick(x)` to recognize both kinds of implementation.
2 changes: 2 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ You can also check a few basic properties, like whether the values contained in
### Type information

- [`valuetype(X)`](@ref): return the type of numbers contained in `X` (e.g., `Float64`)
- [`isthick(X)`](@ref): return `true` if `X` (or its type) implements the ThickNumbers interface

### Generic constructors

Expand Down Expand Up @@ -92,6 +93,7 @@ For an explanation of why these aren't just `==`, `<`, etc, read [The Fundamenta
- [`issupset_tn`](@ref) replaces `⊇` (unicode: `⫄`)
- [`is_strict_supset_tn`](@ref) replaces `⊃` (unicode: `⪾`)
- [`hull`](@ref) creates a number that contains its arguments
- [`isempty_tn(X)`](@ref) replaces `isempty(X)`

### API reference

Expand Down
2 changes: 2 additions & 0 deletions docs/src/user_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ violate the interface requirements.

```@docs
valuetype
isthick
```

## Query functions
Expand Down Expand Up @@ -54,6 +55,7 @@ See also [IntervalSets](https://github.com/JuliaMath/IntervalSets.jl) for a more
in(::Real, ::ThickNumber)
hull
Base.isempty(::ThickNumber)
isempty_tn
issubset_tn
issupset_tn
is_strict_subset_tn
Expand Down
33 changes: 30 additions & 3 deletions src/ThickNumbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using LinearAlgebra
export ThickNumber, FPTNException

# Traits
export valuetype, basetype
export valuetype, basetype, isthick

# These mimic IEEE Std 1788-2015, Table 9.2, but with `inf` and `sup`
# replaced by names that do not imply true bounds.
Expand All @@ -16,7 +16,7 @@ export valuetype, basetype
export lohi, midrad, loval, hival, mid, wid, rad, mag, mig

# Set operations
export emptyset, hull, issubset_tn, ⫃, is_strict_subset_tn, ⪽, issupset_tn, ⫄, is_strict_supset_tn, ⪾
export emptyset, hull, issubset_tn, ⫃, is_strict_subset_tn, ⪽, issupset_tn, ⫄, is_strict_supset_tn, ⪾, isempty_tn

# Operators
export isequal_tn, iseq_tn, ≐, isapprox_tn, ⩪, isless_tn, ≺, ≻, ⪯, ⪰
Expand Down Expand Up @@ -59,6 +59,26 @@ Float64
valuetype(::Type{TN}) where TN<:ThickNumber{T} where T = T
valuetype(x::ThickNumber) = valuetype(typeof(x))

"""
isthick(::Type{T}) where T
isthick(x)

Return whether a type implements the ThickNumbers interface.

# Default implementation

Subtypes of `ThickNumber` return `true` by default:

isthick(::Type{T}) where T = T <: ThickNumber
isthick(x) = isthick(typeof(x))

Types with another supertype can implement the interface by defining
`isthick(::Type{<:SomeType}) = true`. See [Implementing the interface without
subtyping](@ref).
"""
isthick(::Type{T}) where T = T <: ThickNumber
isthick(x) = isthick(typeof(x))

# Functions that must be defined by subtypes

"""
Expand Down Expand Up @@ -403,12 +423,19 @@ The converse of [`is_strict_subset_tn`](@ref).
is_strict_supset_tn(a::ThickNumber, b::ThickNumber) = is_strict_subset_tn(b, a)
const ⪾ = is_strict_supset_tn

"""
isempty_tn(x::ThickNumber)

Return whether the span of `x` is empty (`hival(x) < loval(x)`).
"""
isempty_tn(x::ThickNumber) = hival(x) < loval(x)

"""
isempty(x::ThickNumber)

Returns `true` if the span of `x` is empty (`hival(x) < loval(x)`), `false` otherwise.
"""
Base.isempty(x::ThickNumber) = hival(x) < loval(x)
Base.isempty(x::ThickNumber) = isempty_tn(x)

function Base.isdisjoint(a::ThickNumber, b::ThickNumber)
(isempty(a) || isempty(b)) && return true
Expand Down
8 changes: 8 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ using MidRadArith
# Test all the operations defined in ThickNumbers
x, y = Interval(1.0, 3.0), Interval(-1.0, 3.0)
@test valuetype(x) === valuetype(typeof(x)) === Float64
@test !isthick(Float64)
@test !isthick(3.0)
@test isthick(Interval{Float64})
@test isthick(x)
@test loval(x) === 1.0
@test hival(x) === 3.0
@test mid(x) === 2.0
Expand Down Expand Up @@ -105,6 +109,10 @@ using MidRadArith
@test emptyset(Interval{Float32}) === Interval(Inf32, -Inf32)
@test emptyset(Interval{Float64}) === Interval(Inf, -Inf)
@test emptyset(Interval(1.0, 2.0)) === Interval(Inf, -Inf)
@test isempty_tn(emptyset(Interval{Float64}))
@test !isempty_tn(x)
@test isempty(x) == isempty_tn(x)
@test isempty(emptyset(Interval{Float64})) == isempty_tn(emptyset(Interval{Float64}))
@test isfinite_tn(Interval(1, 2))
@test_throws FPTNException isfinite(Interval(1, 2))
@test !isfinite_tn(Interval(1, Inf))
Expand Down
Loading