1313
1414# contructor for `UniformScaling`
1515
16- IntervalArithmetic. interval (:: Type{T} , J:: LinearAlgebra.UniformScaling , d:: IntervalArithmetic.Decoration = com; format:: Symbol = :infsup ) where {T} =
17- LinearAlgebra. UniformScaling (interval (T, J. λ, d; format = format))
18- IntervalArithmetic. interval (J:: LinearAlgebra.UniformScaling , d:: IntervalArithmetic.Decoration = com; format:: Symbol = :infsup ) =
19- LinearAlgebra. UniformScaling (interval (J. λ, d; format = format))
16+ IntervalArithmetic. _interval_infsup (:: Type{T} , J:: LinearAlgebra.UniformScaling , H:: LinearAlgebra.UniformScaling , d:: IntervalArithmetic.Decoration ) where {T<: IntervalArithmetic.NumTypes } =
17+ LinearAlgebra. UniformScaling (IntervalArithmetic. _interval_infsup (T, J. λ, H. λ, d))
18+
19+ IntervalArithmetic. _infer_numtype (J:: LinearAlgebra.UniformScaling ) = numtype (eltype (J))
20+
21+ IntervalArithmetic. exact (J:: LinearAlgebra.UniformScaling ) = LinearAlgebra. UniformScaling (exact (J. λ))
2022
2123# by-pass generic `opnorm` from LinearAlgebra to prevent NG flag
2224
@@ -139,32 +141,22 @@ end
139141
140142# matrix multiplication
141143
142- function IntervalArithmetic. configure_matmul (matmul:: Symbol )
143- matmul ∈ (:slow , :fast ) || return throw (ArgumentError (" only the matrix multiplication mode `:slow` and `:fast` are available" ))
144-
145- @eval begin
146- function LinearAlgebra. mul! (C:: AbstractVector{<:RealOrComplexI} , A:: AbstractVecOrMat , B:: AbstractVector , α:: Number , β:: Number )
147- size (A, 2 ) == size (B, 1 ) || return throw (DimensionMismatch (" The number of columns of A must match the number of rows of B." ))
148- return IntervalArithmetic. _mul! (IntervalArithmetic. MatMulMode {$(QuoteNode(matmul))} (), C, A, B, α, β)
149- end
150-
151- function LinearAlgebra. mul! (C:: AbstractMatrix{<:RealOrComplexI} , A:: AbstractVecOrMat , B:: AbstractVecOrMat , α:: Number , β:: Number )
152- size (A, 2 ) == size (B, 1 ) || return throw (DimensionMismatch (" The number of columns of A must match the number of rows of B." ))
153- return IntervalArithmetic. _mul! (IntervalArithmetic. MatMulMode {$(QuoteNode(matmul))} (), C, A, B, α, β)
154- end
155- end
156-
157- return matmul
144+ function LinearAlgebra. mul! (C:: AbstractVector{<:RealOrComplexI} , A:: AbstractVecOrMat , B:: AbstractVector , α:: Number , β:: Number )
145+ size (A, 2 ) == size (B, 1 ) || return throw (DimensionMismatch (" The number of columns of A must match the number of rows of B." ))
146+ return _mul! (IntervalArithmetic. default_matmul (), C, A, B, α, β)
158147end
159148
160- IntervalArithmetic. configure_matmul (:fast )
149+ function LinearAlgebra. mul! (C:: AbstractMatrix{<:RealOrComplexI} , A:: AbstractVecOrMat , B:: AbstractVecOrMat , α:: Number , β:: Number )
150+ size (A, 2 ) == size (B, 1 ) || return throw (DimensionMismatch (" The number of columns of A must match the number of rows of B." ))
151+ return _mul! (IntervalArithmetic. default_matmul (), C, A, B, α, β)
152+ end
161153
162154#
163155
164156LinearAlgebra. mul! (C:: AbstractVecOrMat{<:RealOrComplexI} , A:: AbstractMatrix{<:RealOrComplexI} , B:: AbstractVecOrMat{<:RealOrComplexI} ) =
165157 LinearAlgebra. mul! (C, A, B, interval (true ), interval (false ))
166158
167- function IntervalArithmetic . _mul! (:: IntervalArithmetic.MatMulMode{:slow} , C, A:: AbstractMatrix , B:: AbstractVecOrMat , α, β)
159+ function _mul! (:: IntervalArithmetic.MatMulMode{:slow} , C, A:: AbstractMatrix , B:: AbstractVecOrMat , α, β)
168160 if iszero (α)
169161 if iszero (β)
170162 C .= zero (eltype (C))
@@ -221,14 +213,14 @@ end
221213# fast matrix multiplication
222214# Note: Rump's algorithm
223215
224- function IntervalArithmetic . _mul! (:: IntervalArithmetic.MatMulMode{:fast} , C, A, B, α, β)
216+ function _mul! (:: IntervalArithmetic.MatMulMode{:fast} , C, A, B, α, β)
225217 if Int == Int32
226218 @info " Fast multiplication is not supported on 32-bit systems, using the slow version"
227- return IntervalArithmetic . _mul! (IntervalArithmetic. MatMulMode {:slow} (), C, A, B, α, β)
219+ return _mul! (IntervalArithmetic. MatMulMode {:slow} (), C, A, B, α, β)
228220 else
229221 numtype (eltype (C)) <: Union{Float16,Float32,Float64} && return _fastmul! (C, A, B, α, β)
230222 @info " Fast multiplication is only supported for `Union{Float16,Float32,Float64}`, using the slow version"
231- return IntervalArithmetic . _mul! (IntervalArithmetic. MatMulMode {:slow} (), C, A, B, α, β)
223+ return _mul! (IntervalArithmetic. MatMulMode {:slow} (), C, A, B, α, β)
232224 end
233225end
234226
@@ -413,11 +405,11 @@ function ___mul(A::AbstractMatrix{T}, B::AbstractVecOrMat{Interval{T}}) where {T
413405
414406 stride_A = _to_stride_64 (A)
415407 stride_mB = _to_stride_64 (mB)
416- C₁ = IntervalArithmetic. _sub_round .(
408+ C₁ = IntervalArithmetic. _fround .( - ,
417409 T .(_call_gem_openblas! (cache_2, stride_A, stride_mB, RoundDown), RoundDown),
418410 T .(rC, RoundUp),
419411 RoundDown)
420- C₂ = cache_2; C₂ .= IntervalArithmetic. _add_round .(
412+ C₂ = cache_2; C₂ .= IntervalArithmetic. _fround .( + ,
421413 T .(_call_gem_openblas! (cache_2, stride_A, stride_mB, RoundUp), RoundUp),
422414 T .(rC, RoundUp),
423415 RoundUp)
@@ -435,11 +427,11 @@ function ___mul(A::AbstractMatrix{Interval{T}}, B::AbstractVecOrMat{T}) where {T
435427
436428 stride_mA = _to_stride_64 (mA)
437429 stride_B = _to_stride_64 (B)
438- C₁ = IntervalArithmetic. _sub_round .(
430+ C₁ = IntervalArithmetic. _fround .( - ,
439431 T .(_call_gem_openblas! (cache_2, stride_mA, stride_B, RoundDown), RoundDown),
440432 T .(rC, RoundUp),
441433 RoundDown)
442- C₂ = cache_2; C₂ .= IntervalArithmetic. _add_round .(
434+ C₂ = cache_2; C₂ .= IntervalArithmetic. _fround .( + ,
443435 T .(_call_gem_openblas! (cache_2, stride_mA, stride_B, RoundUp), RoundUp),
444436 T .(rC, RoundUp),
445437 RoundUp)
@@ -455,76 +447,33 @@ function ___mul(A::AbstractMatrix{Interval{T}}, B::AbstractVecOrMat{Interval{T}}
455447 cache_2 = zeros (Float64, size (A, 1 ), size (B, 2 ))
456448
457449 absmA_rB = _call_gem_openblas! (cache_1, _to_stride_64 (abs .(mA)), _to_stride_64 (rB), RoundUp)
458- U = rB; U .= IntervalArithmetic. _add_round .( abs .(mB), rB, RoundUp)
450+ U = rB; U .= IntervalArithmetic. _fround .( + , abs .(mB), rB, RoundUp)
459451 rA_U = _call_gem_openblas! (cache_2, _to_stride_64 (rA), _to_stride_64 (U), RoundUp)
460452
461453 cache_3 = zeros (Float64, size (A, 1 ), size (B, 2 ))
462454
463455 stride_mA = _to_stride_64 (mA)
464456 stride_mB = _to_stride_64 (mB)
465- C₁ = IntervalArithmetic. _sub_round .(
457+ C₁ = IntervalArithmetic. _fround .( - ,
466458 T .(_call_gem_openblas! (cache_3, stride_mA, stride_mB, RoundDown), RoundDown),
467- IntervalArithmetic. _add_round .( T .(absmA_rB, RoundUp), T .(rA_U, RoundUp), RoundUp),
459+ IntervalArithmetic. _fround .( + , T .(absmA_rB, RoundUp), T .(rA_U, RoundUp), RoundUp),
468460 RoundDown)
469- C₂ = cache_3; C₂ .= IntervalArithmetic. _add_round .(
461+ C₂ = cache_3; C₂ .= IntervalArithmetic. _fround .( + ,
470462 T .(_call_gem_openblas! (cache_3, stride_mA, stride_mB, RoundUp), RoundUp),
471- IntervalArithmetic. _add_round .( T .(absmA_rB, RoundUp), T .(rA_U, RoundUp), RoundUp),
463+ IntervalArithmetic. _fround .( + , T .(absmA_rB, RoundUp), T .(rA_U, RoundUp), RoundUp),
472464 RoundUp)
473465
474466 return C₁, C₂
475467end
476468
477- # function ___mul(A::AbstractMatrix{Interval{T}}, B::AbstractVecOrMat{Interval{T}}) where {T<:AbstractFloat}
478- # k = size(A, 2)
479- # u2 = eps(T) # twice the unit roundoff
480- # @assert (2k + 2) * u2 ≤ 1
481-
482- # mA, rA = _vec_or_mat_midradius(A)
483- # mB, rB = _vec_or_mat_midradius(B)
484-
485- # cache_1 = zeros(T, size(A, 1), size(B, 2))
486- # cache_2 = zeros(T, size(A, 1), size(B, 2))
487- # mC, μ = _fused_matmul!(cache_1, cache_2, mA, rA, mB, rB)
488-
489- # γ = IntervalArithmetic._add_round.(IntervalArithmetic._mul_round.(convert(T, k + 1), eps.(μ), RoundUp), IntervalArithmetic._mul_round(IntervalArithmetic._inv_round(u2, RoundUp), floatmin(T), RoundUp), RoundUp)
490-
491- # U = mA; U .= IntervalArithmetic._add_round.(abs.(mA), rA, RoundUp)
492- # V = mB; V .= IntervalArithmetic._add_round.(abs.(mB), rB, RoundUp)
493-
494- # cache_3 = zeros(Float64, size(A, 1), size(B, 2))
495- # rC = IntervalArithmetic._add_round.(IntervalArithmetic._sub_round.(T.(_call_gem_openblas!(cache_3, _to_stride_64(U), _to_stride_64(V), RoundUp), RoundUp), μ, RoundUp), 2 .* γ, RoundUp)
496-
497- # C₁ = μ; C₁ .= IntervalArithmetic._sub_round.(mC, rC, RoundDown)
498- # C₂ = γ; C₂ .= IntervalArithmetic._add_round.(mC, rC, RoundUp)
499-
500- # return C₁, C₂
501- # end
502-
503- # function _fused_matmul!(mC, μ, mA, rA, mB, rB)
504- # Threads.@threads for j ∈ axes(mB, 2)
505- # for l ∈ axes(mA, 2)
506- # @inbounds for i ∈ axes(mA, 1)
507- # a, c = mA[i,l], rA[i,l]
508- # b, d = mB[l,j], rB[l,j]
509- # e = sign(a) * min(abs(a), c)
510- # f = sign(b) * min(abs(b), d)
511- # p = a*b + e*f
512- # mC[i,j] += p
513- # μ[i,j] += abs(p)
514- # end
515- # end
516- # end
517- # return mC, μ
518- # end
519-
520469_to_stride_64 (A:: StridedArray{Float64} ) = A
521470_to_stride_64 (A:: StridedArray{<:AbstractFloat} ) = Float64 .(A, RoundUp)
522471_to_stride_64 (A:: AbstractVector ) = _to_stride_64 (Vector (A))
523472_to_stride_64 (A:: AbstractMatrix ) = _to_stride_64 (Matrix (A))
524473
525474function _vec_or_mat_midradius (A:: AbstractVecOrMat{Interval{T}} ) where {T<: AbstractFloat }
526- mA = IntervalArithmetic. _div_round .( IntervalArithmetic. _add_round .( inf .(A), sup .(A), RoundUp), convert (T, 2 ), RoundUp)
527- rA = IntervalArithmetic. _sub_round .( mA, inf .(A), RoundUp)
475+ mA = IntervalArithmetic. _fround .( / , IntervalArithmetic. _fround .( + , inf .(A), sup .(A), RoundUp), convert (T, 2 ), RoundUp)
476+ rA = IntervalArithmetic. _fround .( - , mA, inf .(A), RoundUp)
528477 return mA, rA
529478end
530479
0 commit comments