mollusk 0e4acfb8f2 fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
2018-06-11 03:28:36 -07:00

545 lines
20 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# This file is a part of Julia. License is MIT: https://julialang.org/license
module TestBroadcastInternals
using Base.Broadcast: broadcast_indices, check_broadcast_indices,
check_broadcast_shape, newindex, _bcs, _bcsm
using Base: Test, OneTo
@test @inferred(_bcs((), (3,5), (3,5))) == (3,5)
@test @inferred(_bcs((), (3,1), (3,5))) == (3,5)
@test @inferred(_bcs((), (3,), (3,5))) == (3,5)
@test @inferred(_bcs((), (3,5), (3,))) == (3,5)
@test_throws DimensionMismatch _bcs((), (3,5), (4,5))
@test_throws DimensionMismatch _bcs((), (3,5), (3,4))
@test @inferred(_bcs((), (-1:1, 2:5), (-1:1, 2:5))) == (-1:1, 2:5)
@test @inferred(_bcs((), (-1:1, 2:5), (1, 2:5))) == (-1:1, 2:5)
@test @inferred(_bcs((), (-1:1, 1), (1, 2:5))) == (-1:1, 2:5)
@test @inferred(_bcs((), (-1:1,), (-1:1, 2:5))) == (-1:1, 2:5)
@test_throws DimensionMismatch _bcs((), (-1:1, 2:6), (-1:1, 2:5))
@test_throws DimensionMismatch _bcs((), (-1:1, 2:5), (2, 2:5))
@test @inferred(broadcast_indices(zeros(3,4), zeros(3,4))) == (OneTo(3),OneTo(4))
@test @inferred(broadcast_indices(zeros(3,4), zeros(3))) == (OneTo(3),OneTo(4))
@test @inferred(broadcast_indices(zeros(3), zeros(3,4))) == (OneTo(3),OneTo(4))
@test @inferred(broadcast_indices(zeros(3), zeros(1,4), zeros(1))) == (OneTo(3),OneTo(4))
check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3,5))
check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3,1))
check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3))
check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3,5), zeros(3))
check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3,5), 1)
check_broadcast_indices((OneTo(3),OneTo(5)), 5, 2)
@test_throws DimensionMismatch check_broadcast_indices((OneTo(3),OneTo(5)), zeros(2,5))
@test_throws DimensionMismatch check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3,4))
@test_throws DimensionMismatch check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3,4,2))
@test_throws DimensionMismatch check_broadcast_indices((OneTo(3),OneTo(5)), zeros(3,5), zeros(2))
check_broadcast_indices((-1:1, 6:9), 1)
check_broadcast_shape((-1:1, 6:9), (-1:1, 6:9))
check_broadcast_shape((-1:1, 6:9), (-1:1, 1))
check_broadcast_shape((-1:1, 6:9), (1, 6:9))
@test_throws DimensionMismatch check_broadcast_shape((-1:1, 6:9), (-1, 6:9))
@test_throws DimensionMismatch check_broadcast_shape((-1:1, 6:9), (-1:1, 6))
ci(x) = CartesianIndex(x)
@test @inferred(newindex(ci((2,2)), (true, true), (-1,-1))) == ci((2,2))
@test @inferred(newindex(ci((2,2)), (true, false), (-1,-1))) == ci((2,-1))
@test @inferred(newindex(ci((2,2)), (false, true), (-1,-1))) == ci((-1,2))
@test @inferred(newindex(ci((2,2)), (false, false), (-1,-1))) == ci((-1,-1))
@test @inferred(newindex(ci((2,2)), (true,), (-1,-1))) == ci((2,))
@test @inferred(newindex(ci((2,2)), (true,), (-1,))) == ci((2,))
@test @inferred(newindex(ci((2,2)), (false,), (-1,))) == ci((-1,))
@test @inferred(newindex(ci((2,2)), (), ())) == ci(())
end
function as_sub(x::AbstractVector)
y = similar(x, eltype(x), tuple(([size(x)...]*2)...))
y = view(y, 2:2:length(y))
y[:] = x[:]
y
end
function as_sub(x::AbstractMatrix)
y = similar(x, eltype(x), tuple(([size(x)...]*2)...))
y = view(y, 2:2:size(y,1), 2:2:size(y,2))
for j=1:size(x,2)
for i=1:size(x,1)
y[i,j] = x[i,j]
end
end
y
end
function as_sub{T}(x::AbstractArray{T,3})
y = similar(x, eltype(x), tuple(([size(x)...]*2)...))
y = view(y, 2:2:size(y,1), 2:2:size(y,2), 2:2:size(y,3))
for k=1:size(x,3)
for j=1:size(x,2)
for i=1:size(x,1)
y[i,j,k] = x[i,j,k]
end
end
end
y
end
bittest(f::Function, a...) = (@test f.(a...) == BitArray(broadcast(f, a...)))
n1 = 21
n2 = 32
n3 = 17
rb = 1:5
for arr in (identity, as_sub)
@test broadcast(+, arr(eye(2)), arr([1, 4])) == [2 1; 4 5]
@test broadcast(+, arr(eye(2)), arr([1 4])) == [2 4; 1 5]
@test broadcast(+, arr([1 0]), arr([1, 4])) == [2 1; 5 4]
@test broadcast(+, arr([1, 0]), arr([1 4])) == [2 5; 1 4]
@test broadcast(+, arr([1, 0]), arr([1, 4])) == [2, 4]
@test broadcast(+, arr([1, 0]), 2) == [3, 2]
@test @inferred(broadcast(+, arr(eye(2)), arr([1, 4]))) == arr([2 1; 4 5])
@test arr(eye(2)) .+ arr([1 4]) == arr([2 4; 1 5])
@test arr([1 0]) .+ arr([1, 4]) == arr([2 1; 5 4])
@test arr([1, 0]) .+ arr([1 4]) == arr([2 5; 1 4])
@test arr([1, 0]) .+ arr([1, 4]) == arr([2, 4])
@test arr([1]) .+ arr([]) == arr([])
A = arr(eye(2)); @test broadcast!(+, A, A, arr([1, 4])) == arr([2 1; 4 5])
A = arr(eye(2)); @test broadcast!(+, A, A, arr([1 4])) == arr([2 4; 1 5])
A = arr([1 0]); @test_throws DimensionMismatch broadcast!(+, A, A, arr([1, 4]))
A = arr([1 0]); @test broadcast!(+, A, A, arr([1 4])) == arr([2 4])
A = arr([1 0]); @test broadcast!(+, A, A, 2) == arr([3 2])
@test arr([ 1 2]) .* arr([3, 4]) == [ 3 6; 4 8]
@test arr([24.0 12.0]) ./ arr([2.0, 3.0]) == [12 6; 8 4]
@test arr([1 2]) ./ arr([3, 4]) == [1/3 2/3; 1/4 2/4]
@test arr([1 2]) .\ arr([3, 4]) == [3 1.5; 4 2]
@test arr([3 4]) .^ arr([1, 2]) == [3 4; 9 16]
@test arr(BitArray([true false])) .* arr(BitArray([true, true])) == [true false; true false]
@test arr(BitArray([true false])) .^ arr(BitArray([false, true])) == [true true; true false]
@test arr(BitArray([true false])) .^ arr([0, 3]) == [true true; true false]
M = arr([11 12; 21 22])
@test broadcast_getindex(M, eye(Int, 2).+1,arr([1, 2])) == [21 11; 12 22]
@test_throws BoundsError broadcast_getindex(M, eye(Int, 2).+1,arr([1, -1]))
@test_throws BoundsError broadcast_getindex(M, eye(Int, 2).+1,arr([1, 2]), [2])
@test broadcast_getindex(M, eye(Int, 2).+1,arr([2, 1]), [1]) == [22 12; 11 21]
A = arr(zeros(2,2))
broadcast_setindex!(A, arr([21 11; 12 22]), eye(Int, 2).+1,arr([1, 2]))
@test A == M
broadcast_setindex!(A, 5, [1,2], [2 2])
@test A == [11 5; 21 5]
broadcast_setindex!(A, 7, [1,2], [1 2])
@test A == fill(7, 2, 2)
A = arr(zeros(3,3))
broadcast_setindex!(A, 10:12, 1:3, 1:3)
@test A == diagm(10:12)
@test_throws BoundsError broadcast_setindex!(A, 7, [1,-1], [1 2])
for f in ((==), (<) , (!=), (<=))
bittest(f, arr(eye(2)), arr([1, 4]))
bittest(f, arr(eye(2)), arr([1 4]))
bittest(f, arr([0, 1]), arr([1 4]))
bittest(f, arr([0 1]), arr([1, 4]))
bittest(f, arr([1, 0]), arr([1, 4]))
bittest(f, arr(rand(rb, n1, n2, n3)), arr(rand(rb, n1, n2, n3)))
bittest(f, arr(rand(rb, 1, n2, n3)), arr(rand(rb, n1, 1, n3)))
bittest(f, arr(rand(rb, 1, n2, 1)), arr(rand(rb, n1, 1, n3)))
bittest(f, arr(bitrand(n1, n2, n3)), arr(bitrand(n1, n2, n3)))
end
end
r1 = 1:1
r2 = 1:5
ratio = [1,1/2,1/3,1/4,1/5]
@test r1.*r2 == [1:5;]
@test r1./r2 == ratio
m = [1:2;]'
@test m.*r2 == [1:5 2:2:10]
@test m./r2 [ratio 2ratio]
@test m./[r2;] [ratio 2ratio]
@test @inferred(broadcast(+,[0,1.2],reshape([0,-2],1,1,2))) == reshape([0 -2; 1.2 -0.8],2,1,2)
rt = Base.return_types(broadcast, Tuple{typeof(+), Array{Float64, 3}, Array{Int, 1}})
@test length(rt) == 1 && rt[1] == Array{Float64, 3}
rt = Base.return_types(broadcast!, Tuple{Function, Array{Float64, 3}, Array{Float64, 3}, Array{Int, 1}})
@test length(rt) == 1 && rt[1] == Array{Float64, 3}
# f.(args...) syntax (#15032)
let x = [1,3.2,4.7], y = [3.5, pi, 1e-4], α = 0.2342
@test sin.(x) == broadcast(sin, x)
@test sin.(α) == broadcast(sin, α)
@test sin.(3.2) == broadcast(sin, 3.2) == sin(3.2)
@test factorial.(3) == broadcast(factorial, 3)
@test atan2.(x, y) == broadcast(atan2, x, y)
@test atan2.(x, y') == broadcast(atan2, x, y')
@test atan2.(x, α) == broadcast(atan2, x, α)
@test atan2.(α, y') == broadcast(atan2, α, y')
end
# issue 14725
let a = Number[2, 2.0, 4//2, 2+0im] / 2
@test eltype(a) == Number
end
let a = Real[2, 2.0, 4//2] / 2
@test eltype(a) == Real
end
let a = Real[2, 2.0, 4//2] / 2.0
@test eltype(a) == Float64
end
# issue 16164
let a = broadcast(Float32, [3, 4, 5])
@test eltype(a) == Float32
end
# broadcasting scalars:
@test sin.(1) === broadcast(sin, 1) === sin(1)
@test (()->1234).() === broadcast(()->1234) === 1234
# issue #4883
@test isa(broadcast(tuple, [1 2 3], ["a", "b", "c"]), Matrix{Tuple{Int,String}})
@test isa(broadcast((x,y)->(x==1?1.0:x,y), [1 2 3], ["a", "b", "c"]), Matrix{Tuple{Real,String}})
let a = length.(["foo", "bar"])
@test isa(a, Vector{Int})
@test a == [3, 3]
end
let a = sin.([1, 2])
@test isa(a, Vector{Float64})
@test a [0.8414709848078965, 0.9092974268256817]
end
# PR #17300: loop fusion
@test (x->x+1).((x->x+2).((x->x+3).(1:10))) == collect(7:16)
let A = [sqrt(i)+j for i = 1:3, j=1:4]
@test atan2.(log.(A), sum(A,1)) == broadcast(atan2, broadcast(log, A), sum(A, 1))
end
let x = sin.(1:10)
@test atan2.((x->x+1).(x), (x->x+2).(x)) == broadcast(atan2, x+1, x+2) == broadcast(atan2, x.+1, x.+2)
@test sin.(atan2.([x+1,x+2]...)) == sin.(atan2.(x+1,x+2)) == @. sin(atan2(x+1,x+2))
@test sin.(atan2.(x, 3.7)) == broadcast(x -> sin(atan2(x,3.7)), x)
@test atan2.(x, 3.7) == broadcast(x -> atan2(x,3.7), x) == broadcast(atan2, x, 3.7)
end
# Use side effects to check for loop fusion.
let g = Int[]
f17300(x) = begin; push!(g, x); x+2; end
f17300.(f17300.(f17300.(1:3)))
@test g == [1,3,5, 2,4,6, 3,5,7]
empty!(g)
@. f17300(f17300(f17300(1:3)))
@test g == [1,3,5, 2,4,6, 3,5,7]
end
# fusion with splatted args:
let x = sin.(1:10), a = [x]
@test cos.(x) == cos.(a...)
@test atan2.(x,x) == atan2.(a..., a...) == atan2.([x, x]...)
@test atan2.(x, cos.(x)) == atan2.(a..., cos.(x)) == broadcast(atan2, x, cos.(a...)) == broadcast(atan2, a..., cos.(a...))
@test ((args...)->cos(args[1])).(x) == cos.(x) == ((y,args...)->cos(y)).(x)
end
@test atan2.(3,4) == atan2(3,4) == (() -> atan2(3,4)).()
# fusion with keyword args:
let x = [1:4;]
f17300kw(x; y=0) = x + y
@test f17300kw.(x) == x
@test f17300kw.(x, y=1) == f17300kw.(x; y=1) == f17300kw.(x; [(:y,1)]...) == x .+ 1
@test f17300kw.(sin.(x), y=1) == f17300kw.(sin.(x); y=1) == sin.(x) .+ 1
@test sin.(f17300kw.(x, y=1)) == sin.(f17300kw.(x; y=1)) == sin.(x .+ 1)
end
# issue #23236
let X = [[true,false],[false,true]]
@test [.!x for x in X] == [[false,true],[true,false]]
end
# splice escaping of @.
let x = [4, -9, 1, -16]
@test [2, 3, 4, 5] == @.(1 + sqrt($sort(abs(x))))
end
# interaction of @. with let
@test [1,4,9] == @. let x = [1,2,3]; x^2; end
# interaction of @. with for loops
let x = [1,2,3], y = x
@. for i = 1:3
y = y^2 # should convert to y .= y.^2
end
@test x == [1,256,6561]
end
# interaction of @. with function definitions
let x = [1,2,3]
@. f(x) = x^2
@test f(x) == [1,4,9]
end
# PR #17510: Fused in-place assignment
let x = [1:4;], y = x
y .= 2:5
@test y === x == [2:5;]
y .= factorial.(x)
@test y === x == [2,6,24,120]
y .= 7
@test y === x == [7,7,7,7]
y .= factorial.(3)
@test y === x == [6,6,6,6]
f17510() = 9
y .= f17510.()
@test y === x == [9,9,9,9]
y .-= 1
@test y === x == [8,8,8,8]
@. y -= 1:4 # @. should convert to .-=
@test y === x == [7,6,5,4]
x[1:2] .= 1
@test y === x == [1,1,5,4]
@. x[1:2] .+= [2,3] # use .+= to make sure @. works with dotted assignment
@test y === x == [3,4,5,4]
@. x[:] .= 0 # use .= to make sure @. works with dotted assignment
@test y === x == [0,0,0,0]
@. x[2:end] = 1:3 # @. should convert to .=
@test y === x == [0,1,2,3]
end
let a = [[4, 5], [6, 7]]
a[1] .= 3
@test a == [[3, 3], [6, 7]]
end
let d = Dict(:foo => [1,3,7], (3,4) => [5,9])
d[:foo] .+= 2
@test d[:foo] == [3,5,9]
d[3,4] .-= 1
@test d[3,4] == [4,8]
end
let identity = error, x = [1,2,3]
x .= 1 # make sure it goes to broadcast!(Base.identity, ...), not identity
@test x == [1,1,1]
end
# make sure scalars are inlined, which causes f.(x,scalar) to lower to a "thunk"
import Base.Meta: isexpr
@test isexpr(expand(:(f.(x,y))), :call)
@test isexpr(expand(:(f.(x,1))), :thunk)
@test isexpr(expand(:(f.(x,1.0))), :thunk)
@test isexpr(expand(:(f.(x,$π))), :thunk)
@test isexpr(expand(:(f.(x,"hello"))), :thunk)
@test isexpr(expand(:(f.(x,$("hello")))), :thunk)
# PR #17623: Fused binary operators
@test [true] .* [true] == [true]
@test [1,2,3] .|> (x->x+1) == [2,3,4]
let g = Int[], = (a,b) -> let c=a+2b; push!(g, c); c; end
@test [1,2,3] .⊕ [10,11,12] .⊕ [100,200,300] == [221,424,627]
@test g == [21,221,24,424,27,627] # test for loop fusion
end
# Fused unary operators
@test .√[3,4,5] == sqrt.([3,4,5])
@test .![true, true, false] == [false, false, true]
@test .-[1,2,3] == -[1,2,3] == .+[-1,-2,-3] == [-1,-2,-3]
# PR 16988
@test Base.promote_op(+, Bool) === Int
@test isa(broadcast(+, [true]), Array{Int,1})
# issue #17304
let foo = [[1,2,3],[4,5,6],[7,8,9]]
@test max.(foo...) == broadcast(max, foo...) == [7,8,9]
end
# Issue 17314
@test broadcast(x->log(log(log(x))), [1000]) == [log(log(log(1000)))]
let f17314 = x -> x < 0 ? false : x
@test eltype(broadcast(f17314, 1:3)) === Int
@test eltype(broadcast(f17314, -1:1)) === Integer
@test eltype(broadcast(f17314, Int[])) === Union{Bool,Int}
end
let io = IOBuffer()
broadcast(x->print(io,x), 1:5) # broadcast with side effects
@test take!(io) == [0x31,0x32,0x33,0x34,0x35]
end
# Issue 18176
let f18176(a, b, c) = a + b + c
@test f18176.(1.0:2, 3, 4) == f18176.(3.0, 1.0:2, 4.0) == broadcast(f18176, 3, 4, 1.0:2)
end
# Issue #17984
let A17984 = []
@test isa(abs.(A17984), Array{Any,1})
end
# Issue #16966
@test parse.(Int, "1") == 1
@test parse.(Int, ["1", "2"]) == [1, 2]
@test trunc.((Int,), [1.2, 3.4]) == [1, 3]
@test abs.((1, -2)) == (1, 2)
@test broadcast(+, 1.0, (0, -2.0)) == (1.0,-1.0)
@test broadcast(+, 1.0, (0, -2.0), [1]) == [2.0, 0.0]
@test broadcast(*, ["Hello"], ", ", ["World"], "!") == ["Hello, World!"]
let s = "foo"
@test s .* ["bar", "baz"] == ["foobar", "foobaz"] == "foo" .* ["bar", "baz"]
end
# Ensure that even strange constructors that break `T(x)::T` work with broadcast
struct StrangeType18623 end
StrangeType18623(x) = x
StrangeType18623(x,y) = (x,y)
@test @inferred(broadcast(StrangeType18623, 1:3)) == [1,2,3]
@test @inferred(broadcast(StrangeType18623, 1:3, 4:6)) == [(1,4),(2,5),(3,6)]
@test typeof(Int.(Number[1, 2, 3])) === typeof((x->Int(x)).(Number[1, 2, 3]))
@test @inferred(broadcast(CartesianIndex, 1:2)) == [CartesianIndex(1), CartesianIndex(2)]
@test @inferred(broadcast(CartesianIndex, 1:2, 3:4)) == [CartesianIndex(1,3), CartesianIndex(2,4)]
# Issue 18622
@test @inferred(broadcast(muladd, [1.0], [2.0], [3.0])) == [5.0]
@test @inferred(broadcast(tuple, 1:3, 4:6, 7:9)) == [(1,4,7), (2,5,8), (3,6,9)]
# 19419
@test @inferred(broadcast(round, Int, [1])) == [1]
# https://discourse.julialang.org/t/towards-broadcast-over-combinations-of-sparse-matrices-and-scalars/910
let
f(A, n) = broadcast(x -> +(x, n), A)
@test @inferred(f([1.0], 1)) == [2.0]
g() = (a = 1; Base.Broadcast._broadcast_eltype(x -> x + a, 1.0))
@test @inferred(g()) === Float64
end
# Ref as 0-dimensional array for broadcast
@test (-).(C_NULL, C_NULL)::UInt == 0
@test (+).(1, Ref(2)) == fill(3)
@test (+).(Ref(1), Ref(2)) == fill(3)
@test (+).([[0,2], [1,3]], [1,-1]) == [[1,3], [0,2]]
@test (+).([[0,2], [1,3]], Ref{Vector{Int}}([1,-1])) == [[1,1], [2,2]]
# Check that broadcast!(f, A) populates A via independent calls to f (#12277, #19722),
# and similarly for broadcast!(f, A, numbers...) (#19799).
@test let z = 1; A = broadcast!(() -> z += 1, zeros(2)); A[1] != A[2]; end
@test let z = 1; A = broadcast!(x -> z += x, zeros(2), 1); A[1] != A[2]; end
# broadcasting for custom AbstractArray
struct Array19745{T,N} <: AbstractArray{T,N}
data::Array{T,N}
end
Base.getindex(A::Array19745, i::Integer...) = A.data[i...]
Base.size(A::Array19745) = size(A.data)
Base.Broadcast._containertype{T<:Array19745}(::Type{T}) = Array19745
Base.Broadcast.promote_containertype(::Type{Array19745}, ::Type{Array19745}) = Array19745
Base.Broadcast.promote_containertype(::Type{Array19745}, ::Type{Array}) = Array19745
Base.Broadcast.promote_containertype(::Type{Array19745}, ct) = Array19745
Base.Broadcast.promote_containertype(::Type{Array}, ::Type{Array19745}) = Array19745
Base.Broadcast.promote_containertype(ct, ::Type{Array19745}) = Array19745
Base.Broadcast.broadcast_indices(::Type{Array19745}, A) = indices(A)
Base.Broadcast.broadcast_indices(::Type{Array19745}, A::Ref) = ()
getfield19745(x::Array19745) = x.data
getfield19745(x) = x
Base.Broadcast.broadcast_c(f, ::Type{Array19745}, A, Bs...) =
Array19745(Base.Broadcast.broadcast_c(f, Array, getfield19745(A), map(getfield19745, Bs)...))
@testset "broadcasting for custom AbstractArray" begin
a = randn(10)
aa = Array19745(a)
@test a .+ 1 == @inferred(aa .+ 1)
@test a .* a' == @inferred(aa .* aa')
@test isa(aa .+ 1, Array19745)
@test isa(aa .* aa', Array19745)
end
# broadcast with a custom type that looses to tuple
struct DataValue{T}
value::T
end
Base.Broadcast._containertype(::Type{<:DataValue}) = DataValue
Base.Broadcast.promote_containertype(::Type{Tuple}, ::Type{DataValue}) = Tuple
Base.Broadcast.promote_containertype(::Type{DataValue}, ::Type{Tuple}) = Tuple
Base.Broadcast._broadcast_getindex(::Type{DataValue}, A, I) = A.value
@testset "Broadcast with tuple and a custom type" begin
@test DataValue(1) .+ (1, 2) == (2, 3)
end
# broadcast should only "peel off" one container layer
@test get.([Nullable(1), Nullable(2)]) == [1, 2]
let io = IOBuffer()
broadcast(x -> print(io, x), [Nullable(1.0)])
@test String(take!(io)) == "Nullable{Float64}(1.0)"
end
# Test that broadcast's promotion mechanism handles closures accepting more than one argument.
# (See issue #19641 and referenced issues and pull requests.)
let f() = (a = 1; Base.Broadcast._broadcast_eltype((x, y) -> x + y + a, 1.0, 1.0))
@test @inferred(f()) == Float64
end
@testset "broadcast resulting in BitArray" begin
let f(x) = x ? true : "false"
ba = f.([true])
@test ba isa BitArray
@test ba == [true]
a = f.([false])
@test a isa Array{String}
@test a == ["false"]
@test f.([true, false]) == [true, "false"]
end
end
# Test that broadcast treats type arguments as scalars, i.e. containertype yields Any,
# even for subtypes of abstract array. (https://github.com/JuliaStats/DataArrays.jl/issues/229)
@testset "treat type arguments as scalars, DataArrays issue 229" begin
@test Base.Broadcast.containertype(AbstractArray) == Any
@test broadcast(==, [1], AbstractArray) == BitArray([false])
@test broadcast(==, 1, AbstractArray) == false
end
# Test that broadcasting identity where the input and output Array shapes do not match
# yields the correct result, not merely a partial copy. See pull request #19895 for discussion.
let N = 5
@test iszero(ones(N, N) .= zeros(N, N))
@test iszero(ones(N, N) .= zeros(N, 1))
@test iszero(ones(N, N) .= zeros(1, N))
@test iszero(ones(N, N) .= zeros(1, 1))
end
@testset "test broadcast for matrix of matrices" begin
A = fill(zeros(2,2), 4, 4)
A[1:3,1:3] .= [ones(2,2)]
@test all(A[1:3,1:3] .== [ones(2,2)])
end
# Test that broadcast does not confuse eltypes. See also
# https://github.com/JuliaLang/julia/issues/21325
@testset "eltype confusion (#21325)" begin
foo(x::Char, y::Int) = 0
foo(x::String, y::Int) = "hello"
@test broadcast(foo, "x", [1, 2, 3]) == ["hello", "hello", "hello"]
@test isequal(
[Set([1]), Set([2])] . Set([3]),
[Set([1, 3]), Set([2, 3])])
@test isequal(@inferred(broadcast(foo, "world", Nullable(1))),
Nullable("hello"))
end
@testset "broadcast resulting in tuples" begin
# Issue #21291
let t = (0, 1, 2)
o = 1
@test @inferred(broadcast(+, t, o)) == (1, 2, 3)
end
# Issue #23647
@test (1, 2, 3) .+ (1,) == (1,) .+ (1, 2, 3) == (2, 3, 4)
@test (1,) .+ () == () .+ (1,) == () .+ () == ()
@test (1, 2) .+ (1, 2) == (2, 4)
@test_throws DimensionMismatch (1, 2) .+ (1, 2, 3)
end