@@ -2055,6 +2055,28 @@ end
2055
2055
@test accumulate (op, [10 20 30 ], 2 ) == [10 op (10 , 20 ) op (op (10 , 20 ), 30 )] == [10 40 110 ]
2056
2056
end
2057
2057
2058
+ struct F21666{T <: Base.TypeArithmetic }
2059
+ x:: Float32
2060
+ end
2061
+
2062
+ @testset " Exactness of cumsum # 21666" begin
2063
+ # test that cumsum uses more stable algorithm
2064
+ # for types with unknown/rounding arithmetic
2065
+ Base. TypeArithmetic (:: Type{F21666{T}} ) where {T} = T
2066
+ Base.:+ (x:: F , y:: F ) where {F <: F21666 } = F (x. x + y. x)
2067
+ Base. convert (:: Type{Float64} , x:: F21666 ) = Float64 (x. x)
2068
+ # we make v pretty large, because stable algorithm may have a large base case
2069
+ v = zeros (300 ); v[1 ] = 2 ; v[200 : end ] = eps (Float32)
2070
+
2071
+ f_rounds = Float64 .(cumsum (F21666 {Base.ArithmeticRounds} .(v)))
2072
+ f_unknown = Float64 .(cumsum (F21666 {Base.ArithmeticUnknown} .(v)))
2073
+ f_truth = cumsum (v)
2074
+ f_inexact = Float64 .(accumulate (+ , Float32 .(v)))
2075
+ @test f_rounds == f_unknown
2076
+ @test f_rounds != f_inexact
2077
+ @test norm (f_truth - f_rounds) < norm (f_truth - f_inexact)
2078
+ end
2079
+
2058
2080
@testset " zeros and ones" begin
2059
2081
@test ones ([1 ,2 ], Float64, (2 ,3 )) == ones (2 ,3 )
2060
2082
@test ones (2 ) == ones (Int, 2 ) == ones ([2 ,3 ], Float32, 2 ) == [1 ,1 ]
0 commit comments