From 52344506c87785addfdced4c14ca54a7864b94c8 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 12 Feb 2024 23:08:18 +0100 Subject: [PATCH] do not support :fast multiplication with IA v0.22 --- src/operations/mult.jl | 118 +++++++++++++++++++++++------------------ test/arithmetic.jl | 2 + 2 files changed, 67 insertions(+), 53 deletions(-) diff --git a/src/operations/mult.jl b/src/operations/mult.jl index a711789d..bec8f87e 100644 --- a/src/operations/mult.jl +++ b/src/operations/mult.jl @@ -16,9 +16,12 @@ Sets the algorithm used to perform matrix multiplication with interval matrices. - `:fast` -- computes an enclosure of the matrix product using the midpoint-radius notation of the matrix [[RUM10]](@ref). +!!! note ":fast option no longer supported" + `:fast` support was removed in `IntervalArithmetic` v0.22. + ### Notes -- By default, `:fast` is used. +- By default, `:slow` is used. - Using `fast` is generally significantly faster, but it may return larger intervals, especially if midpoint and radius have the same order of magnitude (50% overestimate at most) [[RUM99]](@ref). @@ -26,6 +29,10 @@ Sets the algorithm used to perform matrix multiplication with interval matrices. function set_multiplication_mode(multype) multype in (:fast, :slow) || throw(ArgumentError("$multype is not a valid input.")) + @static if vIA >= v"0.22" + multype == :fast && throw(ArgumentError("$multype is not supported anymore input.")) + end + type = MultiplicationType{multype}() @eval *(A::IntervalMatrix, B::IntervalMatrix) = *($type, A, B) @@ -40,81 +47,86 @@ end *(::MultiplicationType{:slow}, A::AbstractMatrix, B::IntervalMatrix) = IntervalMatrix(A * B.mat) *(::MultiplicationType{:slow}, A::IntervalMatrix, B::AbstractMatrix) = IntervalMatrix(A.mat * B) -function *(::MultiplicationType{:fast}, - A::AbstractIntervalMatrix{Interval{T}}, - B::AbstractIntervalMatrix{Interval{T}}) where {T} - Ainf = inf(A) - Asup = sup(A) - Binf = inf(B) - Bsup = sup(B) +# not used anymore since IntervalArithmetic v0.22 +# COV_EXCL_START +@static if vIA < v"0.22" + function *(::MultiplicationType{:fast}, + A::AbstractIntervalMatrix{Interval{T}}, + B::AbstractIntervalMatrix{Interval{T}}) where {T} + Ainf = inf(A) + Asup = sup(A) + Binf = inf(B) + Bsup = sup(B) - mA, mB, R, Csup = setrounding(T, RoundUp) do - mA = Ainf + 0.5 * (Asup - Ainf) - mB = Binf + 0.5 * (Bsup - Binf) + mA, mB, R, Csup = setrounding(T, RoundUp) do + mA = Ainf + 0.5 * (Asup - Ainf) + mB = Binf + 0.5 * (Bsup - Binf) - rA = mA - Ainf - rB = mB - Binf + rA = mA - Ainf + rB = mB - Binf - R = abs.(mA) * rB + rA * (abs.(mB) + rB) - Csup = mA * mB + R + R = abs.(mA) * rB + rA * (abs.(mB) + rB) + Csup = mA * mB + R - return mA, mB, R, Csup - end + return mA, mB, R, Csup + end + + Cinf = setrounding(T, RoundDown) do + return mA * mB - R + end - Cinf = setrounding(T, RoundDown) do - return mA * mB - R + return IntervalMatrix(interval.(Cinf, Csup)) end - return IntervalMatrix(interval.(Cinf, Csup)) -end + function *(::MultiplicationType{:fast}, + A::AbstractMatrix{T}, + B::AbstractIntervalMatrix{Interval{T}}) where {T} + Binf = inf(B) + Bsup = sup(B) -function *(::MultiplicationType{:fast}, - A::AbstractMatrix{T}, - B::AbstractIntervalMatrix{Interval{T}}) where {T} - Binf = inf(B) - Bsup = sup(B) + mB, R, Csup = setrounding(T, RoundUp) do + mB = Binf + 0.5 * (Bsup - Binf) - mB, R, Csup = setrounding(T, RoundUp) do - mB = Binf + 0.5 * (Bsup - Binf) + rB = mB - Binf - rB = mB - Binf + R = abs.(A) * rB + Csup = A * mB + R - R = abs.(A) * rB - Csup = A * mB + R + return mB, R, Csup + end - return mB, R, Csup - end + Cinf = setrounding(T, RoundDown) do + return A * mB - R + end - Cinf = setrounding(T, RoundDown) do - return A * mB - R + return IntervalMatrix(interval.(Cinf, Csup)) end - return IntervalMatrix(interval.(Cinf, Csup)) -end + function *(::MultiplicationType{:fast}, + A::AbstractIntervalMatrix{Interval{T}}, + B::AbstractMatrix{T}) where {T} + Ainf = inf(A) + Asup = sup(A) -function *(::MultiplicationType{:fast}, - A::AbstractIntervalMatrix{Interval{T}}, - B::AbstractMatrix{T}) where {T} - Ainf = inf(A) - Asup = sup(A) + mA, R, Csup = setrounding(T, RoundUp) do + mA = Ainf + 0.5 * (Asup - Ainf) - mA, R, Csup = setrounding(T, RoundUp) do - mA = Ainf + 0.5 * (Asup - Ainf) + rA = mA - Ainf - rA = mA - Ainf + R = rA * abs.(B) + Csup = mA * B + R - R = rA * abs.(B) - Csup = mA * B + R + return mA, R, Csup + end - return mA, R, Csup - end + Cinf = setrounding(T, RoundDown) do + return mA * B - R + end - Cinf = setrounding(T, RoundDown) do - return mA * B - R + return IntervalMatrix((interval.(Cinf, Csup))) end - - return IntervalMatrix((interval.(Cinf, Csup))) end +# COV_EXCL_STOP # function *(::MultiplicationType{:rank1}, # A::AbstractMatrix{Interval{T}}, diff --git a/test/arithmetic.jl b/test/arithmetic.jl index 33ba43ad..9cfa1ec1 100644 --- a/test/arithmetic.jl +++ b/test/arithmetic.jl @@ -88,5 +88,7 @@ end IntervalMatrix([interval(5, 12.5) interval(-8, 2); interval(-2, 8) interval(5, 12.5)]) @test mid.(A) * A == IntervalMatrix([interval(5, 12.5) interval(-8, 2); interval(-2, 8) interval(5, 12.5)]) + else + @test_throws ArgumentError set_multiplication_mode(:fast) end end