Skip to content

Commit

Permalink
Add integer powers (JuliaIntervals#7)
Browse files Browse the repository at this point in the history
* ValidatedNumerics -> IntervalArithmetic

* Add powers and tests

* Rewrite tests for small powers / range

* Update appveyor.yml
  • Loading branch information
dpsanders authored Apr 25, 2019
1 parent e7dfbcb commit ceb2031
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 40 deletions.
8 changes: 7 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ version = "0.1.0"
[deps]
IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
IntervalArithmetic = "≥ 0.15.0"
julia = "≥ 1.0.0"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"

[targets]
test = ["Test", "Polynomials"]
39 changes: 24 additions & 15 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
environment:
matrix:
- JULIAVERSION: "julialang/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
- JULIAVERSION: "julialang/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe"
- julia_version: 1
- julia_version: 1.1
- julia_version: nightly

platform:
- x86 # 32-bit
- x64 # 64-bit

# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
# matrix:
# allow_failures:
# - julia_version: nightly

branches:
only:
Expand All @@ -17,18 +26,18 @@ notifications:
on_build_status_changed: false

install:
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$("http://s3.amazonaws.com/"+$env:JULIAVERSION),
"C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))

build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
Pkg.clone(pwd(), \"AffineArithmetic\"); Pkg.build(\"AffineArithmetic\")"
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"

test_script:
- C:\projects\julia\bin\julia -e "Pkg.test(\"AffineArithmetic\")"
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"

# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
15 changes: 14 additions & 1 deletion src/AffineArithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module AffineArithmetic

using IntervalArithmetic

import Base: +, -, *, /, ==,
import Base: +, -, *, /, ^, ==,
zero, one, range,
show

Expand Down Expand Up @@ -54,6 +54,8 @@ Affine(c::Real) = Affine(c, Float64[])

range(C::Affine) = C.c + sum(abs.(C.γ))*(-1..1)

range(X::Interval) = X

# morally:
# +(C::Affine, D::Afine) = Affine(C.c + D.c, C.γ + D.γ)

Expand All @@ -76,6 +78,12 @@ for op in (:+, :-)
end
end

+(C::Affine, α::Real) = Affine(C.c + α, C.γ)
+::Real, C::Affine) = C + α

-(C::Affine, α::Real) = Affine(C.c - α, C.γ)
-::Real, C::Affine) = Affine- C.c, [-x for x in C.γ])

function *(C::Affine, D::Affine)

c = C.c
Expand All @@ -102,6 +110,11 @@ function *(C::Affine, D::Affine)
end

*::Real, C::Affine) = Affine*C.c, α*C.γ)
*(C::Affine, α::Real) = α * C

^(x::Affine, n::Integer) = Base.power_by_squaring(x, n)

Base.literal_pow(::typeof(^), x::Affine{T}, ::Val{p}) where {T,p} = x^p

eltype(C::Affine{T}) where T = T
zero(C::Affine{T}) where T = Affine(zero(T))
Expand Down
49 changes: 26 additions & 23 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using AffineArithmetic
using IntervalArithmetic
using Polynomials

using Test

Expand All @@ -13,6 +14,8 @@ using Test
C = Affine(1.0, [3.0, 4.0])
@test C.c == 1.0
@test C.γ == [3.0, 4.0]

reset_affine_index()
end

reset_affine_index()
Expand All @@ -31,36 +34,21 @@ reset_affine_index()
@test X_a * Y_a == Affine(6.0, [3.0, 2.0, 1.0])
end

sqr(x) = x * x

X = 1..3
X_a = Affine(X)

Y = sqr(X_a) - 2X_a + one(X_a)
r1 = range(Y)
@testset "Small powers and range" begin

Z = sqr(X_a - one(X_a))
range(Z)

Y3 = sqr(X - 1)

@testset "range" begin
X = 1..3
X_a = Affine(X)
Y = Affine(X)

Y1 = sqr(X_a) - 2X_a + one(X_a)
r1 = range(Y)
f(x) = x^2 - x + 1

Y2 = sqr(X_a - one(X_a))
r2 = range(Z)
@test range(f(X)) == -1..9
@test range(f(Y)) == -1..7 # affine is a little better

@test r1 == (-2..4)
@test r2 == r1

Y3 = sqr(X - 1)
@test Y3 == 0..4
g(x) = (x - 1)^3

@test Y3 range(Y1)
@test range(g(X)) == 0..8
@test range(g(Y)) == -6..8 # affine is significantly worse
end

reset_affine_index()
Expand All @@ -76,3 +64,18 @@ reset_affine_index()

@test A * XX == [Affine(0.0, [0.5, 1.0]), Affine(0.0, [-0.5, 0.5])]
end


reset_affine_index()

@testset "Range of polynomial" begin
# example from Rump 2015
p = Poly([-3, 1]) # x - 3
p2 = p^8

x = 4 ± 1e-4
y = Affine(x)

@test (-70..70) range(p2(x))
@test range(p2(y)) 0.998..1.002 # affine is extremely much better!
end

0 comments on commit ceb2031

Please sign in to comment.