diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba5c8f78a6359..b5f41ab43798d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -174,7 +174,7 @@ The steps required to add a new docstring are listed below: Examples written within docstrings can be used as testcases known as "doctests" by annotating code blocks with `jldoctest`. ```jldoctest - julia> Unicode.uppercase("Docstring test") + julia> uppercase("Docstring test") "DOCSTRING TEST" ``` diff --git a/NEWS.md b/NEWS.md index cb23c20919ccc..a66404e1cf104 100644 --- a/NEWS.md +++ b/NEWS.md @@ -40,6 +40,9 @@ New language features * Field access via dot-syntax can now be overloaded by adding methods to `Base.getproperty` and `Base.setproperty!` ([#1974]). + * Values for `Enum`s can now be specified inside of a `begin` block when using the + `@enum` macro ([#25424]). + Language changes ---------------- @@ -176,6 +179,8 @@ Language changes * The syntax `using A.B` can now only be used when `A.B` is a module, and the syntax `using A: B` can only be used for adding single bindings ([#8000]). + * `=>` now has its own precedence level, giving it strictly higher precedence than + `=` and `,` ([#25391]). Breaking changes ---------------- @@ -355,12 +360,33 @@ This section lists changes that do not have deprecation warnings. * `AbstractRange` objects are now considered as equal to other `AbstractArray` objects by `==` and `isequal` if all of their elements are equal ([#16401]). This has required changing the hashing algorithm: ranges now use an O(N) fallback - instead of a O(1) specialized method unless they define the `Base.TypeRangeStep` + instead of a O(1) specialized method unless they define the `Base.RangeStepStyle` trait; see its documentation for details. Types which support subtraction (operator `-`) must now implement `widen` for hashing to work inside heterogeneous arrays. - * `findn(x::AbstractVector)` now return a 1-tuple with the vector of indices, to be - consistent with higher order arrays ([#25365]). + * `findn(x::AbstractArray)` has been deprecated in favor of `find(!iszero, x)`, which + now returns cartesian indices for multidimensional arrays (see below, [#25532]). + + * `find` now returns the same type of indices as `keys`/`pairs` for `AbstractArray`, + `AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774]). + In particular, this means that it returns `CartesianIndex` objects for matrices + and higher-dimensional arrays instead of linear indices as was previously the case. + Use `LinearIndices(a)[find(f, a)]` to compute linear indices. + + * `AbstractSet` objects are now considered equal by `==` and `isequal` if all of their + elements are equal ([#25368]). This has required changing the hashing algorithm + for `BitSet`. + + * the default behavior of `titlecase` is changed in two ways ([#23393]): + + characters not starting a word are converted to lowercase; + a new keyword argument `strict` is added which + allows to get the old behavior when it's `false`. + + any non-letter character is considered as a word separator; + to get the old behavior (only "space" characters are considered as + word separators), use the keyword `wordsep=isspace`. + + * The `tempname` function used to create a file on Windows but not on other + platforms. It now never creates a file ([#9053]). Library improvements -------------------- @@ -844,26 +870,25 @@ Deprecated or removed * `workspace` is discontinued, check out [Revise.jl](https://github.com/timholy/Revise.jl) for an alternative workflow ([#25046]). - * `cumsum`, `cumprod`, `accumulate`, and their mutating versions now require a `dim` - argument instead of defaulting to using the first dimension ([#24684]). + * `cumsum`, `cumprod`, `accumulate`, their mutating versions, and `diff` all now require a `dim` + argument instead of defaulting to using the first dimension unless there is only + one dimension ([#24684], [#25457]). * The `sum_kbn` and `cumsum_kbn` functions have been moved to the [KahanSummation](https://github.com/JuliaMath/KahanSummation.jl) package ([#24869]). - * Unicode-related string functions have been moved to the new `Unicode` standard - library module ([#25021]). This applies to `normalize_string`, `graphemes`, - `is_assigned_char`, `textwidth`, `islower`, `isupper`, `isalpha`, - `isdigit`, `isxdigit`, `isnumber`, `isalnum`, `iscntrl`, `ispunct`, `isspace`, - `isprint`, `isgraph`, `lowercase`, `uppercase`, `titlecase`, `lcfirst` and `ucfirst`. + * `isnumber` has been renamed to `isnumeric` ([#25021]). + + * `is_assigned_char` and `normalize_string` have been renamed to `isassigned` and + `normalize`, and moved to the new `Unicode` standard library module. + `graphemes` has also been moved to that module ([#25021]). * The functions `eigs` and `svds` have been moved to the `IterativeEigensolvers` standard library module ([#24714]). - * `@printf` and `@sprintf` have been moved to the `Printf` standard library ([#23929],[#25056]). + * Sparse array functionality has moved to the `SparseArrays` standard library module ([#25249]). - * `isnumber` has been deprecated in favor of `isnumeric`, `is_assigned_char` - in favor of `isassigned` and `normalize_string` in favor of `normalize`, all three - in the new `Unicode` standard library module ([#25021]). + * `@printf` and `@sprintf` have been moved to the `Printf` standard library ([#23929],[#25056]). * The aliases `Complex32`, `Complex64` and `Complex128` have been deprecated in favor of `ComplexF16`, `ComplexF32` and `ComplexF64` respectively ([#24647]). @@ -915,6 +940,14 @@ Deprecated or removed * `findin(a, b)` has been deprecated in favor of `find(occursin(b), a)` ([#24673]). + * The generic implementations of `strides(::AbstractArray)` and `stride(::AbstractArray, ::Int)` + have been deprecated. Subtypes of `AbstractArray` that implement the newly introduced strided + array interface should define their own `strides` method ([#25321]). + + * `rand(t::Tuple{Vararg{Int}})` is deprecated in favor of `rand(Float64, t)` or `rand(t...)`; + `rand(::Tuple)` will have another meaning in the future ([#25429], [#25278]). + + Command-line option changes --------------------------- @@ -1137,6 +1170,7 @@ Command-line option changes [#24713]: https://github.com/JuliaLang/julia/issues/24713 [#24714]: https://github.com/JuliaLang/julia/issues/24714 [#24715]: https://github.com/JuliaLang/julia/issues/24715 +[#24774]: https://github.com/JuliaLang/julia/issues/24774 [#24781]: https://github.com/JuliaLang/julia/issues/24781 [#24785]: https://github.com/JuliaLang/julia/issues/24785 [#24786]: https://github.com/JuliaLang/julia/issues/24786 @@ -1162,3 +1196,5 @@ Command-line option changes [#25184]: https://github.com/JuliaLang/julia/issues/25184 [#25231]: https://github.com/JuliaLang/julia/issues/25231 [#25365]: https://github.com/JuliaLang/julia/issues/25365 +[#25424]: https://github.com/JuliaLang/julia/issues/25424 +[#25532]: https://github.com/JuliaLang/julia/issues/25532 diff --git a/README.md b/README.md index 591bfcfeb4f3c..83a38633f497f 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Code coverage: [travis-img]: https://img.shields.io/travis/JuliaLang/julia/master.svg?label=Linux+/+macOS [appveyor-img]: https://img.shields.io/appveyor/ci/JuliaLang/julia/master.svg?label=Windows -[coveralls-img]: https://img.shields.io/codecov/c/github/JuliaLang/julia/master.svg?label=coveralls +[coveralls-img]: https://img.shields.io/coveralls/c/github/JuliaLang/julia/master.svg?label=coveralls [codecov-img]: https://img.shields.io/codecov/c/github/JuliaLang/julia/master.svg?label=codecov ## The Julia Language diff --git a/base/Enums.jl b/base/Enums.jl index 48c7233178359..3e20f055fe175 100644 --- a/base/Enums.jl +++ b/base/Enums.jl @@ -46,6 +46,15 @@ julia> f(apple) "I'm a Fruit with value: 1" ``` +Values can also be specified inside a `begin` block, e.g. + +```julia +@enum EnumName begin + value1 + value2 +end +``` + `BaseType`, which defaults to [`Int32`](@ref), must be a primitive subtype of `Integer`. Member values can be converted between the enum type and `BaseType`. `read` and `write` perform these conversions automatically. @@ -69,7 +78,12 @@ macro enum(T, syms...) lo = hi = 0 i = zero(basetype) hasexpr = false + + if length(syms) == 1 && syms[1] isa Expr && syms[1].head == :block + syms = syms[1].args + end for s in syms + s isa LineNumberNode && continue if isa(s, Symbol) if i == typemin(basetype) && !isempty(vals) throw(ArgumentError("overflow in value \"$s\" of Enum $typename")) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index be993d85e66fd..5655741ace0c3 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -849,9 +849,14 @@ eachindex(::IndexLinear, A::AbstractArray) = linearindices(A) function eachindex(::IndexLinear, A::AbstractArray, B::AbstractArray...) @_inline_meta indsA = linearindices(A) - all(x->linearindices(x) == indsA, B) || throw_eachindex_mismatch(IndexLinear(), A, B...) + _all_match_first(linearindices, indsA, B...) || throw_eachindex_mismatch(IndexLinear(), A, B...) indsA end +function _all_match_first(f::F, inds, A, B...) where F<:Function + @_inline_meta + (inds == f(A)) & _all_match_first(f, inds, B...) +end +_all_match_first(f::F, inds) where F<:Function = true isempty(a::AbstractArray) = (_length(a) == 0) @@ -1548,7 +1553,7 @@ function isequal(A::AbstractArray, B::AbstractArray) return true end -function cmp(A::AbstractArray, B::AbstractArray) +function cmp(A::AbstractVector, B::AbstractVector) for (a, b) in zip(A, B) if !isequal(a, b) return isless(a, b) ? -1 : 1 @@ -1557,7 +1562,7 @@ function cmp(A::AbstractArray, B::AbstractArray) return cmp(length(A), length(B)) end -isless(A::AbstractArray, B::AbstractArray) = cmp(A, B) < 0 +isless(A::AbstractVector, B::AbstractVector) = cmp(A, B) < 0 function (==)(A::AbstractArray, B::AbstractArray) if axes(A) != axes(B) @@ -1727,7 +1732,7 @@ for all `i` and `j`. # Examples ```jldoctest -julia> a = reshape(collect(1:16),(2,2,2,2)) +julia> a = reshape(Vector(1:16),(2,2,2,2)) 2×2×2×2 Array{Int64,4}: [:, :, 1, 1] = 1 3 @@ -1954,7 +1959,7 @@ end function hash(a::AbstractArray{T}, h::UInt) where T # O(1) hashing for types with regular step - if isa(a, AbstractRange) && isa(TypeRangeStep(a), RangeStepRegular) + if isa(a, AbstractRange) && isa(RangeStepStyle(a), RangeStepRegular) return hash_range(a, h) end diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl index ee208780fffa2..d5343c922d4e3 100644 --- a/base/abstractarraymath.jl +++ b/base/abstractarraymath.jl @@ -51,7 +51,7 @@ Elements of `dims` must be unique and within the range `1:ndims(A)`. # Examples ```jldoctest -julia> a = reshape(collect(1:4),(2,2,1,1)) +julia> a = reshape(Vector(1:4),(2,2,1,1)) 2×2×1×1 Array{Int64,4}: [:, :, 1, 1] = 1 3 @@ -186,7 +186,7 @@ first dimension. # Examples ```jldoctest -julia> b = reshape(collect(1:16), (4,4)) +julia> b = reshape(Vector(1:16), (4,4)) 4×4 Array{Int64,2}: 1 5 9 13 2 6 10 14 diff --git a/base/array.jl b/base/array.jl index 980880fb1aea6..192b9518b200c 100644 --- a/base/array.jl +++ b/base/array.jl @@ -429,7 +429,7 @@ julia> collect(Float64, 1:2:5) 5.0 ``` """ -collect(::Type{T}, itr) where {T} = _collect(T, itr, iteratorsize(itr)) +collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr)) _collect(::Type{T}, itr, isz::HasLength) where {T} = copyto!(Vector{T}(uninitialized, Int(length(itr)::Integer)), itr) _collect(::Type{T}, itr, isz::HasShape) where {T} = copyto!(similar(Array{T}, axes(itr)), itr) @@ -467,11 +467,11 @@ julia> collect(1:2:13) 13 ``` """ -collect(itr) = _collect(1:1 #= Array =#, itr, iteratoreltype(itr), iteratorsize(itr)) +collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr)) collect(A::AbstractArray) = _collect_indices(axes(A), A) -collect_similar(cont, itr) = _collect(cont, itr, iteratoreltype(itr), iteratorsize(itr)) +collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr)) _collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) = copyto!(_similar_for(cont, eltype(itr), itr, isz), itr) @@ -524,7 +524,7 @@ _array_for(::Type{T}, itr, ::HasLength) where {T} = Vector{T}(uninitialized, Int _array_for(::Type{T}, itr, ::HasShape) where {T} = similar(Array{T}, axes(itr))::Array{T} function collect(itr::Generator) - isz = iteratorsize(itr.iter) + isz = IteratorSize(itr.iter) et = @default_eltype(itr) if isa(isz, SizeUnknown) return grow_to!(Vector{et}(), itr) @@ -583,8 +583,15 @@ function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T end function grow_to!(dest, itr) - out = grow_to!(empty(dest, Union{}), itr, start(itr)) - return isempty(out) ? dest : out + st = start(itr) + if done(itr, st) + return dest + else + v1, st = next(itr, st) + dest2 = empty(dest, typeof(v1)) + push!(dest2, v1) + return grow_to!(dest2, itr, st) + end end function grow_to!(dest, itr, st) @@ -821,7 +828,7 @@ function append!(a::Array{<:Any,1}, items::AbstractVector) return a end -append!(a::Vector, iter) = _append!(a, iteratorsize(iter), iter) +append!(a::Vector, iter) = _append!(a, IteratorSize(iter), iter) push!(a::Vector, iter...) = append!(a, iter) function _append!(a, ::Union{HasLength,HasShape}, iter) @@ -868,7 +875,7 @@ function prepend!(a::Array{<:Any,1}, items::AbstractVector) return a end -prepend!(a::Vector, iter) = _prepend!(a, iteratorsize(iter), iter) +prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter) pushfirst!(a::Vector, iter...) = prepend!(a, iter) function _prepend!(a, ::Union{HasLength,HasShape}, iter) @@ -1334,7 +1341,7 @@ for reverse-order iteration without making a copy. # Examples ```jldoctest -julia> A = collect(1:5) +julia> A = Vector(1:5) 5-element Array{Int64,1}: 1 2 @@ -1392,7 +1399,7 @@ In-place version of [`reverse`](@ref). # Examples ```jldoctest -julia> A = collect(1:5) +julia> A = Vector(1:5) 5-element Array{Int64,1}: 1 2 @@ -1488,7 +1495,7 @@ cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(x->1, n-1)..., length(x """ findnext(A, i::Integer) -Find the next linear index >= `i` of a `true` element of `A`, or `0` if not found. +Find the next linear index >= `i` of a `true` element of `A`, or `nothing` if not found. # Examples ```jldoctest @@ -1501,7 +1508,6 @@ julia> findnext(A, 1) 2 julia> findnext(A, 3) -0 ``` """ function findnext(A, start::Integer) @@ -1519,14 +1525,14 @@ function findnext(A, start::Integer) end i = nextind(A, i) end - return 0 + return nothing end """ findfirst(A) Return the linear index of the first `true` value in `A`. -Return `0` if no such value is found. +Return `nothing` if no such value is found. To search for other kinds of values, pass a predicate as the first argument. # Examples @@ -1539,8 +1545,8 @@ julia> A = [false false; true false] julia> findfirst(A) 2 -julia> findfirst(falses(3)) -0 +julia> findfirst(falses(3)) == nothing +true ``` """ findfirst(A) = findnext(A, 1) @@ -1548,7 +1554,8 @@ findfirst(A) = findnext(A, 1) """ findnext(predicate::Function, A, i::Integer) -Find the next linear index >= `i` of an element of `A` for which `predicate` returns `true`, or `0` if not found. +Find the next linear index >= `i` of an element of `A` for which `predicate` returns `true`, +or `nothing` if not found. # Examples ```jldoctest @@ -1560,8 +1567,8 @@ julia> A = [1 4; 2 2] julia> findnext(isodd, A, 1) 1 -julia> findnext(isodd, A, 2) -0 +julia> findnext(isodd, A, 2) == nothing +true ``` """ function findnext(testf::Function, A, start::Integer) @@ -1573,14 +1580,14 @@ function findnext(testf::Function, A, start::Integer) end i = nextind(A, i) end - return 0 + return nothing end """ findfirst(predicate::Function, A) Return the linear index of the first element of `A` for which `predicate` returns `true`. -Return `0` if there is no such element. +Return `nothing` if there is no such element. # Examples ```jldoctest @@ -1592,8 +1599,8 @@ julia> A = [1 4; 2 2] julia> findfirst(iseven, A) 2 -julia> findfirst(x -> x>10, A) -0 +julia> findfirst(x -> x>10, A) == nothing +true julia> findfirst(equalto(4), A) 3 @@ -1604,7 +1611,7 @@ findfirst(testf::Function, A) = findnext(testf, A, 1) """ findprev(A, i::Integer) -Find the previous linear index <= `i` of a `true` element of `A`, or `0` if not found. +Find the previous linear index <= `i` of a `true` element of `A`, or `nothing` if not found. # Examples ```jldoctest @@ -1616,8 +1623,8 @@ julia> A = [false false; true true] julia> findprev(A,2) 2 -julia> findprev(A,1) -0 +julia> findprev(A,1) == nothing +true ``` """ function findprev(A, start::Integer) @@ -1632,14 +1639,14 @@ function findprev(A, start::Integer) a != 0 && return i i = prevind(A, i) end - return 0 + return nothing end """ findlast(A) Return the linear index of the last `true` value in `A`. -Return `0` if there is no `true` value in `A`. +Return `nothing` if there is no `true` value in `A`. # Examples ```jldoctest @@ -1653,8 +1660,8 @@ julia> findlast(A) julia> A = falses(2,2); -julia> findlast(A) -0 +julia> findlast(A) == nothing +true ``` """ findlast(A) = findprev(A, endof(A)) @@ -1663,7 +1670,7 @@ findlast(A) = findprev(A, endof(A)) findprev(predicate::Function, A, i::Integer) Find the previous linear index <= `i` of an element of `A` for which `predicate` returns `true`, or -`0` if not found. +`nothing` if not found. # Examples ```jldoctest @@ -1672,8 +1679,8 @@ julia> A = [4 6; 1 2] 4 6 1 2 -julia> findprev(isodd, A, 1) -0 +julia> findprev(isodd, A, 1) == nothing +true julia> findprev(isodd, A, 3) 2 @@ -1685,14 +1692,14 @@ function findprev(testf::Function, A, start::Integer) testf(A[i]) && return i i = prevind(A, i) end - return 0 + return nothing end """ findlast(predicate::Function, A) Return the linear index of the last element of `A` for which `predicate` returns `true`. -Return `0` if there is no such element. +Return `nothing` if there is no such element. # Examples ```jldoctest @@ -1704,8 +1711,8 @@ julia> A = [1 2; 3 4] julia> findlast(isodd, A) 2 -julia> findlast(x -> x > 5, A) -0 +julia> findlast(x -> x > 5, A) == nothing +true ``` """ findlast(testf::Function, A) = findprev(testf, A, endof(A)) @@ -1713,57 +1720,87 @@ findlast(testf::Function, A) = findprev(testf, A, endof(A)) """ find(f::Function, A) -Return a vector `I` of the linear indices of `A` where `f(A[I])` returns `true`. +Return a vector `I` of the indices or keys of `A` where `f(A[I])` returns `true`. If there are no such elements of `A`, return an empty array. +Indices or keys are of the same type as those returned by [`keys(A)`](@ref) +and [`pairs(A)`](@ref) for `AbstractArray`, `AbstractDict`, `AbstractString` +`Tuple` and `NamedTuple` objects, and are linear indices starting at `1` +for other iterables. + # Examples ```jldoctest +julia> x = [1, 3, 4] +3-element Array{Int64,1}: + 1 + 3 + 4 + +julia> find(isodd, x) +2-element Array{Int64,1}: + 1 + 2 + julia> A = [1 2 0; 3 4 0] 2×3 Array{Int64,2}: 1 2 0 3 4 0 - julia> find(isodd, A) -2-element Array{Int64,1}: - 1 - 2 +2-element Array{CartesianIndex{2},1}: + CartesianIndex(1, 1) + CartesianIndex(2, 1) julia> find(!iszero, A) -4-element Array{Int64,1}: - 1 - 2 - 3 - 4 +4-element Array{CartesianIndex{2},1}: + CartesianIndex(1, 1) + CartesianIndex(2, 1) + CartesianIndex(1, 2) + CartesianIndex(2, 2) + +julia> d = Dict(:A => 10, :B => -1, :C => 0) +Dict{Symbol,Int64} with 3 entries: + :A => 10 + :B => -1 + :C => 0 + +julia> find(x -> x >= 0, d) +2-element Array{Symbol,1}: + :A + :C -julia> find(isodd, [2, 4]) -0-element Array{Int64,1} ``` """ -function find(testf::Function, A) - # use a dynamic-length array to store the indices, then copy to a non-padded - # array for the return - tmpI = Vector{Int}() - inds = _index_remapper(A) - for (i,a) = enumerate(A) - if testf(a) - push!(tmpI, inds[i]) - end - end - I = Vector{Int}(uninitialized, length(tmpI)) - copyto!(I, tmpI) - return I -end -_index_remapper(A::AbstractArray) = linearindices(A) -_index_remapper(iter) = OneTo(typemax(Int)) # safe for objects that don't implement length +find(testf::Function, A) = collect(first(p) for p in _pairs(A) if testf(last(p))) + +_pairs(A::Union{AbstractArray, AbstractDict, AbstractString, Tuple, NamedTuple}) = pairs(A) +_pairs(iter) = zip(OneTo(typemax(Int)), iter) # safe for objects that don't implement length """ find(A) -Return a vector of the linear indices of the `true` values in `A`. +Return a vector `I` of the `true` indices or keys of `A`. +If there are no such elements of `A`, return an empty array. To search for other kinds of values, pass a predicate as the first argument. +Indices or keys are of the same type as those returned by [`keys(A)`](@ref) +and [`pairs(A)`](@ref) for `AbstractArray`, `AbstractDict`, `AbstractString` +`Tuple` and `NamedTuple` objects, and are linear indices starting at `1` +for other iterables. + # Examples ```jldoctest +julia> A = [true, false, false, true] +4-element Array{Bool,1}: + true + false + false + true + +julia> find(A) +2-element Array{Int64,1}: + 1 + 4 + julia> A = [true false; false true] 2×2 Array{Bool,2}: true false @@ -1779,22 +1816,10 @@ julia> find(falses(3)) ``` """ function find(A) - nnzA = count(t -> t != 0, A) - I = Vector{Int}(uninitialized, nnzA) - cnt = 1 - inds = _index_remapper(A) - warned = false - for (i,a) in enumerate(A) - if !warned && !(a isa Bool) - depwarn("In the future `find(A)` will only work on boolean collections. Use `find(x->x!=0, A)` instead.", :find) - warned = true - end - if a != 0 - I[cnt] = inds[i] - cnt += 1 - end + if !(eltype(A) === Bool) && !all(x -> x isa Bool, A) + depwarn("In the future `find(A)` will only work on boolean collections. Use `find(x->x!=0, A)` instead.", :find) end - return I + collect(first(p) for p in _pairs(A) if last(p) != 0) end find(x::Bool) = x ? [1] : Vector{Int}() @@ -2117,7 +2142,7 @@ The function `f` is passed one argument. # Examples ```jldoctest -julia> filter!(isodd, collect(1:10)) +julia> filter!(isodd, Vector(1:10)) 5-element Array{Int64,1}: 1 3 diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 9fc7f6e9e144b..e731588de8e85 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -166,7 +166,7 @@ function print_matrix(io::IO, X::AbstractVecOrMat, screenwidth -= length(pre) + length(post) presp = repeat(" ", length(pre)) # indent each row to match pre string postsp = "" - @assert Unicode.textwidth(hdots) == Unicode.textwidth(ddots) + @assert textwidth(hdots) == textwidth(ddots) sepsize = length(sep) rowsA, colsA = axes(X,1), axes(X,2) m, n = length(rowsA), length(colsA) diff --git a/base/asyncmap.jl b/base/asyncmap.jl index ff8853bfd1cc3..6b66799f06dbb 100644 --- a/base/asyncmap.jl +++ b/base/asyncmap.jl @@ -124,7 +124,7 @@ function verify_ntasks(iterable, ntasks) end if ntasks == 0 - chklen = iteratorsize(iterable) + chklen = IteratorSize(iterable) if (chklen == HasLength()) || (chklen == HasShape()) ntasks = max(1,min(100, length(iterable))) else @@ -260,13 +260,6 @@ function asyncmap(f, b::BitArray; kwargs...) return b2 end -# TODO: Optimize for sparse arrays -# For now process as regular arrays and convert back -function asyncmap(f, s::AbstractSparseArray...; kwargs...) - sa = map(Array, s) - return sparse(asyncmap(f, sa...; kwargs...)) -end - mutable struct AsyncCollector f results @@ -408,7 +401,7 @@ end # pass-through iterator traits to the iterable # on which the mapping function is being applied -iteratorsize(itr::AsyncGenerator) = iteratorsize(itr.collector.enumerator) +IteratorSize(itr::AsyncGenerator) = IteratorSize(itr.collector.enumerator) size(itr::AsyncGenerator) = size(itr.collector.enumerator) length(itr::AsyncGenerator) = length(itr.collector.enumerator) diff --git a/base/bitarray.jl b/base/bitarray.jl index 6088e1c8909ea..f17fdc018e44c 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -530,7 +530,7 @@ julia> BitArray(x+y == 3 for x = 1:2 for y = 1:3) false ``` """ -BitArray(itr) = gen_bitarray(iteratorsize(itr), itr) +BitArray(itr) = gen_bitarray(IteratorSize(itr), itr) # generic constructor from an iterable without compile-time info # (we pass start(itr) explicitly to avoid a type-instability with filters) @@ -1459,13 +1459,13 @@ function unsafe_bitfindnext(Bc::Vector{UInt64}, start::Integer) end end end - return 0 + return nothing end -# returns the index of the next non-zero element, or 0 if all zeros +# returns the index of the next true element, or nothing if all false function findnext(B::BitArray, start::Integer) start > 0 || throw(BoundsError(B, start)) - start > length(B) && return 0 + start > length(B) && return nothing unsafe_bitfindnext(B.chunks, start) end @@ -1474,11 +1474,11 @@ end # aux function: same as findnext(~B, start), but performed without temporaries function findnextnot(B::BitArray, start::Integer) start > 0 || throw(BoundsError(B, start)) - start > length(B) && return 0 + start > length(B) && return nothing Bc = B.chunks l = length(Bc) - l == 0 && return 0 + l == 0 && return nothing chunk_start = _div64(start-1)+1 within_chunk_start = _mod64(start-1) @@ -1499,15 +1499,16 @@ function findnextnot(B::BitArray, start::Integer) elseif Bc[l] | mask != _msk_end(B) return (l-1) << 6 + trailing_ones(Bc[l] | mask) + 1 end - return 0 + return nothing end findfirstnot(B::BitArray) = findnextnot(B,1) # returns the index of the first matching element -function findnext(B::BitArray, v, start::Integer) +function findnext(pred::EqualTo, B::BitArray, start::Integer) + v = pred.x v == false && return findnextnot(B, start) v == true && return findnext(B, start) - return 0 + return nothing end #findfirst(B::BitArray, v) = findnext(B, 1, v) ## defined in array.jl @@ -1519,9 +1520,9 @@ function findnext(testf::Function, B::BitArray, start::Integer) f0 && !f1 && return findnextnot(B, start) start > 0 || throw(BoundsError(B, start)) - start > length(B) && return 0 + start > length(B) && return nothing f0 && f1 && return Int(start) - return 0 # last case: !f0 && !f1 + return nothing # last case: !f0 && !f1 end #findfirst(testf::Function, B::BitArray) = findnext(testf, B, 1) ## defined in array.jl @@ -1540,18 +1541,18 @@ function unsafe_bitfindprev(Bc::Vector{UInt64}, start::Integer) end end end - return 0 + return nothing end -# returns the index of the previous non-zero element, or 0 if all zeros +# returns the index of the previous true element, or nothing if all false function findprev(B::BitArray, start::Integer) - start > 0 || return 0 + start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) unsafe_bitfindprev(B.chunks, start) end function findprevnot(B::BitArray, start::Integer) - start > 0 || return 0 + start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) Bc = B.chunks @@ -1570,15 +1571,16 @@ function findprevnot(B::BitArray, start::Integer) end end end - return 0 + return nothing end findlastnot(B::BitArray) = findprevnot(B, length(B)) # returns the index of the previous matching element -function findprev(B::BitArray, v, start::Integer) +function findprev(pred::EqualTo, B::BitArray, start::Integer) + v = pred.x v == false && return findprevnot(B, start) v == true && return findprev(B, start) - return 0 + return nothing end #findlast(B::BitArray, v) = findprev(B, 1, v) ## defined in array.jl @@ -1589,30 +1591,30 @@ function findprev(testf::Function, B::BitArray, start::Integer) !f0 && f1 && return findprev(B, start) f0 && !f1 && return findprevnot(B, start) - start > 0 || return 0 + start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) f0 && f1 && return Int(start) - return 0 # last case: !f0 && !f1 + return nothing # last case: !f0 && !f1 end #findlast(testf::Function, B::BitArray) = findprev(testf, B, 1) ## defined in array.jl function find(B::BitArray) l = length(B) nnzB = count(B) - I = Vector{Int}(uninitialized, nnzB) + ind = first(keys(B)) + I = Vector{typeof(ind)}(uninitialized, nnzB) nnzB == 0 && return I Bc = B.chunks - Bcount = 1 Icount = 1 for i = 1:length(Bc)-1 u = UInt64(1) c = Bc[i] for j = 1:64 if c & u != 0 - I[Icount] = Bcount + I[Icount] = ind Icount += 1 end - Bcount += 1 + ind = nextind(B, ind) u <<= 1 end end @@ -1620,18 +1622,19 @@ function find(B::BitArray) c = Bc[end] for j = 0:_mod64(l-1) if c & u != 0 - I[Icount] = Bcount + I[Icount] = ind Icount += 1 end - Bcount += 1 + ind = nextind(B, ind) u <<= 1 end return I end -findn(B::BitVector) = find(B) +# For performance +find(::typeof(!iszero), B::BitArray) = find(B) -function findn(B::BitMatrix) +function findnz(B::BitMatrix) nnzB = count(B) I = Vector{Int}(uninitialized, nnzB) J = Vector{Int}(uninitialized, nnzB) @@ -1643,11 +1646,6 @@ function findn(B::BitMatrix) cnt += 1 end end - return I, J -end - -function findnz(B::BitMatrix) - I, J = findn(B) return I, J, trues(length(I)) end diff --git a/base/bitset.jl b/base/bitset.jl index 9304fc3051ab5..14d0efcf7e8d7 100644 --- a/base/bitset.jl +++ b/base/bitset.jl @@ -68,14 +68,16 @@ function _bits_findnext(b::Bits, start::Int) # start is 0-based # @assert start >= 0 _div64(start) + 1 > length(b) && return -1 - unsafe_bitfindnext(b, start+1) - 1 + ind = unsafe_bitfindnext(b, start+1) + ind === nothing ? -1 : ind - 1 end function _bits_findprev(b::Bits, start::Int) # start is 0-based # @assert start <= 64 * length(b) - 1 start >= 0 || return -1 - unsafe_bitfindprev(b, start+1) - 1 + ind = unsafe_bitfindprev(b, start+1) + ind === nothing ? -1 : ind - 1 end # An internal function for setting the inclusion bit for a given integer @@ -356,33 +358,9 @@ function ==(s1::BitSet, s2::BitSet) return true end -issubset(a::BitSet, b::BitSet) = isequal(a, intersect(a,b)) -<(a::BitSet, b::BitSet) = (a<=b) && !isequal(a,b) -<=(a::BitSet, b::BitSet) = issubset(a, b) +issubset(a::BitSet, b::BitSet) = a == intersect(a,b) +⊊(a::BitSet, b::BitSet) = a <= b && a != b -const hashis_seed = UInt === UInt64 ? 0x88989f1fc7dea67d : 0xc7dea67d -function hash(s::BitSet, h::UInt) - h ⊻= hashis_seed - bc = s.bits - i = 1 - j = length(bc) - - while j > 0 && bc[j] == CHK0 - # Skip trailing empty bytes to prevent extra space from changing the hash - j -= 1 - end - while i <= j && bc[i] == CHK0 - # Skip leading empty bytes to prevent extra space from changing the hash - i += 1 - end - i > j && return h # empty - h = hash(i+s.offset, h) # normalized offset - while j >= i - h = hash(bc[j], h) - j -= 1 - end - h -end minimum(s::BitSet) = first(s) maximum(s::BitSet) = last(s) diff --git a/base/boot.jl b/base/boot.jl index 900a82c588229..922f5a3098b9a 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -111,7 +111,6 @@ # parent::Task # storage::Any # state::Symbol -# consumers::Any # donenotify::Any # result::Any # exception::Any @@ -212,8 +211,6 @@ macro _noinline_meta() Expr(:meta, :noinline) end -function postfixapostrophize end - struct BoundsError <: Exception a::Any i::Any @@ -459,6 +456,7 @@ struct GeneratedFunctionStub spnames::Union{Nothing, Array{Any,1}} line::Int file::Symbol + expand_early::Bool end # invoke and wrap the results of @generated diff --git a/base/channels.jl b/base/channels.jl index 5632d0526c791..929f61c7c1de6 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -49,14 +49,6 @@ mutable struct Channel{T} <: AbstractChannel end return ch end - - # deprecated empty constructor - function Channel{T}() where T - depwarn(string("The empty constructor Channel() is deprecated. ", - "The channel size needs to be specified explictly. ", - "Defaulting to Channel{$T}(32)."), :Channel) - Channel(32) - end end Channel(sz) = Channel{Any}(sz) @@ -119,10 +111,6 @@ function Channel(func::Function; ctype=Any, csize=0, taskref=nothing) end - -# deprecated empty constructor -Channel() = Channel{Any}() - closed_exception() = InvalidStateException("Channel is closed.", :closed) isbuffered(c::Channel) = c.sz_max==0 ? false : true @@ -417,4 +405,4 @@ function done(c::Channel, state::ChannelIterState) end next(c::Channel, state) = (v=state.val; state.hasval=false; (v, state)) -iteratorsize(::Type{<:Channel}) = SizeUnknown() +IteratorSize(::Type{<:Channel}) = SizeUnknown() diff --git a/base/char.jl b/base/char.jl index 717881c37d05c..1581123307643 100644 --- a/base/char.jl +++ b/base/char.jl @@ -127,7 +127,7 @@ function show(io::IO, c::Char) (u <<= 8) == 0 && break end write(io, 0x27) - elseif Unicode.isprint(c) + elseif isprint(c) write(io, 0x27, c, 0x27) else # unprintable, well-formed, non-overlong Unicode u = UInt32(c) diff --git a/base/client.jl b/base/client.jl index 77c1b68daf0c3..a3819b9e6c1dc 100644 --- a/base/client.jl +++ b/base/client.jl @@ -41,6 +41,7 @@ const disable_text_style = AnyDict( :hidden => "\033[28m", :normal => "", :default => "", + :nothing => "", ) # Create a docstring with an automatically generated list @@ -148,7 +149,7 @@ function display_error(io::IO, er, bt) print_with_color(Base.error_color(), io, "ERROR: "; bold = true) # remove REPL-related frames from interactive printing eval_ind = findlast(addr->Base.REPL.ip_matches_func(addr, :eval), bt) - if eval_ind != 0 + if eval_ind !== nothing bt = bt[1:eval_ind-1] end showerror(IOContext(io, :limit => true), er, bt) @@ -374,7 +375,6 @@ function _start() (quiet,repl,startup,color_set,history_file) = process_options(opts) banner = opts.banner == 1 - local term global active_repl global active_repl_backend if repl diff --git a/base/combinatorics.jl b/base/combinatorics.jl index a90084b4ff4e0..f08465be40e62 100644 --- a/base/combinatorics.jl +++ b/base/combinatorics.jl @@ -75,7 +75,7 @@ function permute!!(a, p::AbstractVector{<:Integer}) count = 0 start = 0 while count < length(a) - ptr = start = findnext(!iszero, p, start+1) + ptr = start = findnext(!iszero, p, start+1)::Int temp = a[start] next = p[start] count += 1 @@ -125,7 +125,7 @@ function invpermute!!(a, p::AbstractVector{<:Integer}) count = 0 start = 0 while count < length(a) - start = findnext(!iszero, p, start+1) + start = findnext(!iszero, p, start+1)::Int temp = a[start] next = p[start] count += 1 diff --git a/base/deprecated.jl b/base/deprecated.jl index 729a8bd45dc25..bc4d03d3fa985 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -147,187 +147,9 @@ macro deprecate_moved(old, new, export_old=true, default_package=false) Expr(:call, :deprecate, __module__, Expr(:quote, old), 2)) end -# BEGIN 0.6-alpha deprecations (delete when 0.6 is released) - -@deprecate isambiguous(m1::Method, m2::Method, b::Bool) isambiguous(m1, m2, ambiguous_bottom=b) false -# TODO: delete allow_bottom keyword code in Test.detect_ambiguities - -# END 0.6-alpha deprecations - # BEGIN 0.6 deprecations -const _oldstyle_array_vcat_ = false - -@deprecate write(x) write(STDOUT::IO, x) - -function delete!(::EnvDict, k::AbstractString, def) - depwarn("`delete!(ENV, k, def)` should be replaced with `pop!(ENV, k, def)`. Be aware that `pop!` returns `k` or `def`, while `delete!` returns `ENV` or `def`.", :delete!) - haskey(ENV,k) ? delete!(ENV,k) : def -end - -# Deprecate methods that convert Diagonal and Bidiagonal to <:AbstractTriangular. -function convert(::Type{UpperTriangular}, A::Diagonal) - depwarn(string("`convert(::Type{UpperTriangular}, A::Diagonal)` and other methods ", - "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ", - "Consider calling the `UpperTriangular` constructor directly ", - "(`UpperTriangular(A)`) instead."), :convert) - UpperTriangular(A) -end -function convert(::Type{LowerTriangular}, A::Diagonal) - depwarn(string("`convert(::Type{LowerTriangular}, A::Diagonal)` and other methods ", - "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ", - "Consider calling the `LowerTriangular` constructor directly ", - "(`LowerTriangular(A)`) instead."), :convert) - LowerTriangular(A) -end -function convert(::Type{Base.LinAlg.UnitUpperTriangular}, A::Diagonal) - depwarn(string("`convert(::Type{UnitUpperTriangular}, A::Diagonal)` and other methods ", - "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ", - "Consider calling the `UnitUpperTriangular` constructor directly ", - "(`Base.LinAlg.UnitUpperTriangular(A)`) instead."), :convert) - if !all(x -> x == oneunit(x), A.diag) - throw(ArgumentError("matrix cannot be represented as UnitUpperTriangular")) - end - Base.LinAlg.UnitUpperTriangular(Array(A)) -end -function convert(::Type{Base.LinAlg.UnitLowerTriangular}, A::Diagonal) - depwarn(string("`convert(::Type{UnitLowerTriangular}, A::Diagonal)` and other methods ", - "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ", - "Consider calling the `UnitLowerTriangular` constructor directly ", - "(`Base.LinAlg.UnitLowerTriangular(A)`) instead."), :convert) - if !all(x -> x == oneunit(x), A.diag) - throw(ArgumentError("matrix cannot be represented as UnitLowerTriangular")) - end - Base.LinAlg.UnitLowerTriangular(Array(A)) -end -function convert(::Type{LowerTriangular}, A::Bidiagonal) - depwarn(string("`convert(::Type{LowerTriangular}, A::Bidiagonal)` and other methods ", - "that convert `Diagonal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ", - "Consider calling the `LowerTriangular` constructor directly (`LowerTriangular(A)`) ", - "instead."), :convert) - if !A.isupper - LowerTriangular(Array(A)) - else - throw(ArgumentError("Bidiagonal matrix must have lower off diagonal to be converted to LowerTriangular")) - end -end -function convert(::Type{UpperTriangular}, A::Bidiagonal) - depwarn(string("`convert(::Type{UpperTriangular}, A::Bidiagonal)` and other methods ", - "that convert `Diagoinal`/`Bidiagonal` to `<:AbstractTriangular` are deprecated. ", - "Consider calling the `UpperTriangular` constructor directly (`UpperTriangular(A)`) ", - "instead."), :convert) - if A.isupper - UpperTriangular(Array(A)) - else - throw(ArgumentError("Bidiagonal matrix must have upper off diagonal to be converted to UpperTriangular")) - end -end - -# Deprecate three-arg SubArray since the constructor doesn't need the dims tuple -@deprecate SubArray(parent::AbstractArray, indices::Tuple, dims::Tuple) SubArray(parent, indices) - -# Deprecate vectorized unary functions over sparse matrices in favor of compact broadcast syntax (#17265). -for f in (:sind, :asind, :tand, :atand, :sinpi, :cosc, :ceil, :floor, :trunc, - :round, :log1p, :expm1, :abs, :abs2, :log2, :log10, :exp2, :exp10, - :sinc, :cospi, :cosd, :acosd, :cotd, :acotd, :secd, :cscd) - @eval import .Math: $f - @eval @deprecate $f(A::SparseMatrixCSC) $f.(A) -end - -# For deprecating vectorized functions in favor of compact broadcast syntax -macro dep_vectorize_1arg(S, f) - AbstractArray = GlobalRef(Base, :AbstractArray) - return esc(:( @deprecate $f(x::$AbstractArray{T}) where {T<:$S} $f.(x) )) -end -macro dep_vectorize_2arg(S, f) - AbstractArray = GlobalRef(Base, :AbstractArray) - return esc(quote - @deprecate $f(x::$S, y::$AbstractArray{T1}) where {T1<:$S} $f.(x, y) - @deprecate $f(x::$AbstractArray{T1}, y::$S) where {T1<:$S} $f.(x, y) - @deprecate $f(x::$AbstractArray{T1}, y::$AbstractArray{T2}) where {T1<:$S, T2<:$S} $f.(x, y) - end) -end - -# Deprecate @vectorize_1arg-vectorized functions from... -for f in ( - # base/special/trig.jl - :sinpi, :cospi, :sinc, :cosc, - # base/special/log.jl - :log1p, - # base/special/gamma.jl - :gamma, :lfact, - # base/math.jl - :cbrt, :exp2, :expm1, :exp10, :log2, :log10, :lgamma, #=:log1p,=# - # base/floatfuncs.jl - :abs, :abs2, :angle, :isnan, :isinf, :isfinite, - # base/complex.jl - :cis, - ) - @eval import .Math: $f - @eval @dep_vectorize_1arg Number $f -end -# base/fastmath.jl -for f in ( :acos_fast, :acosh_fast, :angle_fast, :asin_fast, :asinh_fast, - :atan_fast, :atanh_fast, :cbrt_fast, :cis_fast, :cos_fast, - :cosh_fast, :exp10_fast, :exp2_fast, :exp_fast, :expm1_fast, - :lgamma_fast, :log10_fast, :log1p_fast, :log2_fast, :log_fast, - :sin_fast, :sinh_fast, :sqrt_fast, :tan_fast, :tanh_fast ) - @eval import .FastMath: $f - @eval @dep_vectorize_1arg Number $f -end -for f in ( - :trunc, :floor, :ceil, :round, # base/floatfuncs.jl - :rad2deg, :deg2rad, :exponent, :significand, # base/math.jl - :sind, :cosd, :tand, :asind, :acosd, :atand, :asecd, :acscd, :acotd, # base/special/trig.jl - ) - @eval import .Math: $f - @eval @dep_vectorize_1arg Real $f -end -# base/complex.jl -@dep_vectorize_1arg Complex round -@dep_vectorize_1arg Complex float - -# Deprecate @vectorize_2arg-vectorized functions from... -for f in ( - # base/special/gamma.jl - :beta, :lbeta, - # base/math.jl - :log, :hypot, :atan2, - ) - @eval import .Math: $f - @eval @dep_vectorize_2arg Number $f -end -# base/fastmath.jl -for f in (:pow_fast, :atan2_fast, :hypot_fast, :max_fast, :min_fast, :minmax_fast) - @eval import .FastMath: $f - @eval @dep_vectorize_2arg Number $f -end -for f in ( - :max, :min, # base/math.jl - :copysign, :flipsign, # base/floatfuncs.jl - ) - @eval @dep_vectorize_2arg Real $f -end - -# Deprecate @vectorize_1arg and @vectorize_2arg themselves -macro vectorize_1arg(S, f) - depwarn(string("`@vectorize_1arg` is deprecated in favor of compact broadcast syntax. ", - "Instead of `@vectorize_1arg`'ing function `f` and calling `f(arg)`, call `f.(arg)`."), - :vectorize_1arg) - quote - @dep_vectorize_1arg($S, $f) - end -end -macro vectorize_2arg(S, f) - depwarn(string("`@vectorize_2arg` is deprecated in favor of compact broadcast syntax. ", - "Instead of `@vectorize_2arg`'ing function `f` and calling `f(arg1, arg2)`, call ", - "`f.(arg1, arg2)`. "), :vectorize_2arg) - quote - @dep_vectorize_2arg($S, $f) - end -end -export @vectorize_1arg, @vectorize_2arg - +# removing the .op deprecations breaks a few things. TODO: fix # deprecations for uses of old dot operators (.* etc) as objects, rather than # just calling them infix. for op in (:(!=), :≠, :+, :-, :*, :/, :÷, :%, :<, :(<=), :≤, :(==), :>, :>=, :≥, :\, :^, ://, :>>, :<<) @@ -342,478 +164,6 @@ for op in (:(!=), :≠, :+, :-, :*, :/, :÷, :%, :<, :(<=), :≤, :(==), :>, :>= @eval export $dotop end -# Devectorize manually vectorized abs methods in favor of compact broadcast syntax -@deprecate abs(f::Base.Pkg.Resolve.MaxSum.Field) abs.(f) -@deprecate abs(B::BitArray) abs.(B) -@deprecate abs(M::Bidiagonal) abs.(M) -@deprecate abs(D::Diagonal) abs.(D) -@deprecate abs(M::Tridiagonal) abs.(M) -@deprecate abs(M::SymTridiagonal) abs.(M) -@deprecate abs(x::AbstractSparseVector) abs.(x) - -# Deprecate @textmime into the Multimedia module, #18441 -@eval Multimedia macro textmime(mime) - Base.depwarn(string("`@textmime \"mime\"` is deprecated, use ", - "`Base.Multimedia.istextmime(::MIME\"mime\") = true` instead." - ), :textmime) - quote - Base.Multimedia.istextmime(::MIME{$(Meta.quot(Symbol(mime)))}) = true - end -end - -@deprecate ipermutedims(A::AbstractArray,p) permutedims(A, invperm(p)) - -# PR #25168 -@deprecate ipermute!(a, p::AbstractVector) invpermute!(a, p) - -# 18696 -function ($)(x, y) - depwarn("`x \$ y` is deprecated. use `xor(x, y)` or `x ⊻ y` instead.", :$) - xor(x, y) -end -export $ - -@deprecate is (===) - -# midpoints of intervals -@deprecate midpoints(r::AbstractRange) r[1:length(r)-1] + 0.5*step(r) -@deprecate midpoints(v::AbstractVector) [0.5*(v[i] + v[i+1]) for i in 1:length(v)-1] - -@deprecate_binding Filter Iterators.Filter -@deprecate_binding Zip Iterators.Zip -@deprecate filter(flt, itr) Iterators.filter(flt, itr) -@deprecate_binding rest Iterators.rest -@deprecate_binding countfrom Iterators.countfrom -@deprecate_binding take Iterators.take -@deprecate_binding drop Iterators.drop -@deprecate_binding cycle Iterators.cycle -@deprecate_binding repeated Iterators.repeated - -# promote_op method where the operator is also a type -function promote_op(op::Type, Ts::Type...) - depwarn("`promote_op(op::Type, ::Type...)` is deprecated as it is no " * - "longer needed in Base. If you need its functionality, consider " * - "defining it locally.", :promote_op) - if isdefined(Core, :Inference) - return Core.Inference.return_type(op, Tuple{Ts...}) - end - return op -end - -# NOTE: Deprecation of `isdefined(a::Array, i::Int)` is implemented in src/array.c -# and deprecation of `invoke(f, (types...), ...)` is implemented in src/builtins.c -# To be removed when 0.6 deprecations are removed - -# NOTE: Deprecation of Channel{T}() is implemented in channels.jl. -# To be removed from there when 0.6 deprecations are removed. - -# Not exported, but probably better to have deprecations anyway -function reduced_dims(::Tuple{}, d::Int) - d < 1 && throw(ArgumentError("dimension must be ≥ 1, got $d")) - () -end -reduced_dims(::Tuple{}, region) = () -function reduced_dims(dims::Dims, region) - Base.depwarn("`reduced_dims` is deprecated for Dims-tuples; pass `indices` to `reduced_indices` instead", :reduced_dims) - map(last, reduced_indices(map(OneTo, dims), region)) -end - -function reduced_dims0(::Tuple{}, d::Int) - d < 1 && throw(ArgumentError("dimension must be ≥ 1, got $d")) - () -end -reduced_dims0(::Tuple{}, region) = () -function reduced_dims0(dims::Dims, region) - Base.depwarn("`reduced_dims0` is deprecated for Dims-tuples; pass `indices` to `reduced_indices0` instead", :reduced_dims0) - map(last, reduced_indices0(map(OneTo, dims), region)) -end - -function reduced_dims(a::AbstractArray, region) - Base.depwarn("`reduced_dims` is deprecated in favor of `reduced_indices`", :reduced_dims) - to_shape(reduced_indices(a, region)) # to_shape keeps the return-type consistent, when it's possible to do so -end - -function reduced_dims0(a::AbstractArray, region) - Base.depwarn("`reduced_dims0` is deprecated in favor of `reduced_indices0`", :reduced_dims) - to_shape(reduced_indices0(a, region)) -end - -# #18218 -@eval Base.LinAlg begin - function arithtype(T) - Base.depwarn(string("`arithtype` is deprecated. If you were using it inside a ", - "promote_op call, use `promote_op(LinAlg.matprod, Ts...)` instead. Otherwise, ", - "if you need its functionality, consider defining it locally."), - :arithtype) - T - end - function arithtype(::Type{Bool}) - Base.depwarn(string("`arithtype` is deprecated. If you were using it inside a ", - "promote_op call, use `promote_op(LinAlg.matprod, Ts...)` instead. Otherwise, ", - "if you need its functionality, consider defining it locally."), - :arithtype) - Int - end -end - -# #19246 -@deprecate den denominator -@deprecate num numerator - -# #19088 -@deprecate takebuf_array take! -@deprecate takebuf_string(b) String(take!(b)) - -# Index conversions revamp; #19730 -function getindex(A::LogicalIndex, i::Int) - depwarn("`getindex(A::LogicalIndex, i)` is deprecated, use iteration or index into the result of `collect(A)` instead.", :getindex) - checkbounds(A, i) - first(Iterators.drop(A, i-1)) -end -function to_indexes(I...) - Istr = join(I, ", ") - depwarn("`to_indexes` is deprecated, pass both the source array `A` and indices as `to_indices(A, $Istr)` instead.", :to_indexes) - map(_to_index, I) -end -_to_index(i) = to_index(I) -_to_index(c::Colon) = c -const _colon_usage_msg = "convert Colons to a set of indices for indexing into array `A` by passing them in a complete tuple of indices `I` to `to_indices(A, I)`." -function getindex(::Colon, i) - depwarn("`getindex(::Colon, i)` is deprecated, $_colon_usage_msg", :getindex) - to_index(i) -end -function unsafe_getindex(::Colon, i::Integer) - depwarn("`getindex(::Colon, i)` is deprecated, $_colon_usage_msg", :unsafe_getindex) - to_index(i) -end -function step(::Colon) - depwarn("`step(::Colon)` is deprecated, $_colon_usage_msg", :step) - 1 -end -function isempty(::Colon) - depwarn("`isempty(::Colon)` is deprecated, $_colon_usage_msg", :isempty) - false -end -function in(::Integer, ::Colon) - depwarn("`in(::Integer, ::Colon)` is deprecated, $_colon_usage_msg", :in) - true -end - -# #18931 -@deprecate cummin(A, dim=1) accumulate(min, A, dim) -@deprecate cummax(A, dim=1) accumulate(max, A, dim) - -# #19598 -@deprecate sumabs(x) sum(abs, x) -@deprecate sumabs(A, region) sum(abs, A, region) -@deprecate sumabs2(x) sum(abs2, x) -@deprecate sumabs2(A, region) sum(abs2, A, region) -@deprecate minabs(x) minimum(abs, x) -@deprecate minabs(A, region) minimum(abs, A, region) -@deprecate maxabs(x) maximum(abs, x) -@deprecate maxabs(A, region) maximum(abs, A, region) - -for (dep, f, op) in [(:sumabs!, :sum!, :abs), - (:sumabs2!, :sum!, :abs2), - (:minabs!, :minimum!, :abs), - (:maxabs!, :maximum!, :abs)] - @eval function ($dep)(r, A; init=true) - Base.depwarn("`$dep(r, A; init=$init)` is deprecated, use `$f($op, r, A; init=$init)` instead.", Symbol($dep)) - ($f)($op, r, A; init=init) - end -end - -## Deprecate broadcast_zpreserving[!] (wasn't exported, but might as well be friendly) -function gen_broadcast_function_sparse(genbody::Function, f::Function, is_first_sparse::Bool) - body = genbody(f, is_first_sparse) - @eval let - local _F_ - function _F_(B::SparseMatrixCSC{Tv,Ti}, A_1, A_2) where {Tv,Ti} - $body - end - _F_ - end -end -function gen_broadcast_body_zpreserving(f::Function, is_first_sparse::Bool) - F = Expr(:quote, f) - if is_first_sparse - A1 = :(A_1) - A2 = :(A_2) - op1 = :(val1) - op2 = :(val2) - else - A1 = :(A_2) - A2 = :(A_1) - op1 = :(val2) - op2 = :(val1) - end - quote - Base.Broadcast.check_broadcast_indices(axes(B), $A1) - Base.Broadcast.check_broadcast_indices(axes(B), $A2) - - nnzB = isempty(B) ? 0 : - nnz($A1) * div(B.n, ($A1).n) * div(B.m, ($A1).m) - if length(B.rowval) < nnzB - resize!(B.rowval, nnzB) - end - if length(B.nzval) < nnzB - resize!(B.nzval, nnzB) - end - z = zero(Tv) - - ptrB = 1 - B.colptr[1] = 1 - - @inbounds for col = 1:B.n - ptr1::Int = ($A1).n == 1 ? ($A1).colptr[1] : ($A1).colptr[col] - stop1::Int = ($A1).n == 1 ? ($A1).colptr[2] : ($A1).colptr[col+1] - col2 = size($A2, 2) == 1 ? 1 : col - row = 1 - while ptr1 < stop1 && row <= B.m - if ($A1).m != 1 - row = ($A1).rowval[ptr1] - end - row2 = size($A2, 1) == 1 ? 1 : row - val1 = ($A1).nzval[ptr1] - val2 = ($A2)[row2,col2] - res = ($F)($op1, $op2) - if res != z - B.rowval[ptrB] = row - B.nzval[ptrB] = res - ptrB += 1 - end - if ($A1).m != 1 - ptr1 += 1 - else - row += 1 - end - end - B.colptr[col+1] = ptrB - end - deleteat!(B.rowval, B.colptr[end]:length(B.rowval)) - deleteat!(B.nzval, B.colptr[end]:length(B.nzval)) - nothing - end -end -for (Bsig, A1sig, A2sig, gbb, funcname) in - ( - (SparseMatrixCSC , SparseMatrixCSC , Array, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), - (SparseMatrixCSC , Array , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), - (SparseMatrixCSC , Number , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), - (SparseMatrixCSC , SparseMatrixCSC , Number, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), - (SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), - (SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), - ) - @eval let cache = Dict{Function,Function}() - global $funcname - function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig) - func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC) - # need eval because func was just created by gen_broadcast_function_sparse - # TODO: convert this to a generated function - eval(_current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2))))) - return B - end - end # let broadcast_cache -end -_broadcast_zpreserving!(args...) = broadcast!(args...) -# note: promote_eltype_op also deprecated, defined later in this file -_broadcast_zpreserving(f, As...) = - broadcast!(f, similar(Array{_promote_eltype_op(f, As...)}, Base.Broadcast.broadcast_indices(As...)), As...) -_broadcast_zpreserving(f::Function, A_1::SparseMatrixCSC{Tv1,Ti1}, A_2::SparseMatrixCSC{Tv2,Ti2}) where {Tv1,Ti1,Tv2,Ti2} = - _broadcast_zpreserving!(f, spzeros(promote_type(Tv1, Tv2), promote_type(Ti1, Ti2), Base.to_shape(Base.Broadcast.broadcast_indices(A_1, A_2))), A_1, A_2) -_broadcast_zpreserving(f::Function, A_1::SparseMatrixCSC{<:Any,Ti}, A_2::Union{Array,BitArray,Number}) where {Ti} = - _broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, Base.to_shape(Base.Broadcast.broadcast_indices(A_1, A_2))), A_1, A_2) -_broadcast_zpreserving(f::Function, A_1::Union{Array,BitArray,Number}, A_2::SparseMatrixCSC{<:Any,Ti}) where {Ti} = - _broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, Base.to_shape(Base.Broadcast.broadcast_indices(A_1, A_2))), A_1, A_2) - -function _depstring_bczpres() - return string("broadcast_zpreserving[!] is deprecated. Generic sparse broadcast[!] ", - "provides most of broadcast_zpreserving[!]'s functionality. If you have a use case ", - "that generic sparse broadcast[!] does not cover, please describe your use case in ", - " issue #19533 (https://github.com/JuliaLang/julia/issues/19533).") -end -function _depwarn_bczpres(f, args...) - depwarn(_depstring_bczpres(), :broadcast_zpreserving) - return _broadcast_zpreserving(f, args...) -end -function _depwarn_bczpres!(f, args...) - depwarn(_depstring_bczpres(), :broadcast_zpreserving!) - return _broadcast_zpreserving!(f, args...) -end -@eval SparseArrays begin - broadcast_zpreserving(f, args...) = Base._depwarn_bczpres(f, args...) - broadcast_zpreserving(f, A::SparseMatrixCSC, B::SparseMatrixCSC) = Base._depwarn_bczpres(f, A, B) - broadcast_zpreserving(f, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = Base._depwarn_bczpres(f, A, B) - broadcast_zpreserving(f, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = Base._depwarn_bczpres(f, A, B) - broadcast_zpreserving!(f, args...) = Base._depwarn_bczpres!(f, args...) - broadcast_zpreserving!(f, C::SparseMatrixCSC, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = Base._depwarn_bczpres!(f, C, A, B) - broadcast_zpreserving!(f, C::SparseMatrixCSC, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = Base._depwarn_bczpres!(f, C, A, B) -end - -# #19719 -@deprecate getindex(t::Tuple, r::AbstractArray) getindex(t, vec(r)) -@deprecate getindex(t::Tuple, b::AbstractArray{Bool}) getindex(t, vec(b)) - -# Deprecate isimag (#19947). -@deprecate isimag(z::Number) iszero(real(z)) - -# Deprecate vectorized xor in favor of compact broadcast syntax -@deprecate xor(a::Bool, B::BitArray) xor.(a, B) -@deprecate xor(A::BitArray, b::Bool) xor.(A, b) -@deprecate xor(a::Number, B::AbstractArray) xor.(a, B) -@deprecate xor(A::AbstractArray, b::Number) xor.(A, b) -@deprecate xor(A::AbstractArray, B::AbstractArray) xor.(A, B) - -# Broadcast now returns a BitArray when the resulting eltype is Bool (#17623) -@deprecate bitbroadcast broadcast - -# Deprecate two-argument map! (map!(f, A)) for a cycle in anticipation of semantic change -@deprecate map!(f::F, A::AbstractArray) where {F} map!(f, A, A) -@deprecate asyncmap!(f, c; ntasks=0, batch_size=nothing) asyncmap!(f, c, c; ntasks=ntasks, batch_size=batch_size) - -# Not exported, but used outside Base -_promote_array_type(F, ::Type, ::Type, T::Type) = T -_promote_array_type(F, ::Type{<:Real}, ::Type{A}, ::Type) where {A<:AbstractFloat} = A -_promote_array_type(F, ::Type{<:Integer}, ::Type{A}, ::Type) where {A<:Integer} = A -_promote_array_type(::typeof(/), ::Type{<:Integer}, ::Type{<:Integer}, T::Type) = T -_promote_array_type(::typeof(\), ::Type{<:Integer}, ::Type{<:Integer}, T::Type) = T -_promote_array_type(::typeof(/), ::Type{<:Integer}, ::Type{Bool}, T::Type) = T -_promote_array_type(::typeof(\), ::Type{<:Integer}, ::Type{Bool}, T::Type) = T -_promote_array_type(F, ::Type{<:Integer}, ::Type{Bool}, T::Type) = T -_promote_array_type(F, ::Type{<:Union{Complex, Real}}, ::Type{Complex{T}}, ::Type) where {T<:AbstractFloat} = Complex{T} -function promote_array_type(F, R, S, T) - Base.depwarn("`promote_array_type` is deprecated as it is no longer needed " * - "in Base. See https://github.com/JuliaLang/julia/issues/19669 " * - "for more information.", :promote_array_type) - _promote_array_type(F, R, S, T) -end - -# Deprecate manually vectorized abs2 methods in favor of compact broadcast syntax -@deprecate abs2(x::AbstractSparseVector) abs2.(x) - -# Deprecate manually vectorized sign methods in favor of compact broadcast syntax -@deprecate sign(A::AbstractArray) sign.(A) - -# Deprecate manually vectorized trigonometric and hyperbolic functions in favor of compact broadcast syntax -for f in (:secd, :cscd, :cotd) - @eval import .Math: $f - @eval @deprecate $f(A::AbstractArray{<:Number}) $f.(A) -end - -# Deprecate vectorized two-argument complex in favor of compact broadcast syntax -@deprecate complex(A::AbstractArray, b::Real) complex.(A, b) -@deprecate complex(a::Real, B::AbstractArray) complex.(a, B) -@deprecate complex(A::AbstractArray, B::AbstractArray) complex.(A, B) - -# Deprecate manually vectorized clamp methods in favor of compact broadcast syntax -import .Math: clamp -@deprecate clamp(A::AbstractArray, lo, hi) clamp.(A, lo, hi) - -# Deprecate manually vectorized round methods in favor of compact broadcast syntax -@deprecate round(M::Bidiagonal) round.(M) -@deprecate round(M::Tridiagonal) round.(M) -@deprecate round(M::SymTridiagonal) round.(M) -@deprecate round(::Type{T}, x::AbstractArray) where {T} round.(T, x) -@deprecate round(::Type{T}, x::AbstractArray, r::RoundingMode) where {T} round.(T, x, r) -@deprecate round(x::AbstractArray, r::RoundingMode) round.(x, r) -@deprecate round(x::AbstractArray, digits::Integer, base::Integer = 10) round.(x, digits, base) - -# Deprecate manually vectorized trunc methods in favor of compact broadcast syntax -@deprecate trunc(M::Bidiagonal) trunc.(M) -@deprecate trunc(M::Tridiagonal) trunc.(M) -@deprecate trunc(M::SymTridiagonal) trunc.(M) -@deprecate trunc(::Type{T}, x::AbstractArray) where {T} trunc.(T, x) -@deprecate trunc(x::AbstractArray, digits::Integer, base::Integer = 10) trunc.(x, digits, base) - -# Deprecate manually vectorized floor methods in favor of compact broadcast syntax -@deprecate floor(M::Bidiagonal) floor.(M) -@deprecate floor(M::Tridiagonal) floor.(M) -@deprecate floor(M::SymTridiagonal) floor.(M) -@deprecate floor(::Type{T}, A::AbstractArray) where {T} floor.(T, A) -@deprecate floor(A::AbstractArray, digits::Integer, base::Integer = 10) floor.(A, digits, base) - -# Deprecate manually vectorized ceil methods in favor of compact broadcast syntax -@deprecate ceil(M::Bidiagonal) ceil.(M) -@deprecate ceil(M::Tridiagonal) ceil.(M) -@deprecate ceil(M::SymTridiagonal) ceil.(M) -@deprecate ceil(::Type{T}, x::AbstractArray) where {T} ceil.(T, x) -@deprecate ceil(x::AbstractArray, digits::Integer, base::Integer = 10) ceil.(x, digits, base) - -# Deprecate manually vectorized `big` methods in favor of compact broadcast syntax -@deprecate big(r::UnitRange) big.(r) -@deprecate big(r::StepRange) big.(r) -@deprecate big(r::StepRangeLen) big.(r) -@deprecate big(r::LinSpace) big.(r) -@deprecate big(x::AbstractArray{<:Integer}) big.(x) -@deprecate big(x::AbstractArray{<:AbstractFloat}) big.(x) -@deprecate big(A::LowerTriangular) big.(A) -@deprecate big(A::UpperTriangular) big.(A) -@deprecate big(A::Base.LinAlg.UnitLowerTriangular) big.(A) -@deprecate big(A::Base.LinAlg.UnitUpperTriangular) big.(A) -@deprecate big(B::Bidiagonal) big.(B) -@deprecate big(A::AbstractArray{<:Complex{<:Integer}}) big.(A) -@deprecate big(A::AbstractArray{<:Complex{<:AbstractFloat}}) big.(A) -@deprecate big(x::AbstractArray{<:Complex{<:Rational{<:Integer}}}) big.(A) - -# Deprecate manually vectorized div methods in favor of compact broadcast syntax -@deprecate div(A::Number, B::AbstractArray) div.(A, B) -@deprecate div(A::AbstractArray, B::Number) div.(A, B) -@deprecate div(A::AbstractArray, B::AbstractArray) div.(A, B) - -# Deprecate manually vectorized rem methods in favor of compact broadcast syntax -@deprecate rem(A::Number, B::AbstractArray) rem.(A, B) -@deprecate rem(A::AbstractArray, B::Number) rem.(A, B) - -# Deprecate manually vectorized mod methods in favor of compact broadcast syntax -@deprecate mod(B::BitArray, x::Bool) mod.(B, x) -@deprecate mod(x::Bool, B::BitArray) mod.(x, B) -@deprecate mod(A::AbstractArray, B::AbstractArray) mod.(A, B) -@deprecate mod(x::Number, A::AbstractArray) mod.(x, A) -@deprecate mod(A::AbstractArray, x::Number) mod.(A, x) - -# Deprecate vectorized & in favor of dot syntax -@deprecate (&)(a::Bool, B::BitArray) a .& B -@deprecate (&)(A::BitArray, b::Bool) A .& b -@deprecate (&)(a::Number, B::AbstractArray) a .& B -@deprecate (&)(A::AbstractArray, b::Number) A .& b -@deprecate (&)(A::AbstractArray, B::AbstractArray) A .& B - -# Deprecate vectorized | in favor of compact broadcast syntax -@deprecate (|)(a::Bool, B::BitArray) a .| B -@deprecate (|)(A::BitArray, b::Bool) A .| b -@deprecate (|)(a::Number, B::AbstractArray) a .| B -@deprecate (|)(A::AbstractArray, b::Number) A .| b -@deprecate (|)(A::AbstractArray, B::AbstractArray) A .| B - -# Deprecate vectorized ifelse -@deprecate ifelse(c::AbstractArray{Bool}, x, y) ifelse.(c, x, y) -@deprecate ifelse(c::AbstractArray{Bool}, x, y::AbstractArray) ifelse.(c, x, y) -@deprecate ifelse(c::AbstractArray{Bool}, x::AbstractArray, y) ifelse.(c, x, y) -@deprecate ifelse(c::AbstractArray{Bool}, x::AbstractArray, y::AbstractArray) ifelse.(c, x, y) - -# Deprecate vectorized ! -@deprecate(!(A::AbstractArray{Bool}), .!A) # parens for #20541 -@deprecate(!(B::BitArray), .!B) # parens for #20541 - -# Deprecate vectorized ~ -@deprecate ~(A::AbstractArray) .~A -@deprecate ~(B::BitArray) .~B - -function Math.frexp(A::Array{<:AbstractFloat}) - depwarn(string("`frexp(x::Array)` is discontinued. Though not a direct replacement, ", - "consider using dot-syntax to `broadcast` scalar `frexp` over `Array`s ", - "instead, for example `frexp.(rand(4))`."), :frexp) - F = similar(A) - E = Array{Int}(uninitialized, size(A)) - for (iF, iE, iA) in zip(eachindex(F), eachindex(E), eachindex(A)) - F[iF], E[iE] = frexp(A[iA]) - end - return (F, E) -end - -# Deprecate reducing isinteger over arrays -@deprecate isinteger(A::AbstractArray) all(isinteger, A) - # Deprecate promote_eltype_op (#19814, #19937) _promote_eltype_op(::Any) = Any _promote_eltype_op(op, A) = (@_inline_meta; promote_op(op, eltype(A))) @@ -827,295 +177,12 @@ _promote_eltype_op(op, A, B, C, D...) = (@_inline_meta; _promote_eltype_op(op, e _promote_eltype_op(args...) end - -function unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, len::Integer, own::Bool=false) - Base.depwarn("`unsafe_wrap(String, ...)` is deprecated, use `unsafe_string` instead.", :unsafe_wrap) - #ccall(:jl_array_to_string, Ref{String}, (Any,), - # ccall(:jl_ptr_to_array_1d, Vector{UInt8}, (Any, Ptr{UInt8}, Csize_t, Cint), - # Vector{UInt8}, p, len, own)) - unsafe_string(p, len) -end -unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, own::Bool=false) = - unsafe_wrap(String, p, ccall(:strlen, Csize_t, (Ptr{UInt8},), p), own) -unsafe_wrap(::Type{String}, p::Cstring, own::Bool=false) = unsafe_wrap(String, convert(Ptr{UInt8}, p), own) -unsafe_wrap(::Type{String}, p::Cstring, len::Integer, own::Bool=false) = - unsafe_wrap(String, convert(Ptr{UInt8}, p), len, own) - -# #19660 -@deprecate finalize(sa::LibGit2.StrArrayStruct) LibGit2.free(sa) -@deprecate finalize(sa::LibGit2.Buffer) LibGit2.free(sa) - -## produce, consume, and task iteration -# NOTE: When removing produce/consume, also remove field Task.consumers and related code in -# task.jl and event.jl - -function produce(v) - depwarn("`produce` is deprecated, use Channels for inter-task communication.", :produce) - - ct = current_task() - local empty, t, q - while true - q = ct.consumers - if isa(q,Task) - t = q - ct.consumers = nothing - empty = true - break - elseif isa(q,Condition) && !isempty(q.waitq) - t = popfirst!(q.waitq) - empty = isempty(q.waitq) - break - end - wait() - end - - t.state == :runnable || throw(AssertionError("producer.consumer.state == :runnable")) - if empty - schedule_and_wait(t, v) - while true - # wait until there are more consumers - q = ct.consumers - if isa(q,Task) - return q.result - elseif isa(q,Condition) && !isempty(q.waitq) - return q.waitq[1].result - end - wait() - end - else - schedule(t, v) - # make sure `t` runs before us. otherwise, the producer might - # finish before `t` runs again, causing it to see the producer - # as done, causing done(::Task, _) to miss the value `v`. - # see issue #7727 - yield() - return q.waitq[1].result - end -end -produce(v...) = produce(v) -export produce - -function consume(P::Task, values...) - depwarn("`consume` is deprecated, use Channels for inter-task communication.", :consume) - - if istaskdone(P) - return wait(P) - end - - ct = current_task() - ct.result = length(values)==1 ? values[1] : values - - #### un-optimized version - #if P.consumers === nothing - # P.consumers = Condition() - #end - #push!(P.consumers.waitq, ct) - # optimized version that avoids the queue for 1 consumer - if P.consumers === nothing || (isa(P.consumers,Condition)&&isempty(P.consumers.waitq)) - P.consumers = ct - else - if isa(P.consumers, Task) - t = P.consumers - P.consumers = Condition() - push!(P.consumers.waitq, t) - end - push!(P.consumers.waitq, ct) - end - - P.state == :runnable ? schedule_and_wait(P) : wait() # don't attempt to queue it twice -end -export consume - -function start(t::Task) - depwarn(string("Task iteration is deprecated,", - " use Channels for inter-task communication. ", - " A for-loop on a Channel object is terminated by calling `close` on the object."), :taskfor) - nothing -end -function done(t::Task, val) - t.result = consume(t) - istaskdone(t) -end -next(t::Task, val) = (t.result, nothing) -iteratorsize(::Type{Task}) = SizeUnknown() -iteratoreltype(::Type{Task}) = EltypeUnknown() - -isempty(::Task) = error("isempty not defined for Tasks") - -# Deprecate Array(T, dims...) in favor of proper type constructors -@deprecate Array(::Type{T}, d::NTuple{N,Int}) where {T,N} Array{T}(uninitialized, d) -@deprecate Array(::Type{T}, d::Int...) where {T} Array{T}(uninitialized, d...) -@deprecate Array(::Type{T}, m::Int) where {T} Array{T}(uninitialized, m) -@deprecate Array(::Type{T}, m::Int,n::Int) where {T} Array{T}(uninitialized, m,n) -@deprecate Array(::Type{T}, m::Int,n::Int,o::Int) where {T} Array{T}(uninitialized, m,n,o) -@deprecate Array(::Type{T}, d::Integer...) where {T} Array{T}(uninitialized, convert(Tuple{Vararg{Int}}, d)) -@deprecate Array(::Type{T}, m::Integer) where {T} Array{T}(uninitialized, Int(m)) -@deprecate Array(::Type{T}, m::Integer,n::Integer) where {T} Array{T}(uninitialized, Int(m),Int(n)) -@deprecate Array(::Type{T}, m::Integer,n::Integer,o::Integer) where {T} Array{T}(uninitialized, Int(m),Int(n),Int(o)) - -@noinline function is_intrinsic_expr(@nospecialize(x)) - Base.depwarn("`is_intrinsic_expr` is deprecated. There are no intrinsic functions anymore.", :is_intrinsic_expr) - return false -end - -@deprecate EachLine(stream, ondone) EachLine(stream, ondone=ondone) - -# LibGit2 refactor (#19839) -@eval Base.LibGit2 begin - Base.@deprecate_binding Oid GitHash - Base.@deprecate_binding GitAnyObject GitUnknownObject - - @deprecate owner(x) repository(x) false - @deprecate get(::Type{T}, repo::GitRepo, x) where {T<:GitObject} T(repo, x) false - @deprecate get(::Type{T}, repo::GitRepo, oid::GitHash, oid_size::Int) where {T<:GitObject} T(repo, GitShortHash(oid, oid_size)) false - @deprecate revparse(repo::GitRepo, objname::AbstractString) GitObject(repo, objname) false - @deprecate object(repo::GitRepo, te::GitTreeEntry) GitObject(repo, te) false - @deprecate commit(ann::GitAnnotated) GitHash(ann) false - @deprecate lookup(repo::GitRepo, oid::GitHash) GitBlob(repo, oid) false - function Base.cat(repo::GitRepo, ::Type{T}, spec::Union{AbstractString,AbstractGitHash}) where T<:GitObject - Base.depwarn("`cat(repo::GitRepo, T, spec)` is deprecated, use `content(T(repo, spec))` instead.", :cat) - try - return content(GitBlob(repo, spec)) - catch e - isa(e, LibGit2.GitError) && return nothing - rethrow(e) - end - end - Base.cat(repo::GitRepo, spec::Union{AbstractString,AbstractGitHash}) = cat(repo, GitBlob, spec) -end - -# TODO: remove `:typealias` from BINDING_HEADS in base/docs/Docs.jl -# TODO: remove `'typealias` case in expand-table in julia-syntax.scm - -# FloatRange replaced by StepRangeLen - -## Old-style floating point ranges. We reimplement them here because -## the replacement StepRangeLen also has 4 real-valued fields, which -## makes deprecation tricky. See #20506. - -struct Use_StepRangeLen_Instead{T<:AbstractFloat} <: AbstractRange{T} - start::T - step::T - len::T - divisor::T -end - -Use_StepRangeLen_Instead(a::AbstractFloat, s::AbstractFloat, l::Real, d::AbstractFloat) = - Use_StepRangeLen_Instead{promote_type(typeof(a),typeof(s),typeof(d))}(a,s,l,d) - -isempty(r::Use_StepRangeLen_Instead) = length(r) == 0 - -step(r::Use_StepRangeLen_Instead) = r.step/r.divisor - -length(r::Use_StepRangeLen_Instead) = Integer(r.len) - -first(r::Use_StepRangeLen_Instead{T}) where {T} = convert(T, r.start/r.divisor) - -last(r::Use_StepRangeLen_Instead{T}) where {T} = convert(T, (r.start + (r.len-1)*r.step)/r.divisor) - -start(r::Use_StepRangeLen_Instead) = 0 -done(r::Use_StepRangeLen_Instead, i::Int) = length(r) <= i -next(r::Use_StepRangeLen_Instead{T}, i::Int) where {T} = - (convert(T, (r.start + i*r.step)/r.divisor), i+1) - -function getindex(r::Use_StepRangeLen_Instead{T}, i::Integer) where T - @_inline_meta - @boundscheck checkbounds(r, i) - convert(T, (r.start + (i-1)*r.step)/r.divisor) -end - -function getindex(r::Use_StepRangeLen_Instead, s::OrdinalRange) - @_inline_meta - @boundscheck checkbounds(r, s) - Use_StepRangeLen_Instead(r.start + (first(s)-1)*r.step, step(s)*r.step, length(s), r.divisor) -end - --(r::Use_StepRangeLen_Instead) = Use_StepRangeLen_Instead(-r.start, -r.step, r.len, r.divisor) -+(x::Real, r::Use_StepRangeLen_Instead) = Use_StepRangeLen_Instead(r.divisor*x + r.start, r.step, r.len, r.divisor) --(x::Real, r::Use_StepRangeLen_Instead) = Use_StepRangeLen_Instead(r.divisor*x - r.start, -r.step, r.len, r.divisor) --(r::Use_StepRangeLen_Instead, x::Real) = Use_StepRangeLen_Instead(r.start - r.divisor*x, r.step, r.len, r.divisor) -*(x::Real, r::Use_StepRangeLen_Instead) = Use_StepRangeLen_Instead(x*r.start, x*r.step, r.len, r.divisor) -*(r::Use_StepRangeLen_Instead, x::Real) = x * r -/(r::Use_StepRangeLen_Instead, x::Real) = Use_StepRangeLen_Instead(r.start/x, r.step/x, r.len, r.divisor) -promote_rule(::Type{Use_StepRangeLen_Instead{T1}},::Type{Use_StepRangeLen_Instead{T2}}) where {T1,T2} = - Use_StepRangeLen_Instead{promote_type(T1,T2)} -convert(::Type{Use_StepRangeLen_Instead{T}}, r::Use_StepRangeLen_Instead{T}) where {T<:AbstractFloat} = r -convert(::Type{Use_StepRangeLen_Instead{T}}, r::Use_StepRangeLen_Instead) where {T<:AbstractFloat} = - Use_StepRangeLen_Instead{T}(r.start,r.step,r.len,r.divisor) - -promote_rule(::Type{Use_StepRangeLen_Instead{F}}, ::Type{OR}) where {F,OR<:OrdinalRange} = - Use_StepRangeLen_Instead{promote_type(F,eltype(OR))} -convert(::Type{Use_StepRangeLen_Instead{T}}, r::OrdinalRange) where {T<:AbstractFloat} = - Use_StepRangeLen_Instead{T}(first(r), step(r), length(r), one(T)) -convert(::Type{Use_StepRangeLen_Instead}, r::OrdinalRange{T}) where {T} = - Use_StepRangeLen_Instead{typeof(float(first(r)))}(first(r), step(r), length(r), one(T)) - -promote_rule(::Type{LinSpace{F}}, ::Type{OR}) where {F,OR<:Use_StepRangeLen_Instead} = - LinSpace{promote_type(F,eltype(OR))} -convert(::Type{LinSpace{T}}, r::Use_StepRangeLen_Instead) where {T<:AbstractFloat} = - linspace(convert(T, first(r)), convert(T, last(r)), convert(T, length(r))) -convert(::Type{LinSpace}, r::Use_StepRangeLen_Instead{T}) where {T<:AbstractFloat} = - convert(LinSpace{T}, r) - -reverse(r::Use_StepRangeLen_Instead) = Use_StepRangeLen_Instead(r.start + (r.len-1)*r.step, -r.step, r.len, r.divisor) - -function sum(r::Use_StepRangeLen_Instead) - l = length(r) - if iseven(l) - s = r.step * (l-1) * (l>>1) - else - s = (r.step * l) * ((l-1)>>1) - end - return (l * r.start + s)/r.divisor -end - -@deprecate_binding FloatRange Use_StepRangeLen_Instead - -## end of FloatRange - -@noinline zero_arg_matrix_constructor(prefix::String) = - depwarn("`$prefix()` is deprecated, use `$prefix(uninitialized, 0, 0)` instead.", :zero_arg_matrix_constructor) -function Matrix{T}() where T - zero_arg_matrix_constructor("Matrix{T}") - return Matrix{T}(uninitialized, 0, 0) -end -function Matrix() - zero_arg_matrix_constructor("Matrix") - return Matrix(uninitialized, 0, 0) -end - -# TODO: remove warning for using `_` in parse_input_line in base/client.jl - -# Special functions have been moved to a package -for f in (:airyai, :airyaiprime, :airybi, :airybiprime, :airyaix, :airyaiprimex, :airybix, :airybiprimex, - :besselh, :besselhx, :besseli, :besselix, :besselj, :besselj0, :besselj1, :besseljx, :besselk, - :besselkx, :bessely, :bessely0, :bessely1, :besselyx, - :dawson, :erf, :erfc, :erfcinv, :erfcx, :erfi, :erfinv, - :eta, :zeta, :digamma, :invdigamma, :polygamma, :trigamma, - :hankelh1, :hankelh1x, :hankelh2, :hankelh2x, - :airy, :airyx, :airyprime) - @eval @deprecate_moved $f "SpecialFunctions" -end - -@deprecate_binding LinearIndexing IndexStyle false -@deprecate_binding LinearFast IndexLinear false -@deprecate_binding LinearSlow IndexCartesian false -@deprecate_binding linearindexing IndexStyle false - -# #19635 -for fname in (:ones, :zeros) - @eval @deprecate ($fname)(T::Type, arr) ($fname)(T, size(arr)) - @eval ($fname)(::Type{T}, i::Integer) where {T} = ($fname)(T, (i,)) # provides disambiguation with method in Base - @eval function ($fname)(::Type{T}, arr::Array{T}) where T - msg = $("`$fname{T}(::Type{T}, arr::Array{T})` is deprecated, use `$fname(T, size(arr))` instead.") - error(msg) - end -end - # END 0.6 deprecations # BEGIN 0.7 deprecations +# TODO: remove warning for using `_` in parse_input_line in base/client.jl + @deprecate issubtype (<:) @deprecate union() Set() @@ -1132,12 +199,6 @@ end import .LinAlg: cond @deprecate cond(F::LinAlg.LU, p::Integer) cond(convert(AbstractArray, F), p) -# PR #21359 -import .Random: srand -@deprecate srand(r::MersenneTwister, filename::AbstractString, n::Integer=4) srand(r, read!(filename, Vector{UInt32}(uninitialized, Int(n)))) -@deprecate srand(filename::AbstractString, n::Integer=4) srand(read!(filename, Vector{UInt32}(uninitialized, Int(n)))) -@deprecate MersenneTwister(filename::AbstractString) srand(MersenneTwister(0), read!(filename, Vector{UInt32}(uninitialized, Int(4)))) - # PR #21974 @deprecate versioninfo(verbose::Bool) versioninfo(verbose=verbose) @deprecate versioninfo(io::IO, verbose::Bool) versioninfo(io, verbose=verbose) @@ -1389,8 +450,6 @@ import .LinAlg: lufact, lufact!, qrfact, qrfact!, cholfact, cholfact! @deprecate cholfact!(A::AbstractMatrix, ::Type{Val{false}}) cholfact!(A, Val(false)) @deprecate cholfact!(A::AbstractMatrix, ::Type{Val{true}}; tol = 0.0) cholfact!(A, Val(true); tol = tol) @deprecate cat(::Type{Val{N}}, A::AbstractArray...) where {N} cat(Val(N), A...) -@deprecate cat(::Type{Val{N}}, A::SparseArrays._SparseConcatGroup...) where {N} cat(Val(N), A...) -@deprecate cat(::Type{Val{N}}, A::SparseArrays._DenseConcatGroup...) where {N} cat(Val(N), A...) @deprecate cat_t(::Type{Val{N}}, ::Type{T}, A, B) where {N,T} cat_t(Val(N), T, A, B) false @deprecate reshape(A::AbstractArray, ::Type{Val{N}}) where {N} reshape(A, Val(N)) @@ -1425,6 +484,7 @@ function OverflowError() end # PR #22703 +import .LinAlg: Bidiagonal @deprecate Bidiagonal(dv::AbstractVector, ev::AbstractVector, isupper::Bool) Bidiagonal(dv, ev, ifelse(isupper, :U, :L)) @deprecate Bidiagonal(dv::AbstractVector, ev::AbstractVector, uplo::Char) Bidiagonal(dv, ev, ifelse(uplo == 'U', :U, :L)) @deprecate Bidiagonal(A::AbstractMatrix, isupper::Bool) Bidiagonal(A, ifelse(isupper, :U, :L)) @@ -1442,24 +502,6 @@ end # remove parse-with-chains-warn and bitshift-warn # update precedence table in doc/src/manual/mathematical-operations.md -# deprecate remaining vectorized methods over SparseVectors (zero-preserving) -for op in (:floor, :ceil, :trunc, :round, - :log1p, :expm1, :sinpi, - :sin, :tan, :sind, :tand, - :asin, :atan, :asind, :atand, - :sinh, :tanh, :asinh, :atanh) - @eval @deprecate ($op)(x::AbstractSparseVector{<:Number,<:Integer}) ($op).(x) -end -# deprecate remaining vectorized methods over SparseVectors (not-zero-preserving) -for op in (:exp, :exp2, :exp10, :log, :log2, :log10, - :cos, :cosd, :acos, :cosh, :cospi, - :csc, :cscd, :acot, :csch, :acsch, - :cot, :cotd, :acosd, :coth, - :sec, :secd, :acotd, :sech, :asech) - @eval import .Math: $op - @eval @deprecate ($op)(x::AbstractSparseVector{<:Number,<:Integer}) ($op).(x) -end - # PR #22182 @deprecate is_apple Sys.isapple @deprecate is_bsd Sys.isbsd @@ -1492,6 +534,7 @@ end # PR #22925 # also uncomment constructor tests in test/linalg/bidiag.jl +import .LinAlg: Bidiagonal function Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) where {T,S} depwarn(string("`Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) where {T, S}`", " is deprecated, manually convert both vectors to the same type instead."), :Bidiagonal) @@ -1501,6 +544,7 @@ end # PR #23035 # also uncomment constructor tests in test/linalg/tridiag.jl +import .LinAlg: SymTridiagonal function SymTridiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}) where {T,S} depwarn(string("`SymTridiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}) ", "where {T, S}` is deprecated, convert both vectors to the same type instead."), :SymTridiagonal) @@ -1510,6 +554,7 @@ end # PR #23154 # also uncomment constructor tests in test/linalg/tridiag.jl +import .LinAlg: Tridiagonal function Tridiagonal(dl::AbstractVector{Tl}, d::AbstractVector{Td}, du::AbstractVector{Tu}) where {Tl,Td,Tu} depwarn(string("`Tridiagonal(dl::AbstractVector{Tl}, d::AbstractVector{Td}, du::AbstractVector{Tu}) ", "where {Tl, Td, Tu}` is deprecated, convert all vectors to the same type instead."), :Tridiagonal) @@ -1582,8 +627,6 @@ end @deprecate convert(::Type{S}, g::Unicode.GraphemeIterator) where {S<:AbstractString} convert(S, g.s) @deprecate convert(::Type{String}, v::AbstractVector{Char}) String(v) -@deprecate convert(::Type{UInt128}, u::Random.UUID) UInt128(u) -@deprecate convert(::Type{Random.UUID}, s::AbstractString) Random.UUID(s) @deprecate convert(::Type{Libc.FILE}, s::IO) Libc.FILE(s) @deprecate convert(::Type{VersionNumber}, v::Integer) VersionNumber(v) @deprecate convert(::Type{VersionNumber}, v::Tuple) VersionNumber(v) @@ -1629,11 +672,8 @@ end # PR #23066 @deprecate cfunction(f, r, a::Tuple) cfunction(f, r, Tuple{a...}) -# PR 23341 -import .LinAlg: diagm -@deprecate diagm(A::SparseMatrixCSC) sparse(Diagonal(sparsevec(A))) - # PR #23373 +import .LinAlg: diagm @deprecate diagm(A::BitMatrix) BitMatrix(Diagonal(vec(A))) # PR 23341 @@ -1747,33 +787,6 @@ end @deprecate contains(eq::Function, itr, x) any(y->eq(y,x), itr) -# PR #23757 -import .SparseArrays.spdiagm -@deprecate spdiagm(x::AbstractVector) sparse(Diagonal(x)) -function spdiagm(x::AbstractVector, d::Number) - depwarn(string("`spdiagm(x::AbstractVector, d::Number)` is deprecated, use ", - "`spdiagm(d => x)` instead, which now returns a square matrix. To preserve the old ", - "behaviour, use `sparse(SparseArrays.spdiagm_internal(d => x)...)`"), :spdiagm) - I, J, V = SparseArrays.spdiagm_internal(d => x) - return sparse(I, J, V) -end -function spdiagm(x, d) - depwarn(string("`spdiagm((x1, x2, ...), (d1, d2, ...))` is deprecated, use ", - "`spdiagm(d1 => x1, d2 => x2, ...)` instead, which now returns a square matrix. ", - "To preserve the old behaviour, use ", - "`sparse(SparseArrays.spdiagm_internal(d1 => x1, d2 => x2, ...)...)`"), :spdiagm) - I, J, V = SparseArrays.spdiagm_internal((d[i] => x[i] for i in 1:length(x))...) - return sparse(I, J, V) -end -function spdiagm(x, d, m::Integer, n::Integer) - depwarn(string("`spdiagm((x1, x2, ...), (d1, d2, ...), m, n)` is deprecated, use ", - "`spdiagm(d1 => x1, d2 => x2, ...)` instead, which now returns a square matrix. ", - "To specify a non-square matrix and preserve the old behaviour, use ", - "`I, J, V = SparseArrays.spdiagm_internal(d1 => x1, d2 => x2, ...); sparse(I, J, V, m, n)`"), :spdiagm) - I, J, V = SparseArrays.spdiagm_internal((d[i] => x[i] for i in 1:length(x))...) - return sparse(I, J, V, m, n) -end - # deprecate zeros(D::Diagonal[, opts...]) function zeros(D::Diagonal) depwarn(string("`zeros(D::Diagonal)` is deprecated, use ", @@ -1906,7 +919,6 @@ function eye(::Type{Diagonal{T}}, n::Int) where T return Diagonal{T}(I, n) end @eval Base.LinAlg import Base.eye -# @eval Base.SparseArrays import Base.eye # SparseArrays has an eye for things cholmod export tic, toq, toc @@ -1940,8 +952,6 @@ function toc() return t end -@eval Base.SparseArrays @deprecate sparse(s::UniformScaling, m::Integer) sparse(s, m, m) - # A[I...] .= with scalar indices should modify the element at A[I...] function Broadcast.dotview(A::AbstractArray, args::Number...) depwarn("the behavior of `A[I...] .= X` with scalar indices will change in the future. Use `A[I...] = X` instead.", :broadcast!) @@ -2019,12 +1029,6 @@ end # PR #25030 @eval LinAlg @deprecate fillslots! fillstored! false -# PR #25037 -@eval SparseArrays @deprecate spones(A::SparseMatrixCSC) LinAlg.fillstored!(copy(A), 1) -@eval SparseArrays @deprecate spones(A::SparseVector) LinAlg.fillstored!(copy(A), 1) -using .SparseArrays.spones -export spones - function diagm(v::BitVector) depwarn(string("`diagm(v::BitVector)` is deprecated, use `diagm(0 => v)` or ", "`BitMatrix(Diagonal(v))` instead."), :diagm) @@ -2073,19 +1077,6 @@ function full(A::Union{Diagonal,Bidiagonal,Tridiagonal,SymTridiagonal}) return Matrix(A) end -# full for sparse arrays -function full(S::Union{SparseVector,SparseMatrixCSC}) - (arrtypestr, desttypestr) = - isa(S, SparseVector) ? ("SparseVector", "Vector") : - isa(S, SparseMatrixCSC) ? ("SparseMatrixCSC", "Matrix") : - error("should not be reachable!") - depwarn(string( - "`full(S::$(arrtypestr))` (and `full` in general) has been deprecated. ", - "To replace `full(S::$(arrtypestr))`, consider `$(desttypestr)(S)` or, ", - "if that option is too narrow, `Array(S)`."), :full) - return Array(S) -end - # full for factorizations function full(F::Union{LinAlg.LU,LinAlg.LQ,LinAlg.QR,LinAlg.QRPivoted,LinAlg.QRCompactWY, LinAlg.SVD,LinAlg.LDLt,LinAlg.Schur,LinAlg.Eigen,LinAlg.Hessenberg, @@ -2198,7 +1189,6 @@ end # issue #22849 @deprecate reinterpret(::Type{T}, a::Array{S}, dims::NTuple{N,Int}) where {T, S, N} reshape(reinterpret(T, vec(a)), dims) -@deprecate reinterpret(::Type{T}, a::SparseMatrixCSC{S}, dims::NTuple{N,Int}) where {T, S, N} reinterpret(T, reshape(a, dims)) @deprecate reinterpret(::Type{T}, a::ReinterpretArray{S}, dims::NTuple{N,Int}) where {T, S, N} reshape(reinterpret(T, vec(a)), dims) # issue #24006 @@ -2235,55 +1225,6 @@ end # deprecate bits to bitstring (#24263, #24281) @deprecate bits bitstring -# deprecate speye -export speye -function speye(n::Integer) - depwarn(string("`speye(n::Integer)` has been deprecated in favor of `I`, `sparse`, and ", - "`SparseMatrixCSC` constructor methods. For a direct replacement, consider ", - "`sparse(1.0I, n, n)`, `SparseMatrixCSC(1.0I, n, n)`, or `SparseMatrixCSC{Float64}(I, n, n)`. ", - "If `Float64` element type is not necessary, consider the shorter `sparse(I, n, n)` ", - "or `SparseMatrixCSC(I, n, n)` (with default `eltype(I)` of `Bool`)."), :speye) - return sparse(1.0I, n, n) -end -function speye(m::Integer, n::Integer) - depwarn(string("`speye(m::Integer, n::Integer)` has been deprecated in favor of `I`, ", - "`sparse`, and `SparseMatrixCSC` constructor methods. For a direct ", - "replacement, consider `sparse(1.0I, m, n)`, `SparseMatrixCSC(1.0I, m, n)`, ", - "or `SparseMatrixCSC{Float64}(I, m, n)`. If `Float64` element type is not ", - " necessary, consider the shorter `sparse(I, m, n)` or `SparseMatrixCSC(I, m, n)` ", - "(with default `eltype(I)` of `Bool`)."), :speye) - return sparse(1.0I, m, n) -end -function speye(::Type{T}, n::Integer) where T - depwarn(string("`speye(T, n::Integer)` has been deprecated in favor of `I`, `sparse`, and ", - "`SparseMatrixCSC` constructor methods. For a direct replacement, consider ", - "`sparse(T(1)I, n, n)` if `T` is concrete or `SparseMatrixCSC{T}(I, n, n)` ", - "if `T` is either concrete or abstract. If element type `T` is not necessary, ", - "consider the shorter `sparse(I, n, n)` or `SparseMatrixCSC(I, n, n)` ", - "(with default `eltype(I)` of `Bool`)."), :speye) - return SparseMatrixCSC{T}(I, n, n) -end -function speye(::Type{T}, m::Integer, n::Integer) where T - depwarn(string("`speye(T, m::Integer, n::Integer)` has been deprecated in favor of `I`, ", - "`sparse`, and `SparseMatrixCSC` constructor methods. For a direct ", - "replacement, consider `sparse(T(1)I, m, n)` if `T` is concrete or ", - "`SparseMatrixCSC{T}(I, m, n)` if `T` is either concrete or abstract. ", - "If element type `T` is not necessary, consider the shorter ", - "`sparse(I, m, n)` or `SparseMatrixCSC(I, m, n)` (with default `eltype(I)` ", - "of `Bool`)."), :speye) - return SparseMatrixCSC{T}(I, m, n) -end -function speye(S::SparseMatrixCSC{T}) where T - depwarn(string("`speye(S::SparseMatrixCSC{T})` has been deprecated in favor of `I`, ", - "`sparse`, and `SparseMatrixCSC` constructor methods. For a direct ", - "replacement, consider `sparse(T(1)I, size(S)...)` if `T` is concrete or ", - "`SparseMatrixCSC{eltype(S)}(I, size(S))` if `T` is either concrete or abstract. ", - "If preserving element type `T` is not necessary, consider the shorter ", - "`sparse(I, size(S)...)` or `SparseMatrixCSC(I, size(S))` (with default ", - "`eltype(I)` of `Bool`)."), :speye) - return SparseMatrixCSC{T}(I, m, n) -end - # issue #24167 @deprecate EnvHash EnvDict @@ -2301,6 +1242,8 @@ end @deprecate cumsum(A::AbstractArray) cumsum(A, 1) @deprecate cumprod(A::AbstractArray) cumprod(A, 1) +import .LinAlg: diff +@deprecate diff(A::AbstractMatrix) diff(A, 1) # issue #16307 @deprecate finalizer(o, f::Function) finalizer(f, o) @@ -2312,6 +1255,7 @@ end finalizer(f::Ptr{Cvoid}, o::Ptr{Cvoid}) = invoke(finalizer, Tuple{Ptr{Cvoid}, Any}, f, o) finalizer(f::Ptr{Cvoid}, o::Function) = invoke(finalizer, Tuple{Ptr{Cvoid}, Any}, f, o) + # Broadcast extension API (#23939) @eval Broadcast begin Base.@deprecate_binding containertype combine_styles false @@ -2559,7 +1503,7 @@ end end sum(@inbounds(return rowvec[i]*vec[i]) for i = 1:length(vec)) end - @inline *(rowvec::RowVector, mat::AbstractMatrix) = rvtranspose(Transpose(mat) * rvtranspose(rowvec)) + @inline *(rowvec::RowVector, mat::AbstractMatrix) = rvtranspose(transpose(mat) * rvtranspose(rowvec)) *(::RowVector, ::RowVector) = throw(DimensionMismatch("Cannot multiply two transposed vectors")) @inline *(vec::AbstractVector, rowvec::RowVector) = vec .* rowvec *(vec::AbstractVector, rowvec::AbstractVector) = throw(DimensionMismatch("Cannot multiply two vectors")) @@ -2659,26 +1603,33 @@ end @deprecate RowVector{T}(n::Tuple{Int,Int}) where {T} RowVector{T}(uninitialized, n) end +# TODOs re. .' deprecation +# (1) remove .' deprecation from src/julia-syntax.scm around line 2346 +# (2) remove .' documentation from base/docs/basedocs.jl around line 255 +# (3) remove .'-involving code from base/show.jl around line 1277 +# (4) remove .'-involving test from test/deprecation_exec.jl around line 178 +# (5) remove .'-related code from src/ast.scm and src/julia-parser.scm + # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/operators.jl, to deprecate -@deprecate Ac_ldiv_Bt(a,b) (\)(Adjoint(a), Transpose(b)) -@deprecate At_ldiv_Bt(a,b) (\)(Transpose(a), Transpose(b)) -@deprecate A_ldiv_Bt(a,b) (\)(a, Transpose(b)) -@deprecate At_ldiv_B(a,b) (\)(Transpose(a), b) -@deprecate Ac_ldiv_Bc(a,b) (\)(Adjoint(a), Adjoint(b)) -@deprecate A_ldiv_Bc(a,b) (\)(a, Adjoint(b)) -@deprecate Ac_ldiv_B(a,b) (\)(Adjoint(a), b) -@deprecate At_rdiv_Bt(a,b) (/)(Transpose(a), Transpose(b)) -@deprecate A_rdiv_Bt(a,b) (/)(a, Transpose(b)) -@deprecate At_rdiv_B(a,b) (/)(Transpose(a), b) -@deprecate Ac_rdiv_Bc(a,b) (/)(Adjoint(a), Adjoint(b)) -@deprecate A_rdiv_Bc(a,b) (/)(a, Adjoint(b)) -@deprecate Ac_rdiv_B(a,b) (/)(Adjoint(a), b) -@deprecate At_mul_Bt(a,b) (*)(Transpose(a), Transpose(b)) -@deprecate A_mul_Bt(a,b) (*)(a, Transpose(b)) -@deprecate At_mul_B(a,b) (*)(Transpose(a), b) -@deprecate Ac_mul_Bc(a,b) (*)(Adjoint(a), Adjoint(b)) -@deprecate A_mul_Bc(a,b) (*)(a, Adjoint(b)) -@deprecate Ac_mul_B(a,b) (*)(Adjoint(a), b) +@deprecate Ac_ldiv_Bt(a,b) (\)(adjoint(a), transpose(b)) +@deprecate At_ldiv_Bt(a,b) (\)(transpose(a), transpose(b)) +@deprecate A_ldiv_Bt(a,b) (\)(a, transpose(b)) +@deprecate At_ldiv_B(a,b) (\)(transpose(a), b) +@deprecate Ac_ldiv_Bc(a,b) (\)(adjoint(a), adjoint(b)) +@deprecate A_ldiv_Bc(a,b) (\)(a, adjoint(b)) +@deprecate Ac_ldiv_B(a,b) (\)(adjoint(a), b) +@deprecate At_rdiv_Bt(a,b) (/)(transpose(a), transpose(b)) +@deprecate A_rdiv_Bt(a,b) (/)(a, transpose(b)) +@deprecate At_rdiv_B(a,b) (/)(transpose(a), b) +@deprecate Ac_rdiv_Bc(a,b) (/)(adjoint(a), adjoint(b)) +@deprecate A_rdiv_Bc(a,b) (/)(a, adjoint(b)) +@deprecate Ac_rdiv_B(a,b) (/)(adjoint(a), b) +@deprecate At_mul_Bt(a,b) (*)(transpose(a), transpose(b)) +@deprecate A_mul_Bt(a,b) (*)(a, transpose(b)) +@deprecate At_mul_B(a,b) (*)(transpose(a), b) +@deprecate Ac_mul_Bc(a,b) (*)(adjoint(a), adjoint(b)) +@deprecate A_mul_Bc(a,b) (*)(a, adjoint(b)) +@deprecate Ac_mul_B(a,b) (*)(adjoint(a), b) # additionally, the following in-place ops were exported from Base export A_mul_B!, A_mul_Bt!, At_mul_B!, At_mul_Bt!, @@ -2732,23 +1683,23 @@ end @deprecate A_mul_B!(C::AbstractVector, A::BiTri, B::AbstractVector) mul!(C, A, B) @deprecate A_mul_B!(C::AbstractMatrix, A::BiTri, B::AbstractVecOrMat) mul!(C, A, B) @deprecate A_mul_B!(C::AbstractVecOrMat, A::BiTri, B::AbstractVecOrMat) mul!(C, A, B) - @deprecate Ac_ldiv_B(A::Bidiagonal, v::RowVector) (\)(Adjoint(A), v) - @deprecate At_ldiv_B(A::Bidiagonal, v::RowVector) (\)(Transpose(A), v) - @deprecate Ac_ldiv_B(A::Bidiagonal{<:Number}, v::RowVector{<:Number}) (\)(Adjoint(A), v) - @deprecate At_ldiv_B(A::Bidiagonal{<:Number}, v::RowVector{<:Number}) (\)(Transpose(A), v) - @deprecate Ac_mul_B(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} (*)(Adjoint(A), B) - @deprecate A_mul_Bc(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} (*)(A, Adjoint(B)) - @deprecate A_rdiv_Bc(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} (/)(A, Adjoint(B)) + @deprecate Ac_ldiv_B(A::Bidiagonal, v::RowVector) (\)(adjoint(A), v) + @deprecate At_ldiv_B(A::Bidiagonal, v::RowVector) (\)(transpose(A), v) + @deprecate Ac_ldiv_B(A::Bidiagonal{<:Number}, v::RowVector{<:Number}) (\)(adjoint(A), v) + @deprecate At_ldiv_B(A::Bidiagonal{<:Number}, v::RowVector{<:Number}) (\)(transpose(A), v) + @deprecate Ac_mul_B(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} (*)(adjoint(A), B) + @deprecate A_mul_Bc(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} (*)(A, adjoint(B)) + @deprecate A_rdiv_Bc(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} (/)(A, adjoint(B)) @deprecate A_ldiv_B!(A::Union{Bidiagonal, AbstractTriangular}, b::AbstractVector) ldiv!(A, b) - @deprecate At_ldiv_B!(A::Bidiagonal, b::AbstractVector) ldiv!(Transpose(A), b) - @deprecate Ac_ldiv_B!(A::Bidiagonal, b::AbstractVector) ldiv!(Adjoint(A), b) + @deprecate At_ldiv_B!(A::Bidiagonal, b::AbstractVector) ldiv!(transpose(A), b) + @deprecate Ac_ldiv_B!(A::Bidiagonal, b::AbstractVector) ldiv!(adjoint(A), b) @deprecate A_ldiv_B!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix) ldiv!(A, B) - @deprecate Ac_ldiv_B!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix) ldiv!(Adjoint(A), B) - @deprecate At_ldiv_B!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix) ldiv!(Transpose(A), B) - @deprecate At_ldiv_B(A::Bidiagonal, B::AbstractVecOrMat) (\)(Transpose(A), B) - @deprecate Ac_ldiv_B(A::Bidiagonal, B::AbstractVecOrMat) ldiv!(Adjoint(A), B) - @deprecate Ac_ldiv_B(A::Bidiagonal{TA}, B::AbstractVecOrMat{TB}) where {TA<:Number,TB<:Number} (\)(Adjoint(A), B) - @deprecate At_ldiv_B(A::Bidiagonal{TA}, B::AbstractVecOrMat{TB}) where {TA<:Number,TB<:Number} (\)(Transpose(A), B) + @deprecate Ac_ldiv_B!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix) ldiv!(adjoint(A), B) + @deprecate At_ldiv_B!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix) ldiv!(transpose(A), B) + @deprecate At_ldiv_B(A::Bidiagonal, B::AbstractVecOrMat) (\)(transpose(A), B) + @deprecate Ac_ldiv_B(A::Bidiagonal, B::AbstractVecOrMat) ldiv!(adjoint(A), B) + @deprecate Ac_ldiv_B(A::Bidiagonal{TA}, B::AbstractVecOrMat{TB}) where {TA<:Number,TB<:Number} (\)(adjoint(A), B) + @deprecate At_ldiv_B(A::Bidiagonal{TA}, B::AbstractVecOrMat{TB}) where {TA<:Number,TB<:Number} (\)(transpose(A), B) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/tridiag.jl, to deprecate @@ -2758,63 +1709,66 @@ end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/diagonal.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_mul_B!(A::Union{LowerTriangular,UpperTriangular}, D::Diagonal) mul!(A, D) - @deprecate A_mul_B!(A::UnitLowerTriangular, D::Diagonal) mul!(A, D) - @deprecate A_mul_B!(A::UnitUpperTriangular, D::Diagonal) mul!(A, D) - @deprecate A_mul_B!(D::Diagonal, B::UnitLowerTriangular) mul!(D, B) - @deprecate A_mul_B!(D::Diagonal, B::UnitUpperTriangular) mul!(D, B) - @deprecate Ac_mul_B(D::Diagonal, B::Diagonal) (*)(Adjoint(D), B) - @deprecate Ac_mul_B(A::AbstractTriangular, D::Diagonal) (*)(Adjoint(A), D) - @deprecate Ac_mul_B(A::AbstractMatrix, D::Diagonal) (*)(Adjoint(A), D) - @deprecate At_mul_B(D::Diagonal, B::Diagonal) (*)(Transpose(D), B) - @deprecate At_mul_B(A::AbstractTriangular, D::Diagonal) (*)(Transpose(A), D) - @deprecate At_mul_B(A::AbstractMatrix, D::Diagonal) (*)(Transpose(A), D) - @deprecate A_mul_Bc(D::Diagonal, B::Diagonal) (*)(D, Adjoint(B)) - @deprecate A_mul_Bc(D::Diagonal, B::AbstractTriangular) (*)(D, Adjoint(B)) - @deprecate A_mul_Bc(D::Diagonal, Q::Union{QRCompactWYQ,QRPackedQ}) (*)(D, Adjoint(Q)) - @deprecate A_mul_Bc(D::Diagonal, A::AbstractMatrix) (*)(D, Adjoint(A)) - @deprecate A_mul_Bt(D::Diagonal, B::Diagonal) (*)(D, Transpose(B)) - @deprecate A_mul_Bt(D::Diagonal, B::AbstractTriangular) (*)(D, Transpose(B)) - @deprecate A_mul_Bt(D::Diagonal, A::AbstractMatrix) (*)(D, Transpose(A)) - @deprecate Ac_mul_Bc(D::Diagonal, B::Diagonal) (*)(Adjoint(D), Adjoint(B)) - @deprecate At_mul_Bt(D::Diagonal, B::Diagonal) (*)(Transpose(D), Transpose(B)) - @deprecate A_mul_B!(A::Diagonal,B::Diagonal) mul!(A, B) - @deprecate At_mul_B!(A::Diagonal,B::Diagonal) mul!(Transpose(A), B) - @deprecate Ac_mul_B!(A::Diagonal,B::Diagonal) mul!(Adjoint(A), B) - @deprecate A_mul_B!(A::QRPackedQ, D::Diagonal) mul!(A, D) - @deprecate A_mul_B!(A::Diagonal,B::AbstractMatrix) mul!(A, B) - @deprecate At_mul_B!(A::Diagonal,B::AbstractMatrix) mul!(Transpose(A), B) - @deprecate Ac_mul_B!(A::Diagonal,B::AbstractMatrix) mul!(Adjoint(A), B) - @deprecate A_mul_B!(A::AbstractMatrix,B::Diagonal) mul!(A, B) - @deprecate A_mul_Bt!(A::AbstractMatrix,B::Diagonal) mul!(A, Transpose(B)) - @deprecate A_mul_Bc!(A::AbstractMatrix,B::Diagonal) mul!(A, Adjoint(B)) + @deprecate A_mul_B!(A::Union{LowerTriangular,UpperTriangular}, D::Diagonal) mul1!(A, D) + @deprecate A_mul_B!(A::UnitLowerTriangular, D::Diagonal) mul1!(A, D) + @deprecate A_mul_B!(A::UnitUpperTriangular, D::Diagonal) mul1!(A, D) + @deprecate A_mul_B!(D::Diagonal, B::UnitLowerTriangular) mul2!(D, B) + @deprecate A_mul_B!(D::Diagonal, B::UnitUpperTriangular) mul2!(D, B) + @deprecate Ac_mul_B(D::Diagonal, B::Diagonal) (*)(adjoint(D), B) + @deprecate Ac_mul_B(A::AbstractTriangular, D::Diagonal) (*)(adjoint(A), D) + @deprecate Ac_mul_B(A::AbstractMatrix, D::Diagonal) (*)(adjoint(A), D) + @deprecate At_mul_B(D::Diagonal, B::Diagonal) (*)(transpose(D), B) + @deprecate At_mul_B(A::AbstractTriangular, D::Diagonal) (*)(transpose(A), D) + @deprecate At_mul_B(A::AbstractMatrix, D::Diagonal) (*)(transpose(A), D) + @deprecate A_mul_Bc(D::Diagonal, B::Diagonal) (*)(D, adjoint(B)) + @deprecate A_mul_Bc(D::Diagonal, B::AbstractTriangular) (*)(D, adjoint(B)) + @deprecate A_mul_Bc(D::Diagonal, Q::Union{QRCompactWYQ,QRPackedQ}) (*)(D, adjoint(Q)) + @deprecate A_mul_Bc(D::Diagonal, A::AbstractMatrix) (*)(D, adjoint(A)) + @deprecate A_mul_Bt(D::Diagonal, B::Diagonal) (*)(D, transpose(B)) + @deprecate A_mul_Bt(D::Diagonal, B::AbstractTriangular) (*)(D, transpose(B)) + @deprecate A_mul_Bt(D::Diagonal, A::AbstractMatrix) (*)(D, transpose(A)) + @deprecate Ac_mul_Bc(D::Diagonal, B::Diagonal) (*)(adjoint(D), adjoint(B)) + @deprecate At_mul_Bt(D::Diagonal, B::Diagonal) (*)(transpose(D), transpose(B)) + function A_mul_B!(A::Diagonal,B::Diagonal) + depwarn("`A_mul_B!(A::Diagonal,B::Diagonal)` should be replaced with `mul1!(A, B)` or `mul2!(A, B)`.", :A_mul_B!) + throw(MethodError(A_mul_B!, (A, B))) + end + @deprecate At_mul_B!(A::Diagonal,B::Diagonal) mul2!(transpose(A), B) + @deprecate Ac_mul_B!(A::Diagonal,B::Diagonal) mul2!(adjoint(A), B) + @deprecate A_mul_B!(A::QRPackedQ, D::Diagonal) mul1!(A, D) + @deprecate A_mul_B!(A::Diagonal,B::AbstractMatrix) mul2!(A, B) + @deprecate At_mul_B!(A::Diagonal,B::AbstractMatrix) mul2!(transpose(A), B) + @deprecate Ac_mul_B!(A::Diagonal,B::AbstractMatrix) mul2!(adjoint(A), B) + @deprecate A_mul_B!(A::AbstractMatrix,B::Diagonal) mul1!(A, B) + @deprecate A_mul_Bt!(A::AbstractMatrix,B::Diagonal) mul1!(A, transpose(B)) + @deprecate A_mul_Bc!(A::AbstractMatrix,B::Diagonal) mul1!(A, adjoint(B)) @deprecate A_mul_B!(out::AbstractVector, A::Diagonal, in::AbstractVector) mul!(out, A, in) - @deprecate Ac_mul_B!(out::AbstractVector, A::Diagonal, in::AbstractVector) mul!(out, Adjoint(A), in) - @deprecate At_mul_B!(out::AbstractVector, A::Diagonal, in::AbstractVector) mul!(out, Transpose(A), in) + @deprecate Ac_mul_B!(out::AbstractVector, A::Diagonal, in::AbstractVector) mul!(out, adjoint(A), in) + @deprecate At_mul_B!(out::AbstractVector, A::Diagonal, in::AbstractVector) mul!(out, transpose(A), in) @deprecate A_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) mul!(out, A, in) - @deprecate Ac_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) mul!(out, Adjoint(A), in) - @deprecate At_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) mul!(out, Transpose(A), in) - @deprecate A_mul_Bt(A::Diagonal, B::RealHermSymComplexSym) (*)(A, Transpose(B)) - @deprecate At_mul_B(A::RealHermSymComplexSym, B::Diagonal) (*)(Transpose(A), B) - @deprecate A_mul_Bc(A::Diagonal, B::RealHermSymComplexHerm) (*)(A, Adjoint(B)) - @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::Diagonal) (*)(Adjoint(A), B) + @deprecate Ac_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) mul!(out, adjoint(A), in) + @deprecate At_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) mul!(out, transpose(A), in) + @deprecate A_mul_Bt(A::Diagonal, B::RealHermSymComplexSym) (*)(A, transpose(B)) + @deprecate At_mul_B(A::RealHermSymComplexSym, B::Diagonal) (*)(transpose(A), B) + @deprecate A_mul_Bc(A::Diagonal, B::RealHermSymComplexHerm) (*)(A, adjoint(B)) + @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::Diagonal) (*)(adjoint(A), B) @deprecate A_ldiv_B!(D::Diagonal{T}, v::AbstractVector{T}) where {T} ldiv!(D, v) @deprecate A_ldiv_B!(D::Diagonal{T}, V::AbstractMatrix{T}) where {T} ldiv!(D, V) - @deprecate Ac_ldiv_B!(D::Diagonal{T}, B::AbstractVecOrMat{T}) where {T} ldiv!(Adjoint(D), B) - @deprecate At_ldiv_B!(D::Diagonal{T}, B::AbstractVecOrMat{T}) where {T} ldiv!(Transpose(D), B) + @deprecate Ac_ldiv_B!(D::Diagonal{T}, B::AbstractVecOrMat{T}) where {T} ldiv!(adjoint(D), B) + @deprecate At_ldiv_B!(D::Diagonal{T}, B::AbstractVecOrMat{T}) where {T} ldiv!(transpose(D), B) @deprecate A_rdiv_B!(A::AbstractMatrix{T}, D::Diagonal{T}) where {T} rdiv!(A, D) - @deprecate A_rdiv_Bc!(A::AbstractMatrix{T}, D::Diagonal{T}) where {T} rdiv!(A, Adjoint(D)) - @deprecate A_rdiv_Bt!(A::AbstractMatrix{T}, D::Diagonal{T}) where {T} rdiv!(A, Transpose(D)) - @deprecate Ac_ldiv_B(F::Factorization, D::Diagonal) (\)(Adjoint(F), D) - @deprecate A_mul_Bt(D::Diagonal, rowvec::RowVector) (*)(D, Transpose(rowvec)) - @deprecate A_mul_Bc(D::Diagonal, rowvec::RowVector) (*)(D, Adjoint(rowvec)) + @deprecate A_rdiv_Bc!(A::AbstractMatrix{T}, D::Diagonal{T}) where {T} rdiv!(A, adjoint(D)) + @deprecate A_rdiv_Bt!(A::AbstractMatrix{T}, D::Diagonal{T}) where {T} rdiv!(A, transpose(D)) + @deprecate Ac_ldiv_B(F::Factorization, D::Diagonal) (\)(adjoint(F), D) + @deprecate A_mul_Bt(D::Diagonal, rowvec::RowVector) (*)(D, transpose(rowvec)) + @deprecate A_mul_Bc(D::Diagonal, rowvec::RowVector) (*)(D, adjoint(rowvec)) @deprecate A_ldiv_B!(D::Diagonal, B::StridedVecOrMat) ldiv!(D, B) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/special.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_mul_Bc!(A::AbstractTriangular, B::Union{QRCompactWYQ,QRPackedQ}) mul!(A, Adjoint(B)) - @deprecate A_mul_Bc(A::AbstractTriangular, B::Union{QRCompactWYQ,QRPackedQ}) (*)(A, Adjoint(B)) + @deprecate A_mul_Bc!(A::AbstractTriangular, B::Union{QRCompactWYQ,QRPackedQ}) mul1!(A, adjoint(B)) + @deprecate A_mul_Bc(A::AbstractTriangular, B::Union{QRCompactWYQ,QRPackedQ}) (*)(A, adjoint(B)) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/bunchkaufman.jl, to deprecate @@ -2836,22 +1790,22 @@ end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/factorization.jl, to deprecate @eval Base.LinAlg begin - @deprecate Ac_ldiv_B(F::Factorization, B::AbstractVecOrMat) (\)(Adjoint(F), B) + @deprecate Ac_ldiv_B(F::Factorization, B::AbstractVecOrMat) (\)(adjoint(F), B) @deprecate A_ldiv_B!(Y::AbstractVecOrMat, A::Factorization, B::AbstractVecOrMat) ldiv!(Y, A, B) - @deprecate Ac_ldiv_B!(Y::AbstractVecOrMat, A::Factorization, B::AbstractVecOrMat) ldiv!(Y, Adjoint(A), B) - @deprecate At_ldiv_B!(Y::AbstractVecOrMat, A::Factorization, B::AbstractVecOrMat) ldiv!(Y, Transpose(A), B) - @deprecate At_ldiv_B(F::Factorization{<:Real}, B::AbstractVecOrMat) (\)(Transpose(F), B) - @deprecate At_ldiv_B(F::Factorization, B) (\)(Transpose(F), B) + @deprecate Ac_ldiv_B!(Y::AbstractVecOrMat, A::Factorization, B::AbstractVecOrMat) ldiv!(Y, adjoint(A), B) + @deprecate At_ldiv_B!(Y::AbstractVecOrMat, A::Factorization, B::AbstractVecOrMat) ldiv!(Y, transpose(A), B) + @deprecate At_ldiv_B(F::Factorization{<:Real}, B::AbstractVecOrMat) (\)(transpose(F), B) + @deprecate At_ldiv_B(F::Factorization, B) (\)(transpose(F), B) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/hessenberg.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_mul_B!(Q::HessenbergQ{T}, X::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(Q, X) - @deprecate A_mul_B!(X::StridedMatrix{T}, Q::HessenbergQ{T}) where {T<:BlasFloat} mul!(X, Q) - @deprecate Ac_mul_B!(Q::HessenbergQ{T}, X::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(Adjoint(Q), X) - @deprecate A_mul_Bc!(X::StridedMatrix{T}, Q::HessenbergQ{T}) where {T<:BlasFloat} mul!(X, Adjoint(Q)) - @deprecate Ac_mul_B(Q::HessenbergQ{T}, X::StridedVecOrMat{S}) where {T,S} (*)(Adjoint(Q), X) - @deprecate A_mul_Bc(X::StridedVecOrMat{S}, Q::HessenbergQ{T}) where {T,S} (*)(X, Adjoint(Q)) + @deprecate A_mul_B!(Q::HessenbergQ{T}, X::StridedVecOrMat{T}) where {T<:BlasFloat} mul2!(Q, X) + @deprecate A_mul_B!(X::StridedMatrix{T}, Q::HessenbergQ{T}) where {T<:BlasFloat} mul1!(X, Q) + @deprecate Ac_mul_B!(Q::HessenbergQ{T}, X::StridedVecOrMat{T}) where {T<:BlasFloat} mul2!(adjoint(Q), X) + @deprecate A_mul_Bc!(X::StridedMatrix{T}, Q::HessenbergQ{T}) where {T<:BlasFloat} mul1!(X, adjoint(Q)) + @deprecate Ac_mul_B(Q::HessenbergQ{T}, X::StridedVecOrMat{S}) where {T,S} (*)(adjoint(Q), X) + @deprecate A_mul_Bc(X::StridedVecOrMat{S}, Q::HessenbergQ{T}) where {T,S} (*)(X, adjoint(Q)) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/ldlt.jl, to deprecate @@ -2875,83 +1829,83 @@ end @deprecate A_mul_B!(C::StridedMatrix{T}, A::StridedMatrix{T}, B::Hermitian{T,<:StridedMatrix}) where {T<:BlasReal} mul!(C, A, B) @deprecate A_mul_B!(C::StridedMatrix{T}, A::Hermitian{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasComplex} mul!(C, A, B) @deprecate A_mul_B!(C::StridedMatrix{T}, A::StridedMatrix{T}, B::Hermitian{T,<:StridedMatrix}) where {T<:BlasComplex} mul!(C, A, B) - @deprecate At_mul_B(A::RealHermSymComplexSym, B::AbstractVector) (*)(Transpose(A), B) - @deprecate At_mul_B(A::RealHermSymComplexSym, B::AbstractMatrix) (*)(Transpose(A), B) - @deprecate A_mul_Bt(A::AbstractMatrix, B::RealHermSymComplexSym) (*)(A, Transpose(B)) - @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractVector) (*)(Adjoint(A), B) - @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractMatrix) (*)(Adjoint(A), B) - @deprecate A_mul_Bc(A::AbstractMatrix, B::RealHermSymComplexHerm) (*)(A, Adjoint(B)) - @deprecate A_mul_Bt(A::RowVector, B::RealHermSymComplexSym) (*)(A, Transpose(B)) - @deprecate A_mul_Bc(A::RowVector, B::RealHermSymComplexHerm) (*)(A, Adjoint(B)) - @deprecate At_mul_B(A::RealHermSymComplexSym, B::AbstractTriangular) (*)(Transpose(A), B) - @deprecate A_mul_Bt(A::AbstractTriangular, B::RealHermSymComplexSym) (*)(A, Transpose(B)) - @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractTriangular) (*)(Adjoint(A), B) - @deprecate A_mul_Bc(A::AbstractTriangular, B::RealHermSymComplexHerm) (*)(A, Adjoint(B)) + @deprecate At_mul_B(A::RealHermSymComplexSym, B::AbstractVector) (*)(transpose(A), B) + @deprecate At_mul_B(A::RealHermSymComplexSym, B::AbstractMatrix) (*)(transpose(A), B) + @deprecate A_mul_Bt(A::AbstractMatrix, B::RealHermSymComplexSym) (*)(A, transpose(B)) + @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractVector) (*)(adjoint(A), B) + @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractMatrix) (*)(adjoint(A), B) + @deprecate A_mul_Bc(A::AbstractMatrix, B::RealHermSymComplexHerm) (*)(A, adjoint(B)) + @deprecate A_mul_Bt(A::RowVector, B::RealHermSymComplexSym) (*)(A, transpose(B)) + @deprecate A_mul_Bc(A::RowVector, B::RealHermSymComplexHerm) (*)(A, adjoint(B)) + @deprecate At_mul_B(A::RealHermSymComplexSym, B::AbstractTriangular) (*)(transpose(A), B) + @deprecate A_mul_Bt(A::AbstractTriangular, B::RealHermSymComplexSym) (*)(A, transpose(B)) + @deprecate Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractTriangular) (*)(adjoint(A), B) + @deprecate A_mul_Bc(A::AbstractTriangular, B::RealHermSymComplexHerm) (*)(A, adjoint(B)) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/lu.jl, to deprecate @eval Base.LinAlg begin @deprecate A_ldiv_B!(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} ldiv!(A, B) @deprecate A_ldiv_B!(A::LU{<:Any,<:StridedMatrix}, B::StridedVecOrMat) ldiv!(A, B) - @deprecate At_ldiv_B!(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} ldiv!(Transpose(A), B) - @deprecate At_ldiv_B!(A::LU{<:Any,<:StridedMatrix}, B::StridedVecOrMat) ldiv!(Transpose(A), B) - @deprecate Ac_ldiv_B!(F::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:Real} ldiv!(Adjoint(F), B) - @deprecate Ac_ldiv_B!(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasComplex} ldiv!(Adjoint(A), B) - @deprecate Ac_ldiv_B!(A::LU{<:Any,<:StridedMatrix}, B::StridedVecOrMat) ldiv!(Adjoint(A), B) - @deprecate At_ldiv_Bt(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} (\)(Transpose(A), Transpose(B)) - @deprecate At_ldiv_Bt(A::LU, B::StridedVecOrMat) (\)(Transpose(A), Transpose(B)) - @deprecate Ac_ldiv_Bc(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasComplex} (\)(Adjoint(A), Adjoint(B)) - @deprecate Ac_ldiv_Bc(A::LU, B::StridedVecOrMat) (\)(Adjoint(A), Adjoint(B)) + @deprecate At_ldiv_B!(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} ldiv!(transpose(A), B) + @deprecate At_ldiv_B!(A::LU{<:Any,<:StridedMatrix}, B::StridedVecOrMat) ldiv!(transpose(A), B) + @deprecate Ac_ldiv_B!(F::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:Real} ldiv!(adjoint(F), B) + @deprecate Ac_ldiv_B!(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasComplex} ldiv!(adjoint(A), B) + @deprecate Ac_ldiv_B!(A::LU{<:Any,<:StridedMatrix}, B::StridedVecOrMat) ldiv!(adjoint(A), B) + @deprecate At_ldiv_Bt(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} (\)(transpose(A), transpose(B)) + @deprecate At_ldiv_Bt(A::LU, B::StridedVecOrMat) (\)(transpose(A), transpose(B)) + @deprecate Ac_ldiv_Bc(A::LU{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasComplex} (\)(adjoint(A), adjoint(B)) + @deprecate Ac_ldiv_Bc(A::LU, B::StridedVecOrMat) (\)(adjoint(A), adjoint(B)) @deprecate A_ldiv_B!(A::LU{T,Tridiagonal{T,V}}, B::AbstractVecOrMat) where {T,V} ldiv!(A, B) - @deprecate At_ldiv_B!(A::LU{T,Tridiagonal{T,V}}, B::AbstractVecOrMat) where {T,V} (\)(Transpose(A), B) - @deprecate Ac_ldiv_B!(A::LU{T,Tridiagonal{T,V}}, B::AbstractVecOrMat) where {T,V} ldiv!(Adjoint(A), B) + @deprecate At_ldiv_B!(A::LU{T,Tridiagonal{T,V}}, B::AbstractVecOrMat) where {T,V} (\)(transpose(A), B) + @deprecate Ac_ldiv_B!(A::LU{T,Tridiagonal{T,V}}, B::AbstractVecOrMat) where {T,V} ldiv!(adjoint(A), B) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/lq.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_mul_B!(A::LQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(A, B) - @deprecate A_mul_B!(A::LQ{T}, B::QR{T}) where {T<:BlasFloat} mul!(A, B) - @deprecate A_mul_B!(A::QR{T}, B::LQ{T}) where {T<:BlasFloat} mul!(A, B) - @deprecate A_mul_B!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(A, B) - @deprecate Ac_mul_B!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasReal} mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasComplex} mul!(Adjoint(A), B) - @deprecate Ac_mul_B(A::LQPackedQ, B::StridedVecOrMat) (*)(Adjoint(A), B) - @deprecate A_mul_Bc(A::LQPackedQ, B::StridedVecOrMat) (*)(A, Adjoint(B)) - @deprecate Ac_mul_Bc(A::LQPackedQ, B::StridedVecOrMat) (*)(Adjoint(A), Adjoint(B)) - @deprecate A_mul_B!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasFloat} mul!(A, B) - @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasReal} mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasComplex} mul!(A, Adjoint(B)) - @deprecate A_mul_Bc(A::StridedVecOrMat, Q::LQPackedQ) (*)(A, Adjoint(Q)) - @deprecate Ac_mul_Bc(A::StridedMatrix, Q::LQPackedQ) (*)(Adjoint(A), Adjoint(Q)) - @deprecate Ac_mul_B(A::StridedMatrix, Q::LQPackedQ) (*)(Adjoint(A), Q) + @deprecate A_mul_B!(A::LQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul2!(A, B) + @deprecate A_mul_B!(A::LQ{T}, B::QR{T}) where {T<:BlasFloat} A*B + @deprecate A_mul_B!(A::QR{T}, B::LQ{T}) where {T<:BlasFloat} A*B + @deprecate A_mul_B!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul2!(A, B) + @deprecate Ac_mul_B!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasReal} mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasComplex} mul2!(adjoint(A), B) + @deprecate Ac_mul_B(A::LQPackedQ, B::StridedVecOrMat) (*)(adjoint(A), B) + @deprecate A_mul_Bc(A::LQPackedQ, B::StridedVecOrMat) (*)(A, adjoint(B)) + @deprecate Ac_mul_Bc(A::LQPackedQ, B::StridedVecOrMat) (*)(adjoint(A), adjoint(B)) + @deprecate A_mul_B!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasFloat} mul1!(A, B) + @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasReal} mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasComplex} mul1!(A, adjoint(B)) + @deprecate A_mul_Bc(A::StridedVecOrMat, Q::LQPackedQ) (*)(A, adjoint(Q)) + @deprecate Ac_mul_Bc(A::StridedMatrix, Q::LQPackedQ) (*)(adjoint(A), adjoint(Q)) + @deprecate Ac_mul_B(A::StridedMatrix, Q::LQPackedQ) (*)(adjoint(A), Q) @deprecate A_ldiv_B!(A::LQ{T}, B::StridedVecOrMat{T}) where {T} ldiv!(A, B) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/qr.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_mul_B!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} mul!(A, B) - @deprecate A_mul_B!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} mul!(A, B) - @deprecate A_mul_B!(A::QRPackedQ, B::AbstractVecOrMat) mul!(A, B) - @deprecate Ac_mul_B!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::QRPackedQ, B::AbstractVecOrMat) mul!(Adjoint(A), B) - @deprecate Ac_mul_B(Q::AbstractQ, B::StridedVecOrMat) (*)(Adjoint(Q), B) - @deprecate A_mul_Bc(Q::AbstractQ, B::StridedVecOrMat) (*)(Q, Adjoint(B)) - @deprecate Ac_mul_Bc(Q::AbstractQ, B::StridedVecOrMat) (*)(Adjoint(Q), Adjoint(B)) - @deprecate A_mul_B!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} mul!(A, B) - @deprecate A_mul_B!(A::StridedVecOrMat{T}, B::QRPackedQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} mul!(A, B) - @deprecate A_mul_B!(A::StridedMatrix,Q::QRPackedQ) mul!(A, Q) - @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T}) where {T<:BlasReal} mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T}) where {T<:BlasComplex} mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRPackedQ{T}) where {T<:BlasReal} mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRPackedQ{T}) where {T<:BlasComplex} mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedMatrix,Q::QRPackedQ) mul!(A, Adjoint(Q)) - @deprecate A_mul_Bc(A::StridedMatrix, B::AbstractQ) (*)(A, Adjoint(B)) - @deprecate A_mul_Bc(rowvec::RowVector, B::AbstractQ) (*)(rowvec, Adjoint(B)) - @deprecate Ac_mul_B(A::StridedVecOrMat, Q::AbstractQ) (*)(Adjoint(A), Q) - @deprecate Ac_mul_Bc(A::StridedVecOrMat, Q::AbstractQ) (*)(Adjoint(A), Adjoint(Q)) + @deprecate A_mul_B!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} mul2!(A, B) + @deprecate A_mul_B!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} mul2!(A, B) + @deprecate A_mul_B!(A::QRPackedQ, B::AbstractVecOrMat) mul2!(A, B) + @deprecate Ac_mul_B!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::QRPackedQ, B::AbstractVecOrMat) mul2!(adjoint(A), B) + @deprecate Ac_mul_B(Q::AbstractQ, B::StridedVecOrMat) (*)(adjoint(Q), B) + @deprecate A_mul_Bc(Q::AbstractQ, B::StridedVecOrMat) (*)(Q, adjoint(B)) + @deprecate Ac_mul_Bc(Q::AbstractQ, B::StridedVecOrMat) (*)(adjoint(Q), adjoint(B)) + @deprecate A_mul_B!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} mul1!(A, B) + @deprecate A_mul_B!(A::StridedVecOrMat{T}, B::QRPackedQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} mul1!(A, B) + @deprecate A_mul_B!(A::StridedMatrix,Q::QRPackedQ) mul1!(A, Q) + @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T}) where {T<:BlasReal} mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T}) where {T<:BlasComplex} mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRPackedQ{T}) where {T<:BlasReal} mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedVecOrMat{T}, B::QRPackedQ{T}) where {T<:BlasComplex} mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedMatrix,Q::QRPackedQ) mul1!(A, adjoint(Q)) + @deprecate A_mul_Bc(A::StridedMatrix, B::AbstractQ) (*)(A, adjoint(B)) + @deprecate A_mul_Bc(rowvec::RowVector, B::AbstractQ) (*)(rowvec, adjoint(B)) + @deprecate Ac_mul_B(A::StridedVecOrMat, Q::AbstractQ) (*)(adjoint(A), Q) + @deprecate Ac_mul_Bc(A::StridedVecOrMat, Q::AbstractQ) (*)(adjoint(A), adjoint(Q)) @deprecate A_ldiv_B!(A::QRCompactWY{T}, b::StridedVector{T}) where {T<:BlasFloat} ldiv!(A, b) @deprecate A_ldiv_B!(A::QRCompactWY{T}, B::StridedMatrix{T}) where {T<:BlasFloat} ldiv!(A, B) @deprecate A_ldiv_B!(A::QRPivoted{T}, B::StridedMatrix{T}, rcond::Real) where {T<:BlasFloat} ldiv!(A, B, rcond) @@ -2965,186 +1919,186 @@ end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/matmul.jl, to deprecate @eval Base.LinAlg begin - @deprecate Ac_mul_Bc(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(Adjoint(A), Adjoint(B)) - @deprecate Ac_mul_Bc!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, Adjoint(A), Adjoint(B)) - @deprecate Ac_mul_Bc!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, Adjoint(A), Adjoint(B)) - @deprecate Ac_mul_Bt!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, Adjoint(A), Transpose(B)) - @deprecate A_mul_Bc!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasComplex} mul!(C, A, Adjoint(B)) - @deprecate A_mul_Bc!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, A, Adjoint(B)) - @deprecate A_mul_Bc(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(A, Adjoint(B)) - @deprecate A_mul_Bc(A::StridedMatrix{<:BlasFloat}, B::StridedMatrix{<:BlasReal}) (*)(A, Adjoint(B)) - @deprecate A_mul_Bc!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{<:BlasReal}) where {T<:BlasFloat} mul!(C, A, Adjoint(B)) - @deprecate Ac_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasComplex} mul!(C, Adjoint(A), B) - @deprecate Ac_mul_B!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, Adjoint(A), B) - @deprecate Ac_mul_B(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(Adjoint(A), B) - @deprecate Ac_mul_B(A::StridedMatrix{T}, B::StridedMatrix{T}) where {T<:BlasReal} (*)(Adjoint(A), B) - @deprecate Ac_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasReal} mul!(C, Adjoint(A), B) - @deprecate At_mul_Bt!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, Transpose(A), Transpose(B)) - @deprecate At_mul_Bt!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, Transpose(A), Transpose(B)) - @deprecate At_mul_Bt(A::AbstractMatrix{T}, B::AbstractVecOrMat{S}) where {T,S} (*)(Transpose(A), Transpose(B)) - @deprecate A_mul_Bt!(C::AbstractVecOrMat, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, A, Transpose(B)) - @deprecate A_mul_Bt!(C::StridedMatrix{Complex{Float32}}, A::StridedVecOrMat{Complex{Float32}}, B::StridedVecOrMat{Float32}) mul!(C, A, Transpose(B)) - @deprecate A_mul_Bt!(C::StridedMatrix{Complex{Float64}}, A::StridedVecOrMat{Complex{Float64}}, B::StridedVecOrMat{Float64}) mul!(C, A, Transpose(B)) - @deprecate A_mul_Bt!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, A, Transpose(B)) - @deprecate A_mul_Bt(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(A, Transpose(B)) - @deprecate At_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, Transpose(A), B) - @deprecate At_mul_B!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, Transpose(A), B) - @deprecate At_mul_B(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(Transpose(A), B) + @deprecate Ac_mul_Bc(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(adjoint(A), adjoint(B)) + @deprecate Ac_mul_Bc!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, adjoint(A), adjoint(B)) + @deprecate Ac_mul_Bc!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, adjoint(A), adjoint(B)) + @deprecate Ac_mul_Bt!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, adjoint(A), transpose(B)) + @deprecate A_mul_Bc!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasComplex} mul!(C, A, adjoint(B)) + @deprecate A_mul_Bc!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, A, adjoint(B)) + @deprecate A_mul_Bc(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(A, adjoint(B)) + @deprecate A_mul_Bc(A::StridedMatrix{<:BlasFloat}, B::StridedMatrix{<:BlasReal}) (*)(A, adjoint(B)) + @deprecate A_mul_Bc!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{<:BlasReal}) where {T<:BlasFloat} mul!(C, A, adjoint(B)) + @deprecate Ac_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasComplex} mul!(C, adjoint(A), B) + @deprecate Ac_mul_B!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, adjoint(A), B) + @deprecate Ac_mul_B(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(adjoint(A), B) + @deprecate Ac_mul_B(A::StridedMatrix{T}, B::StridedMatrix{T}) where {T<:BlasReal} (*)(adjoint(A), B) + @deprecate Ac_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasReal} mul!(C, adjoint(A), B) + @deprecate At_mul_Bt!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, transpose(A), transpose(B)) + @deprecate At_mul_Bt!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, transpose(A), transpose(B)) + @deprecate At_mul_Bt(A::AbstractMatrix{T}, B::AbstractVecOrMat{S}) where {T,S} (*)(transpose(A), transpose(B)) + @deprecate A_mul_Bt!(C::AbstractVecOrMat, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, A, transpose(B)) + @deprecate A_mul_Bt!(C::StridedMatrix{Complex{Float32}}, A::StridedVecOrMat{Complex{Float32}}, B::StridedVecOrMat{Float32}) mul!(C, A, transpose(B)) + @deprecate A_mul_Bt!(C::StridedMatrix{Complex{Float64}}, A::StridedVecOrMat{Complex{Float64}}, B::StridedVecOrMat{Float64}) mul!(C, A, transpose(B)) + @deprecate A_mul_Bt!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, A, transpose(B)) + @deprecate A_mul_Bt(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(A, transpose(B)) + @deprecate At_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, transpose(A), B) + @deprecate At_mul_B!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, transpose(A), B) + @deprecate At_mul_B(A::AbstractMatrix{T}, B::AbstractMatrix{S}) where {T,S} (*)(transpose(A), B) @deprecate A_mul_B!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) mul!(C, A, B) @deprecate A_mul_B!(C::StridedMatrix{Complex{Float32}}, A::StridedVecOrMat{Complex{Float32}}, B::StridedVecOrMat{Float32}) mul!(C, A, B) @deprecate A_mul_B!(C::StridedMatrix{Complex{Float64}}, A::StridedVecOrMat{Complex{Float64}}, B::StridedVecOrMat{Float64}) mul!(C, A, B) @deprecate A_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} mul!(C, A, B) - @deprecate Ac_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasReal} mul!(y, Adjoint(A), x) - @deprecate Ac_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasComplex} mul!(y, Adjoint(A), x) - @deprecate Ac_mul_B!(y::AbstractVector, A::AbstractVecOrMat, x::AbstractVector) mul!(y, Adjoint(A), x) - @deprecate Ac_mul_B(A::StridedMatrix{T}, x::StridedVector{S}) where {T<:BlasFloat,S} (*)(Adjoint(A), x) - @deprecate Ac_mul_B(A::AbstractMatrix{T}, x::AbstractVector{S}) where {T,S} (*)(Adjoint(A), x) - @deprecate At_mul_B(A::StridedMatrix{T}, x::StridedVector{S}) where {T<:BlasFloat,S} (*)(Transpose(A), x) - @deprecate At_mul_B(A::AbstractMatrix{T}, x::AbstractVector{S}) where {T,S} (*)(Transpose(A), x) - @deprecate At_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasFloat} mul!(y, Transpose(A), x) - @deprecate At_mul_B!(y::AbstractVector, A::AbstractVecOrMat, x::AbstractVector) mul!(y, Transpose(A), x) + @deprecate Ac_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasReal} mul!(y, adjoint(A), x) + @deprecate Ac_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasComplex} mul!(y, adjoint(A), x) + @deprecate Ac_mul_B!(y::AbstractVector, A::AbstractVecOrMat, x::AbstractVector) mul!(y, adjoint(A), x) + @deprecate Ac_mul_B(A::StridedMatrix{T}, x::StridedVector{S}) where {T<:BlasFloat,S} (*)(adjoint(A), x) + @deprecate Ac_mul_B(A::AbstractMatrix{T}, x::AbstractVector{S}) where {T,S} (*)(adjoint(A), x) + @deprecate At_mul_B(A::StridedMatrix{T}, x::StridedVector{S}) where {T<:BlasFloat,S} (*)(transpose(A), x) + @deprecate At_mul_B(A::AbstractMatrix{T}, x::AbstractVector{S}) where {T,S} (*)(transpose(A), x) + @deprecate At_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasFloat} mul!(y, transpose(A), x) + @deprecate At_mul_B!(y::AbstractVector, A::AbstractVecOrMat, x::AbstractVector) mul!(y, transpose(A), x) @deprecate A_mul_B!(y::AbstractVector, A::AbstractVecOrMat, x::AbstractVector) mul!(y, A, x) @deprecate A_mul_B!(y::StridedVector{Complex{Float32}}, A::StridedVecOrMat{Complex{Float32}}, x::StridedVector{Float32}) mul!(y, A, x) @deprecate A_mul_B!(y::StridedVector{Complex{Float64}}, A::StridedVecOrMat{Complex{Float64}}, x::StridedVector{Float64}) mul!(y, A, x) @deprecate A_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasFloat} mul!(y, A, x) - @deprecate A_mul_Bt(a::AbstractVector, B::AbstractMatrix) (*)(a, Transpose(B)) - @deprecate A_mul_Bt(A::AbstractMatrix, b::AbstractVector) (*)(A, Transpose(b)) - @deprecate A_mul_Bc(a::AbstractVector, B::AbstractMatrix) (*)(a, Adjoint(B)) - @deprecate A_mul_Bc(A::AbstractMatrix, b::AbstractVector) (*)(A, Adjoint(b)) - @deprecate At_mul_B(x::StridedVector{T}, y::StridedVector{T}) where {T<:BlasComplex} (*)(Transpose(x), y) + @deprecate A_mul_Bt(a::AbstractVector, B::AbstractMatrix) (*)(a, transpose(B)) + @deprecate A_mul_Bt(A::AbstractMatrix, b::AbstractVector) (*)(A, transpose(b)) + @deprecate A_mul_Bc(a::AbstractVector, B::AbstractMatrix) (*)(a, adjoint(B)) + @deprecate A_mul_Bc(A::AbstractMatrix, b::AbstractVector) (*)(A, adjoint(b)) + @deprecate At_mul_B(x::StridedVector{T}, y::StridedVector{T}) where {T<:BlasComplex} (*)(transpose(x), y) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/triangular.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_mul_Bc(A::AbstractTriangular, B::AbstractTriangular) (*)(A, Adjoint(B)) - @deprecate A_mul_Bt(A::AbstractTriangular, B::AbstractTriangular) (*)(A, Transpose(B)) - @deprecate Ac_mul_B(A::AbstractTriangular, B::AbstractTriangular) (*)(Adjoint(A), B) - @deprecate At_mul_B(A::AbstractTriangular, B::AbstractTriangular) (*)(Transpose(A), B) - @deprecate Ac_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::RowVector) (\)(Adjoint(A), B) - @deprecate Ac_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::RowVector) (\)(Adjoint(A), B) - @deprecate At_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::RowVector) (\)(Transpose(A), B) - @deprecate At_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::RowVector) (\)(Transpose(A), B) - @deprecate A_rdiv_Bc(rowvec::RowVector, A::Union{UpperTriangular,LowerTriangular}) (/)(rowvec, Adjoint(A)) - @deprecate A_rdiv_Bc(rowvec::RowVector, A::Union{UnitUpperTriangular,UnitLowerTriangular}) (/)(rowvec, Adjoint(A)) - @deprecate A_rdiv_Bt(rowvec::RowVector, A::Union{UpperTriangular,LowerTriangular}) (/)(rowvec, Transpose(A)) - @deprecate A_rdiv_Bt(rowvec::RowVector, A::Union{UnitUpperTriangular,UnitLowerTriangular}) (/)(rowvec, Transpose(A)) - @deprecate A_mul_Bt(rowvec::RowVector, A::AbstractTriangular) (*)(rowvec, Transpose(A)) - @deprecate A_mul_Bt(A::AbstractTriangular, rowvec::RowVector) (*)(A, Transpose(rowvec)) - @deprecate At_mul_Bt(A::AbstractTriangular, rowvec::RowVector) (*)(Transpose(A), Transpose(rowvec)) - @deprecate A_mul_Bc(rowvec::RowVector, A::AbstractTriangular) (*)(rowvec, Adjoint(A)) - @deprecate A_mul_Bc(A::AbstractTriangular, rowvec::RowVector) (*)(A, Adjoint(rowvec)) - @deprecate Ac_mul_Bc(A::AbstractTriangular, rowvec::RowVector) (*)(Adjoint(A), Adjoint(rowvec)) - @deprecate Ac_mul_B(A::AbstractMatrix, B::AbstractTriangular) (*)(Adjoint(A), B) - @deprecate At_mul_B(A::AbstractMatrix, B::AbstractTriangular) (*)(Transpose(A), B) - @deprecate A_mul_Bc(A::AbstractTriangular, B::AbstractMatrix) (*)(A, Adjoint(B)) - @deprecate A_mul_Bt(A::AbstractTriangular, B::AbstractMatrix) (*)(A, Transpose(B)) - @deprecate Ac_mul_Bc(A::AbstractTriangular, B::AbstractTriangular) (*)(Adjoint(A), Adjoint(B)) - @deprecate Ac_mul_Bc(A::AbstractTriangular, B::AbstractMatrix) (*)(Adjoint(A), Adjoint(B)) - @deprecate Ac_mul_Bc(A::AbstractMatrix, B::AbstractTriangular) (*)(Adjoint(A), Adjoint(B)) - @deprecate At_mul_Bt(A::AbstractTriangular, B::AbstractTriangular) (*)(Transpose(A), Transpose(B)) - @deprecate At_mul_Bt(A::AbstractTriangular, B::AbstractMatrix) (*)(Transpose(A), Transpose(B)) - @deprecate At_mul_Bt(A::AbstractMatrix, B::AbstractTriangular) (*)(Transpose(A), Transpose(B)) - @deprecate A_mul_Bc!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) mul!(A, Adjoint(B)) - @deprecate A_mul_Bt!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) mul!(A, Transpose(B)) - @deprecate A_mul_Bt!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) mul!(A, Transpose(B)) - @deprecate A_rdiv_Bc!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) rdiv!(A, Adjoint(B)) - @deprecate A_rdiv_Bc!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) rdiv!(A, Adjoint(B)) - @deprecate A_rdiv_Bt!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) rdiv!(A, Transpose(B)) - @deprecate A_rdiv_Bt!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) rdiv!(A, Transpose(B)) + @deprecate A_mul_Bc(A::AbstractTriangular, B::AbstractTriangular) (*)(A, adjoint(B)) + @deprecate A_mul_Bt(A::AbstractTriangular, B::AbstractTriangular) (*)(A, transpose(B)) + @deprecate Ac_mul_B(A::AbstractTriangular, B::AbstractTriangular) (*)(adjoint(A), B) + @deprecate At_mul_B(A::AbstractTriangular, B::AbstractTriangular) (*)(transpose(A), B) + @deprecate Ac_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::RowVector) (\)(adjoint(A), B) + @deprecate Ac_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::RowVector) (\)(adjoint(A), B) + @deprecate At_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::RowVector) (\)(transpose(A), B) + @deprecate At_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::RowVector) (\)(transpose(A), B) + @deprecate A_rdiv_Bc(rowvec::RowVector, A::Union{UpperTriangular,LowerTriangular}) (/)(rowvec, adjoint(A)) + @deprecate A_rdiv_Bc(rowvec::RowVector, A::Union{UnitUpperTriangular,UnitLowerTriangular}) (/)(rowvec, adjoint(A)) + @deprecate A_rdiv_Bt(rowvec::RowVector, A::Union{UpperTriangular,LowerTriangular}) (/)(rowvec, transpose(A)) + @deprecate A_rdiv_Bt(rowvec::RowVector, A::Union{UnitUpperTriangular,UnitLowerTriangular}) (/)(rowvec, transpose(A)) + @deprecate A_mul_Bt(rowvec::RowVector, A::AbstractTriangular) (*)(rowvec, transpose(A)) + @deprecate A_mul_Bt(A::AbstractTriangular, rowvec::RowVector) (*)(A, transpose(rowvec)) + @deprecate At_mul_Bt(A::AbstractTriangular, rowvec::RowVector) (*)(transpose(A), transpose(rowvec)) + @deprecate A_mul_Bc(rowvec::RowVector, A::AbstractTriangular) (*)(rowvec, adjoint(A)) + @deprecate A_mul_Bc(A::AbstractTriangular, rowvec::RowVector) (*)(A, adjoint(rowvec)) + @deprecate Ac_mul_Bc(A::AbstractTriangular, rowvec::RowVector) (*)(adjoint(A), adjoint(rowvec)) + @deprecate Ac_mul_B(A::AbstractMatrix, B::AbstractTriangular) (*)(adjoint(A), B) + @deprecate At_mul_B(A::AbstractMatrix, B::AbstractTriangular) (*)(transpose(A), B) + @deprecate A_mul_Bc(A::AbstractTriangular, B::AbstractMatrix) (*)(A, adjoint(B)) + @deprecate A_mul_Bt(A::AbstractTriangular, B::AbstractMatrix) (*)(A, transpose(B)) + @deprecate Ac_mul_Bc(A::AbstractTriangular, B::AbstractTriangular) (*)(adjoint(A), adjoint(B)) + @deprecate Ac_mul_Bc(A::AbstractTriangular, B::AbstractMatrix) (*)(adjoint(A), adjoint(B)) + @deprecate Ac_mul_Bc(A::AbstractMatrix, B::AbstractTriangular) (*)(adjoint(A), adjoint(B)) + @deprecate At_mul_Bt(A::AbstractTriangular, B::AbstractTriangular) (*)(transpose(A), transpose(B)) + @deprecate At_mul_Bt(A::AbstractTriangular, B::AbstractMatrix) (*)(transpose(A), transpose(B)) + @deprecate At_mul_Bt(A::AbstractMatrix, B::AbstractTriangular) (*)(transpose(A), transpose(B)) + @deprecate A_mul_Bc!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) mul1!(A, adjoint(B)) + @deprecate A_mul_Bt!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) mul1!(A, transpose(B)) + @deprecate A_mul_Bt!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) mul1!(A, transpose(B)) + @deprecate A_rdiv_Bc!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) rdiv!(A, adjoint(B)) + @deprecate A_rdiv_Bc!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) rdiv!(A, adjoint(B)) + @deprecate A_rdiv_Bt!(A::UpperTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) rdiv!(A, transpose(B)) + @deprecate A_rdiv_Bt!(A::LowerTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) rdiv!(A, transpose(B)) @deprecate A_rdiv_B!(A::UpperTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) rdiv!(A, B) @deprecate A_rdiv_B!(A::LowerTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) rdiv!(A, B) - @deprecate Ac_mul_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) mul!(Adjoint(A), B) - @deprecate At_mul_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) mul!(Transpose(A), B) - @deprecate At_mul_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) mul!(Transpose(A), B) - @deprecate Ac_ldiv_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) ldiv!(Adjoint(A), B) - @deprecate Ac_ldiv_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) ldiv!(Adjoint(A), B) - @deprecate At_ldiv_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) ldiv!(Transpose(A), B) - @deprecate At_ldiv_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) ldiv!(Transpose(A), B) - @deprecate A_rdiv_Bt!(A::StridedMatrix, B::UnitLowerTriangular) rdiv!(A, Transpose(B)) - @deprecate A_rdiv_Bt!(A::StridedMatrix, B::LowerTriangular) rdiv!(A, Transpose(B)) - @deprecate A_rdiv_Bt!(A::StridedMatrix, B::UnitUpperTriangular) rdiv!(A, Transpose(B)) - @deprecate A_rdiv_Bt!(A::StridedMatrix, B::UpperTriangular) rdiv!(A, Transpose(B)) - @deprecate A_rdiv_Bc!(A::StridedMatrix, B::UnitLowerTriangular) rdiv!(A, Adjoint(B)) - @deprecate A_rdiv_Bc!(A::StridedMatrix, B::LowerTriangular) rdiv!(A, Adjoint(B)) - @deprecate A_rdiv_Bc!(A::StridedMatrix, B::UnitUpperTriangular) rdiv!(A, Adjoint(B)) - @deprecate A_rdiv_Bc!(A::StridedMatrix, B::UpperTriangular) rdiv!(A, Adjoint(B)) + @deprecate Ac_mul_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) mul2!(adjoint(A), B) + @deprecate At_mul_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) mul2!(transpose(A), B) + @deprecate At_mul_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) mul2!(transpose(A), B) + @deprecate Ac_ldiv_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) ldiv!(adjoint(A), B) + @deprecate Ac_ldiv_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) ldiv!(adjoint(A), B) + @deprecate At_ldiv_B!(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) ldiv!(transpose(A), B) + @deprecate At_ldiv_B!(A::Union{UpperTriangular,UnitUpperTriangular}, B::LowerTriangular) ldiv!(transpose(A), B) + @deprecate A_rdiv_Bt!(A::StridedMatrix, B::UnitLowerTriangular) rdiv!(A, transpose(B)) + @deprecate A_rdiv_Bt!(A::StridedMatrix, B::LowerTriangular) rdiv!(A, transpose(B)) + @deprecate A_rdiv_Bt!(A::StridedMatrix, B::UnitUpperTriangular) rdiv!(A, transpose(B)) + @deprecate A_rdiv_Bt!(A::StridedMatrix, B::UpperTriangular) rdiv!(A, transpose(B)) + @deprecate A_rdiv_Bc!(A::StridedMatrix, B::UnitLowerTriangular) rdiv!(A, adjoint(B)) + @deprecate A_rdiv_Bc!(A::StridedMatrix, B::LowerTriangular) rdiv!(A, adjoint(B)) + @deprecate A_rdiv_Bc!(A::StridedMatrix, B::UnitUpperTriangular) rdiv!(A, adjoint(B)) + @deprecate A_rdiv_Bc!(A::StridedMatrix, B::UpperTriangular) rdiv!(A, adjoint(B)) @deprecate A_rdiv_B!(A::StridedMatrix, B::UnitLowerTriangular) rdiv!(A, B) @deprecate A_rdiv_B!(A::StridedMatrix, B::LowerTriangular) rdiv!(A, B) @deprecate A_rdiv_B!(A::StridedMatrix, B::UnitUpperTriangular) rdiv!(A, B) @deprecate A_rdiv_B!(A::StridedMatrix, B::UpperTriangular) rdiv!(A, B) - @deprecate Ac_ldiv_B!(A::UnitUpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Adjoint(A), b, x) - @deprecate Ac_ldiv_B!(A::UpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Adjoint(A), b, x) - @deprecate Ac_ldiv_B!(A::UnitLowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Adjoint(A), b, x) - @deprecate Ac_ldiv_B!(A::LowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Adjoint(A), b, x) - @deprecate At_ldiv_B!(A::UnitUpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Transpose(A), b, x) - @deprecate At_ldiv_B!(A::UpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Transpose(A), b, x) - @deprecate At_ldiv_B!(A::UnitLowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Transpose(A), b, x) - @deprecate At_ldiv_B!(A::LowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(Transpose(A), b, x) - @deprecate A_mul_Bt!(A::StridedMatrix, B::UnitLowerTriangular) mul!(A, Transpose(B)) - @deprecate A_mul_Bt!(A::StridedMatrix, B::LowerTriangular) mul!(A, Transpose(B)) - @deprecate A_mul_Bt!(A::StridedMatrix, B::UnitUpperTriangular) mul!(A, Transpose(B)) - @deprecate A_mul_Bt!(A::StridedMatrix, B::UpperTriangular) mul!(A, Transpose(B)) - @deprecate A_mul_Bc!(A::StridedMatrix, B::UnitLowerTriangular) mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedMatrix, B::LowerTriangular) mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedMatrix, B::UnitUpperTriangular) mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedMatrix, B::UpperTriangular) mul!(A, Adjoint(B)) - @deprecate A_mul_B!(A::StridedMatrix, B::UnitLowerTriangular) mul!(A, B) - @deprecate A_mul_B!(A::StridedMatrix, B::LowerTriangular) mul!(A, B) - @deprecate A_mul_B!(A::StridedMatrix, B::UnitUpperTriangular) mul!(A, B) - @deprecate A_mul_B!(A::StridedMatrix, B::UpperTriangular) mul!(A, B) - @deprecate At_mul_B!(A::UnitLowerTriangular, B::StridedVecOrMat) mul!(Transpose(A), B) - @deprecate At_mul_B!(A::LowerTriangular, B::StridedVecOrMat) mul!(Transpose(A), B) - @deprecate At_mul_B!(A::UnitUpperTriangular, B::StridedVecOrMat) mul!(Transpose(A), B) - @deprecate At_mul_B!(A::UpperTriangular, B::StridedVecOrMat) mul!(Transpose(A), B) - @deprecate Ac_mul_B!(A::UnitLowerTriangular, B::StridedVecOrMat) mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::LowerTriangular, B::StridedVecOrMat) mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::UnitUpperTriangular, B::StridedVecOrMat) mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::UpperTriangular, B::StridedVecOrMat) mul!(Adjoint(A), B) - @deprecate A_mul_B!(A::UnitLowerTriangular, B::StridedVecOrMat) mul!(A, B) - @deprecate A_mul_B!(A::LowerTriangular, B::StridedVecOrMat) mul!(A, B) - @deprecate A_mul_B!(A::UnitUpperTriangular, B::StridedVecOrMat) mul!(A, B) - @deprecate A_mul_B!(A::UpperTriangular, B::StridedVecOrMat) mul!(A, B) + @deprecate Ac_ldiv_B!(A::UnitUpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(adjoint(A), b, x) + @deprecate Ac_ldiv_B!(A::UpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(adjoint(A), b, x) + @deprecate Ac_ldiv_B!(A::UnitLowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(adjoint(A), b, x) + @deprecate Ac_ldiv_B!(A::LowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(adjoint(A), b, x) + @deprecate At_ldiv_B!(A::UnitUpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(transpose(A), b, x) + @deprecate At_ldiv_B!(A::UpperTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(transpose(A), b, x) + @deprecate At_ldiv_B!(A::UnitLowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(transpose(A), b, x) + @deprecate At_ldiv_B!(A::LowerTriangular, b::AbstractVector, x::AbstractVector = b) ldiv!(transpose(A), b, x) + @deprecate A_mul_Bt!(A::StridedMatrix, B::UnitLowerTriangular) mul1!(A, transpose(B)) + @deprecate A_mul_Bt!(A::StridedMatrix, B::LowerTriangular) mul1!(A, transpose(B)) + @deprecate A_mul_Bt!(A::StridedMatrix, B::UnitUpperTriangular) mul1!(A, transpose(B)) + @deprecate A_mul_Bt!(A::StridedMatrix, B::UpperTriangular) mul1!(A, transpose(B)) + @deprecate A_mul_Bc!(A::StridedMatrix, B::UnitLowerTriangular) mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedMatrix, B::LowerTriangular) mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedMatrix, B::UnitUpperTriangular) mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedMatrix, B::UpperTriangular) mul1!(A, adjoint(B)) + @deprecate A_mul_B!(A::StridedMatrix, B::UnitLowerTriangular) mul1!(A, B) + @deprecate A_mul_B!(A::StridedMatrix, B::LowerTriangular) mul1!(A, B) + @deprecate A_mul_B!(A::StridedMatrix, B::UnitUpperTriangular) mul1!(A, B) + @deprecate A_mul_B!(A::StridedMatrix, B::UpperTriangular) mul1!(A, B) + @deprecate At_mul_B!(A::UnitLowerTriangular, B::StridedVecOrMat) mul2!(transpose(A), B) + @deprecate At_mul_B!(A::LowerTriangular, B::StridedVecOrMat) mul2!(transpose(A), B) + @deprecate At_mul_B!(A::UnitUpperTriangular, B::StridedVecOrMat) mul2!(transpose(A), B) + @deprecate At_mul_B!(A::UpperTriangular, B::StridedVecOrMat) mul2!(transpose(A), B) + @deprecate Ac_mul_B!(A::UnitLowerTriangular, B::StridedVecOrMat) mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::LowerTriangular, B::StridedVecOrMat) mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::UnitUpperTriangular, B::StridedVecOrMat) mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::UpperTriangular, B::StridedVecOrMat) mul2!(adjoint(A), B) + @deprecate A_mul_B!(A::UnitLowerTriangular, B::StridedVecOrMat) mul2!(A, B) + @deprecate A_mul_B!(A::LowerTriangular, B::StridedVecOrMat) mul2!(A, B) + @deprecate A_mul_B!(A::UnitUpperTriangular, B::StridedVecOrMat) mul2!(A, B) + @deprecate A_mul_B!(A::UpperTriangular, B::StridedVecOrMat) mul2!(A, B) @deprecate A_mul_B!(C::AbstractVector , A::AbstractTriangular, B::AbstractVector) mul!(C, A, B) @deprecate A_mul_B!(C::AbstractMatrix , A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, B) @deprecate A_mul_B!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, B) - @deprecate Ac_mul_B!(C::AbstractVector , A::AbstractTriangular, B::AbstractVector) mul!(C, Adjoint(A), B) - @deprecate Ac_mul_B!(C::AbstractMatrix , A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, Adjoint(A), B) - @deprecate Ac_mul_B!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, Adjoint(A), B) - @deprecate At_mul_B!(C::AbstractVector , A::AbstractTriangular, B::AbstractVector) mul!(C, Transpose(A), B) - @deprecate At_mul_B!(C::AbstractMatrix , A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, Transpose(A), B) - @deprecate At_mul_B!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, Transpose(A), B) - @deprecate A_mul_B!(A::Tridiagonal, B::AbstractTriangular) mul!(A, B) + @deprecate Ac_mul_B!(C::AbstractVector , A::AbstractTriangular, B::AbstractVector) mul!(C, adjoint(A), B) + @deprecate Ac_mul_B!(C::AbstractMatrix , A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, adjoint(A), B) + @deprecate Ac_mul_B!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, adjoint(A), B) + @deprecate At_mul_B!(C::AbstractVector , A::AbstractTriangular, B::AbstractVector) mul!(C, transpose(A), B) + @deprecate At_mul_B!(C::AbstractMatrix , A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, transpose(A), B) + @deprecate At_mul_B!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, transpose(A), B) + @deprecate A_mul_B!(A::Tridiagonal, B::AbstractTriangular) mul2!(A, B) @deprecate A_mul_B!(C::AbstractMatrix, A::AbstractTriangular, B::Tridiagonal) mul!(C, A, B) @deprecate A_mul_B!(C::AbstractMatrix, A::Tridiagonal, B::AbstractTriangular) mul!(C, A, B) - @deprecate A_mul_Bt!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, Transpose(B)) - @deprecate A_mul_Bc!(C::AbstractMatrix, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, Adjoint(B)) - @deprecate A_mul_Bc!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, Adjoint(B)) + @deprecate A_mul_Bt!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, transpose(B)) + @deprecate A_mul_Bc!(C::AbstractMatrix, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, adjoint(B)) + @deprecate A_mul_Bc!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) mul!(C, A, adjoint(B)) end for mat in (:AbstractVector, :AbstractMatrix) @eval Base.LinAlg begin - @deprecate Ac_mul_B(A::AbstractTriangular, B::$mat) (*)(Adjoint(A), B) - @deprecate At_mul_B(A::AbstractTriangular, B::$mat) (*)(Transpose(A), B) - @deprecate Ac_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::$mat) (\)(Adjoint(A), B) - @deprecate At_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::$mat) (\)(Transpose(A), B) - @deprecate Ac_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::$mat) (\)(Adjoint(A), B) - @deprecate At_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::$mat) (\)(Transpose(A), B) - @deprecate A_rdiv_Bc(A::$mat, B::Union{UnitUpperTriangular, UnitLowerTriangular}) (/)(A, Adjoint(B)) - @deprecate A_rdiv_Bt(A::$mat, B::Union{UnitUpperTriangular, UnitLowerTriangular}) (/)(A, Transpose(B)) - @deprecate A_rdiv_Bc(A::$mat, B::Union{UpperTriangular,LowerTriangular}) (/)(A, Adjoint(B)) - @deprecate A_rdiv_Bt(A::$mat, B::Union{UpperTriangular,LowerTriangular}) (/)(A, Transpose(B)) + @deprecate Ac_mul_B(A::AbstractTriangular, B::$mat) (*)(adjoint(A), B) + @deprecate At_mul_B(A::AbstractTriangular, B::$mat) (*)(transpose(A), B) + @deprecate Ac_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::$mat) (\)(adjoint(A), B) + @deprecate At_ldiv_B(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::$mat) (\)(transpose(A), B) + @deprecate Ac_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::$mat) (\)(adjoint(A), B) + @deprecate At_ldiv_B(A::Union{UpperTriangular,LowerTriangular}, B::$mat) (\)(transpose(A), B) + @deprecate A_rdiv_Bc(A::$mat, B::Union{UnitUpperTriangular, UnitLowerTriangular}) (/)(A, adjoint(B)) + @deprecate A_rdiv_Bt(A::$mat, B::Union{UnitUpperTriangular, UnitLowerTriangular}) (/)(A, transpose(B)) + @deprecate A_rdiv_Bc(A::$mat, B::Union{UpperTriangular,LowerTriangular}) (/)(A, adjoint(B)) + @deprecate A_rdiv_Bt(A::$mat, B::Union{UpperTriangular,LowerTriangular}) (/)(A, transpose(B)) end end @eval Base.LinAlg begin - @deprecate A_mul_Bc(A::AbstractMatrix, B::AbstractTriangular) (*)(A, Adjoint(B)) - @deprecate A_mul_Bt(A::AbstractMatrix, B::AbstractTriangular) (*)(A, Transpose(B)) + @deprecate A_mul_Bc(A::AbstractMatrix, B::AbstractTriangular) (*)(A, adjoint(B)) + @deprecate A_mul_Bt(A::AbstractMatrix, B::AbstractTriangular) (*)(A, transpose(B)) end for (f, op, transform) in ( - (:A_mul_Bc, :*, :Adjoint), - (:A_mul_Bt, :*, :Transpose), - (:A_rdiv_Bc, :/, :Adjoint), - (:A_rdiv_Bt, :/, :Transpose)) + (:A_mul_Bc, :*, :adjoint), + (:A_mul_Bt, :*, :transpose), + (:A_rdiv_Bc, :/, :adjoint), + (:A_rdiv_Bt, :/, :transpose)) @eval Base.LinAlg begin @deprecate $f(A::LowerTriangular, B::UpperTriangular) ($op)(A, ($transform)(B)) @deprecate $f(A::LowerTriangular, B::UnitUpperTriangular) ($op)(A, ($transform)(B)) @@ -3153,10 +2107,10 @@ for (f, op, transform) in ( end end for (f, op, transform) in ( - (:Ac_mul_B, :*, :Adjoint), - (:At_mul_B, :*, :Transpose), - (:Ac_ldiv_B, :\, :Adjoint), - (:At_ldiv_B, :\, :Transpose)) + (:Ac_mul_B, :*, :adjoint), + (:At_mul_B, :*, :transpose), + (:Ac_ldiv_B, :\, :adjoint), + (:At_ldiv_B, :\, :transpose)) @eval Base.LinAlg begin @deprecate ($f)(A::UpperTriangular, B::LowerTriangular) ($op)(($transform)(A), B) @deprecate ($f)(A::UnitUpperTriangular, B::LowerTriangular) ($op)(($transform)(A), B) @@ -3170,135 +2124,132 @@ for (t, uploc, isunitc) in ((:LowerTriangular, 'L', 'N'), (:UnitUpperTriangular, 'U', 'U')) @eval Base.LinAlg begin # Vector multiplication - @deprecate A_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasFloat} mul!(A, b) - @deprecate At_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasFloat} mul!(Transpose(A), b) - @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasReal} mul!(Adjoint(A), b) - @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasComplex} mul!(Adjoint(A), b) + @deprecate A_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasFloat} mul2!(A, b) + @deprecate At_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasFloat} mul2!(transpose(A), b) + @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasReal} mul2!(adjoint(A), b) + @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasComplex} mul2!(adjoint(A), b) # Matrix multiplication - @deprecate A_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasFloat} mul!(A, B) - @deprecate A_mul_B!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} mul!(A, B) + @deprecate A_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasFloat} mul2!(A, B) + @deprecate A_mul_B!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} mul1!(A, B) - @deprecate At_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasFloat} mul!(Transpose(A), B) - @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasComplex} mul!(Adjoint(A), B) - @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasReal} mul!(Adjoint(A), B) + @deprecate At_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasFloat} mul2!(transpose(A), B) + @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasComplex} mul2!(adjoint(A), B) + @deprecate Ac_mul_B!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasReal} mul2!(adjoint(A), B) - @deprecate A_mul_Bt!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} mul!(A, Transpose(B)) - @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasComplex} mul!(A, Adjoint(B)) - @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasReal} mul!(A, Adjoint(B)) + @deprecate A_mul_Bt!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} mul1!(A, transpose(B)) + @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasComplex} mul1!(A, adjoint(B)) + @deprecate A_mul_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasReal} mul1!(A, adjoint(B)) # Left division @deprecate A_ldiv_B!(A::$t{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} ldiv!(A, B) - @deprecate At_ldiv_B!(A::$t{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} ldiv!(Transpose(A), B) - @deprecate Ac_ldiv_B!(A::$t{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasReal} ldiv!(Adjoint(A), B) - @deprecate Ac_ldiv_B!(A::$t{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasComplex} ldiv!(Adjoint(A), B) + @deprecate At_ldiv_B!(A::$t{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} ldiv!(transpose(A), B) + @deprecate Ac_ldiv_B!(A::$t{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasReal} ldiv!(adjoint(A), B) + @deprecate Ac_ldiv_B!(A::$t{T,<:StridedMatrix}, B::StridedVecOrMat{T}) where {T<:BlasComplex} ldiv!(adjoint(A), B) # Right division @deprecate A_rdiv_B!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} rdiv!(A, B) - @deprecate A_rdiv_Bt!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} rdiv!(A, Transpose(B)) - @deprecate A_rdiv_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasReal} rdiv!(A, Adjoint(B)) - @deprecate A_rdiv_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasComplex} rdiv!(A, Adjoint(B)) + @deprecate A_rdiv_Bt!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} rdiv!(A, transpose(B)) + @deprecate A_rdiv_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasReal} rdiv!(A, adjoint(B)) + @deprecate A_rdiv_Bc!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasComplex} rdiv!(A, adjoint(B)) end end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/rowvector.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_rdiv_Bt(rowvec::RowVector, mat::AbstractMatrix) (/)(rowvec, Transpose(mat)) - @deprecate A_rdiv_Bc(rowvec::RowVector, mat::AbstractMatrix) (/)(rowvec, Adjoint(mat)) - @deprecate At_ldiv_B(mat::AbstractMatrix, rowvec::RowVector) (\)(Transpose(mat), rowvec) - @deprecate Ac_ldiv_B(mat::AbstractMatrix, rowvec::RowVector) (\)(Adjoint(mat), rowvec) - @deprecate Ac_mul_B(u::RowVector, v::AbstractVector) (*)(Adjoint(u), v) - @deprecate Ac_mul_B(vec::AbstractVector, mat::AbstractMatrix) (*)(Adjoint(vec), mat) - @deprecate Ac_mul_B(rowvec1::RowVector, rowvec2::RowVector) (*)(Adjoint(rowvec1), rowvec2) - @deprecate Ac_mul_B(vec::AbstractVector, rowvec::RowVector) (*)(Adjoint(vec), rowvec) - @deprecate Ac_mul_B(vec1::AbstractVector, vec2::AbstractVector) (*)(Adjoint(vec1), vec2) - @deprecate Ac_mul_Bc(rowvec::RowVector, vec::AbstractVector) (*)(Adjoint(rowvec), Adjoint(vec)) - @deprecate Ac_mul_Bc(vec::AbstractVector, mat::AbstractMatrix) (*)(Adjoint(vec), Adjoint(mat)) - @deprecate Ac_mul_Bc(rowvec1::RowVector, rowvec2::RowVector) (*)(Adjoint(rowvec1), Adjoint(rowvec2)) - @deprecate Ac_mul_Bc(vec::AbstractVector, rowvec::RowVector) (*)(Adjoint(vec), Adjoint(rowvec)) - @deprecate Ac_mul_Bc(vec::AbstractVector, rowvec::AbstractVector) (*)(Adjoint(vec), Adjoint(rowvec)) - @deprecate Ac_mul_Bc(mat::AbstractMatrix, rowvec::RowVector) (*)(Adjoint(mat), Adjoint(rowvec)) - @deprecate A_mul_Bc(u::RowVector, v::AbstractVector) (*)(u, Adjoint(v)) - @deprecate A_mul_Bc(rowvec::RowVector, mat::AbstractMatrix) (*)(rowvec, Adjoint(mat)) - @deprecate A_mul_Bc(rowvec1::RowVector, rowvec2::RowVector) (*)(rowvec1, Adjoint(rowvec2)) - @deprecate A_mul_Bc(vec::AbstractVector, rowvec::RowVector) (*)(vec, Adjoint(rowvec)) - @deprecate A_mul_Bc(vec1::AbstractVector, vec2::AbstractVector) (*)(vec1, Adjoint(vec2)) - @deprecate A_mul_Bc(mat::AbstractMatrix, rowvec::RowVector) (*)(mat, Adjoint(rowvec)) - @deprecate At_mul_B(v::RowVector, u::AbstractVector) (*)(Transpose(v), u) - @deprecate At_mul_B(vec::AbstractVector, mat::AbstractMatrix) (*)(Transpose(vec), mat) - @deprecate At_mul_B(rowvec1::RowVector, rowvec2::RowVector) (*)(Transpose(rowvec1), rowvec2) - @deprecate At_mul_B(vec::AbstractVector, rowvec::RowVector) (*)(Transpose(vec), rowvec) - @deprecate At_mul_B(vec1::AbstractVector{T}, vec2::AbstractVector{T}) where {T<:Real} (*)(Transpose(vec1), vec2) - @deprecate At_mul_B(vec1::AbstractVector, vec2::AbstractVector) (*)(Transpose(vec1), vec2) - @deprecate At_mul_Bt(rowvec::RowVector, vec::AbstractVector) (*)(Transpose(rowvec), Transpose(vec)) - @deprecate At_mul_Bt(vec::AbstractVector, mat::AbstractMatrix) (*)(Transpose(vec), Transpose(mat)) - @deprecate At_mul_Bt(rowvec1::RowVector, rowvec2::RowVector) (*)(Transpose(rowvec1), Transpose(rowvec2)) - @deprecate At_mul_Bt(vec::AbstractVector, rowvec::RowVector) (*)(Transpose(vec), Transpose(rowvec)) - @deprecate At_mul_Bt(vec::AbstractVector, rowvec::AbstractVector) (*)(Transpose(vec), Transpose(rowvec)) - @deprecate At_mul_Bt(mat::AbstractMatrix, rowvec::RowVector) (*)(Transpose(mat), Transpose(rowvec)) - @deprecate A_mul_Bt(v::RowVector, A::AbstractVector) (*)(v, Transpose(A)) - @deprecate A_mul_Bt(rowvec::RowVector, mat::AbstractMatrix) (*)(rowvec, Transpose(mat)) - @deprecate A_mul_Bt(rowvec1::RowVector, rowvec2::RowVector) (*)(rowvec1, Transpose(rowvec2)) - @deprecate A_mul_Bt(vec::AbstractVector, rowvec::RowVector) (*)(vec, Transpose(rowvec)) - @deprecate A_mul_Bt(vec1::AbstractVector, vec2::AbstractVector) (*)(vec1, Transpose(vec2)) - @deprecate A_mul_Bt(mat::AbstractMatrix, rowvec::RowVector) (*)(mat, Transpose(rowvec)) + @deprecate A_rdiv_Bt(rowvec::RowVector, mat::AbstractMatrix) (/)(rowvec, transpose(mat)) + @deprecate A_rdiv_Bc(rowvec::RowVector, mat::AbstractMatrix) (/)(rowvec, adjoint(mat)) + @deprecate At_ldiv_B(mat::AbstractMatrix, rowvec::RowVector) (\)(transpose(mat), rowvec) + @deprecate Ac_ldiv_B(mat::AbstractMatrix, rowvec::RowVector) (\)(adjoint(mat), rowvec) + @deprecate Ac_mul_B(u::RowVector, v::AbstractVector) (*)(adjoint(u), v) + @deprecate Ac_mul_B(vec::AbstractVector, mat::AbstractMatrix) (*)(adjoint(vec), mat) + @deprecate Ac_mul_B(rowvec1::RowVector, rowvec2::RowVector) (*)(adjoint(rowvec1), rowvec2) + @deprecate Ac_mul_B(vec::AbstractVector, rowvec::RowVector) (*)(adjoint(vec), rowvec) + @deprecate Ac_mul_B(vec1::AbstractVector, vec2::AbstractVector) (*)(adjoint(vec1), vec2) + @deprecate Ac_mul_Bc(rowvec::RowVector, vec::AbstractVector) (*)(adjoint(rowvec), adjoint(vec)) + @deprecate Ac_mul_Bc(vec::AbstractVector, mat::AbstractMatrix) (*)(adjoint(vec), adjoint(mat)) + @deprecate Ac_mul_Bc(rowvec1::RowVector, rowvec2::RowVector) (*)(adjoint(rowvec1), adjoint(rowvec2)) + @deprecate Ac_mul_Bc(vec::AbstractVector, rowvec::RowVector) (*)(adjoint(vec), adjoint(rowvec)) + @deprecate Ac_mul_Bc(vec::AbstractVector, rowvec::AbstractVector) (*)(adjoint(vec), adjoint(rowvec)) + @deprecate Ac_mul_Bc(mat::AbstractMatrix, rowvec::RowVector) (*)(adjoint(mat), adjoint(rowvec)) + @deprecate A_mul_Bc(u::RowVector, v::AbstractVector) (*)(u, adjoint(v)) + @deprecate A_mul_Bc(rowvec::RowVector, mat::AbstractMatrix) (*)(rowvec, adjoint(mat)) + @deprecate A_mul_Bc(rowvec1::RowVector, rowvec2::RowVector) (*)(rowvec1, adjoint(rowvec2)) + @deprecate A_mul_Bc(vec::AbstractVector, rowvec::RowVector) (*)(vec, adjoint(rowvec)) + @deprecate A_mul_Bc(vec1::AbstractVector, vec2::AbstractVector) (*)(vec1, adjoint(vec2)) + @deprecate A_mul_Bc(mat::AbstractMatrix, rowvec::RowVector) (*)(mat, adjoint(rowvec)) + @deprecate At_mul_B(v::RowVector, u::AbstractVector) (*)(transpose(v), u) + @deprecate At_mul_B(vec::AbstractVector, mat::AbstractMatrix) (*)(transpose(vec), mat) + @deprecate At_mul_B(rowvec1::RowVector, rowvec2::RowVector) (*)(transpose(rowvec1), rowvec2) + @deprecate At_mul_B(vec::AbstractVector, rowvec::RowVector) (*)(transpose(vec), rowvec) + @deprecate At_mul_B(vec1::AbstractVector{T}, vec2::AbstractVector{T}) where {T<:Real} (*)(transpose(vec1), vec2) + @deprecate At_mul_B(vec1::AbstractVector, vec2::AbstractVector) (*)(transpose(vec1), vec2) + @deprecate At_mul_Bt(rowvec::RowVector, vec::AbstractVector) (*)(transpose(rowvec), transpose(vec)) + @deprecate At_mul_Bt(vec::AbstractVector, mat::AbstractMatrix) (*)(transpose(vec), transpose(mat)) + @deprecate At_mul_Bt(rowvec1::RowVector, rowvec2::RowVector) (*)(transpose(rowvec1), transpose(rowvec2)) + @deprecate At_mul_Bt(vec::AbstractVector, rowvec::RowVector) (*)(transpose(vec), transpose(rowvec)) + @deprecate At_mul_Bt(vec::AbstractVector, rowvec::AbstractVector) (*)(transpose(vec), transpose(rowvec)) + @deprecate At_mul_Bt(mat::AbstractMatrix, rowvec::RowVector) (*)(transpose(mat), transpose(rowvec)) + @deprecate A_mul_Bt(v::RowVector, A::AbstractVector) (*)(v, transpose(A)) + @deprecate A_mul_Bt(rowvec::RowVector, mat::AbstractMatrix) (*)(rowvec, transpose(mat)) + @deprecate A_mul_Bt(rowvec1::RowVector, rowvec2::RowVector) (*)(rowvec1, transpose(rowvec2)) + @deprecate A_mul_Bt(vec::AbstractVector, rowvec::RowVector) (*)(vec, transpose(rowvec)) + @deprecate A_mul_Bt(vec1::AbstractVector, vec2::AbstractVector) (*)(vec1, transpose(vec2)) + @deprecate A_mul_Bt(mat::AbstractMatrix, rowvec::RowVector) (*)(mat, transpose(rowvec)) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/linalg/givens.jl, to deprecate @eval Base.LinAlg begin - @deprecate A_mul_Bc!(A::AbstractMatrix, R::Rotation) mul!(A, Adjoint(R)) - @deprecate A_mul_B!(R::Rotation, A::AbstractMatrix) mul!(R, A) - @deprecate A_mul_B!(G::Givens, R::Rotation) mul!(G, R) - @deprecate A_mul_Bc!(A::AbstractMatrix, G::Givens) mul!(A, Adjoint(G)) - @deprecate A_mul_B!(G::Givens, A::AbstractVecOrMat) mul!(G, A) - @deprecate A_mul_B!(G1::Givens, G2::Givens) mul!(G1, G2) - @deprecate A_mul_Bc(A::AbstractVecOrMat{T}, R::AbstractRotation{S}) where {T,S} (*)(A, Adjoint(R)) + @deprecate A_mul_Bc!(A::AbstractMatrix, R::Rotation) mul1!(A, adjoint(R)) + @deprecate A_mul_B!(R::Rotation, A::AbstractMatrix) mul2!(R, A) + @deprecate A_mul_B!(G::Givens, R::Rotation) mul2!(G, R) + @deprecate A_mul_Bc!(A::AbstractMatrix, G::Givens) mul1!(A, adjoint(G)) + @deprecate A_mul_B!(G::Givens, A::AbstractVecOrMat) mul2!(G, A) + @deprecate A_mul_B!(G1::Givens, G2::Givens) G1 * G2 + @deprecate A_mul_Bc(A::AbstractVecOrMat{T}, R::AbstractRotation{S}) where {T,S} (*)(A, adjoint(R)) end -# former imports into SparseArrays +# A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/sparse/linalg.jl, to deprecate @eval Base.SparseArrays begin import Base: A_mul_B!, Ac_mul_B, Ac_mul_B!, At_mul_B, At_mul_B! import Base: A_mul_Bc, A_mul_Bt, Ac_mul_Bc, At_mul_Bt import Base: At_ldiv_B, Ac_ldiv_B, A_ldiv_B! - import Base.LinAlg: At_ldiv_B!, Ac_ldiv_B!, A_rdiv_B!, A_rdiv_Bc!, mul!, ldiv!, rdiv! -end + import Base.LinAlg: At_ldiv_B!, Ac_ldiv_B!, A_rdiv_B!, A_rdiv_Bc! -# A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/sparse/linalg.jl, to deprecate -@eval Base.SparseArrays begin using Base.LinAlg: Adjoint, Transpose - @deprecate Ac_ldiv_B(A::SparseMatrixCSC, B::RowVector) (\)(Adjoint(A), B) - @deprecate At_ldiv_B(A::SparseMatrixCSC, B::RowVector) (\)(Transpose(A), B) - @deprecate Ac_ldiv_B(A::SparseMatrixCSC, B::AbstractVecOrMat) (\)(Adjoint(A), B) - @deprecate At_ldiv_B(A::SparseMatrixCSC, B::AbstractVecOrMat) (\)(Transpose(A), B) - @deprecate A_rdiv_Bc!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, Adjoint(D)) - @deprecate A_rdiv_Bt!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, Transpose(D)) + @deprecate Ac_ldiv_B(A::SparseMatrixCSC, B::RowVector) (\)(adjoint(A), B) + @deprecate At_ldiv_B(A::SparseMatrixCSC, B::RowVector) (\)(transpose(A), B) + @deprecate Ac_ldiv_B(A::SparseMatrixCSC, B::AbstractVecOrMat) (\)(adjoint(A), B) + @deprecate At_ldiv_B(A::SparseMatrixCSC, B::AbstractVecOrMat) (\)(transpose(A), B) + @deprecate A_rdiv_Bc!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, adjoint(D)) + @deprecate A_rdiv_Bt!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, transpose(D)) @deprecate A_rdiv_B!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, D) @deprecate A_ldiv_B!(L::LowerTriangular{T,<:SparseMatrixCSCUnion{T}}, B::StridedVecOrMat) where {T} ldiv!(L, B) @deprecate A_ldiv_B!(U::UpperTriangular{T,<:SparseMatrixCSCUnion{T}}, B::StridedVecOrMat) where {T} ldiv!(U, B) - @deprecate A_mul_Bt(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(A, Transpose(B)) - @deprecate A_mul_Bc(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(A, Adjoint(B)) - @deprecate At_mul_B(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(Transpose(A), B) - @deprecate Ac_mul_B(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(Adjoint(A), B) - @deprecate At_mul_Bt(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(Transpose(A), Transpose(B)) - @deprecate Ac_mul_Bc(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(Adjoint(A), Adjoint(B)) + @deprecate A_mul_Bt(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(A, transpose(B)) + @deprecate A_mul_Bc(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(A, adjoint(B)) + @deprecate At_mul_B(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(transpose(A), B) + @deprecate Ac_mul_B(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(adjoint(A), B) + @deprecate At_mul_Bt(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(transpose(A), transpose(B)) + @deprecate Ac_mul_Bc(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(adjoint(A), adjoint(B)) @deprecate A_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, A, B) - @deprecate Ac_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, Adjoint(A), B) - @deprecate At_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, Transpose(A), B) + @deprecate Ac_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, adjoint(A), B) + @deprecate At_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, transpose(A), B) @deprecate A_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, A, B, β, C) @deprecate A_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(A, x) @deprecate A_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(A, B) - @deprecate Ac_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, Adjoint(A), B, β, C) - @deprecate Ac_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(Adjoint(A), x) - @deprecate Ac_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(Adjoint(A), B) - @deprecate At_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, Transpose(A), B, β, C) - @deprecate At_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(Transpose(A), x) - @deprecate At_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(Transpose(A), B) - @deprecate A_mul_Bt(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(A, Transpose(B)) - @deprecate A_mul_Bc(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(A, Adjoint(B)) - @deprecate At_mul_B(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(Transpose(A), B) - @deprecate Ac_mul_B(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(Adjoint(A),B) - @deprecate At_mul_Bt(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(Transpose(A), Transpose(B)) - @deprecate Ac_mul_Bc(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(Adjoint(A), Adjoint(B)) + @deprecate Ac_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, adjoint(A), B, β, C) + @deprecate Ac_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(adjoint(A), x) + @deprecate Ac_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(adjoint(A), B) + @deprecate At_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, transpose(A), B, β, C) + @deprecate At_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(transpose(A), x) + @deprecate At_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(transpose(A), B) + @deprecate A_mul_Bt(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(A, transpose(B)) + @deprecate A_mul_Bc(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(A, adjoint(B)) + @deprecate At_mul_B(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(transpose(A), B) + @deprecate Ac_mul_B(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(adjoint(A),B) + @deprecate At_mul_Bt(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(transpose(A), transpose(B)) + @deprecate Ac_mul_Bc(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(adjoint(A), adjoint(B)) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/sparse/sparsevector.jl, to deprecate @@ -3308,35 +2259,34 @@ for isunittri in (true, false), islowertri in (true, false) tritype = :(Base.LinAlg.$(Symbol(unitstr, halfstr, "Triangular"))) @eval Base.SparseArrays begin using Base.LinAlg: Adjoint, Transpose - @deprecate At_ldiv_B(A::$tritype{TA,<:AbstractMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(Transpose(A), b) - @deprecate At_ldiv_B(A::$tritype{TA,<:StridedMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(Transpose(A), b) - @deprecate At_ldiv_B(A::$tritype, b::SparseVector) (\)(Transpose(A), b) - @deprecate Ac_ldiv_B(A::$tritype{TA,<:AbstractMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(Adjoint(A), b) - @deprecate Ac_ldiv_B(A::$tritype{TA,<:StridedMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(Adjoint(A), b) - @deprecate Ac_ldiv_B(A::$tritype, b::SparseVector) (\)(Adjoint(A), b) + @deprecate At_ldiv_B(A::$tritype{TA,<:AbstractMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(transpose(A), b) + @deprecate At_ldiv_B(A::$tritype{TA,<:StridedMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(transpose(A), b) + @deprecate At_ldiv_B(A::$tritype, b::SparseVector) (\)(transpose(A), b) + @deprecate Ac_ldiv_B(A::$tritype{TA,<:AbstractMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(adjoint(A), b) + @deprecate Ac_ldiv_B(A::$tritype{TA,<:StridedMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(adjoint(A), b) + @deprecate Ac_ldiv_B(A::$tritype, b::SparseVector) (\)(adjoint(A), b) @deprecate A_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(A, b) - @deprecate At_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(Transpose(A), b) - @deprecate Ac_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(Adjoint(A), b) + @deprecate At_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(transpose(A), b) + @deprecate Ac_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(adjoint(A), b) end end @eval Base.SparseArrays begin using Base.LinAlg: Adjoint, Transpose - @deprecate Ac_mul_B(A::SparseMatrixCSC, x::AbstractSparseVector) (*)(Adjoint(A), x) - @deprecate At_mul_B(A::SparseMatrixCSC, x::AbstractSparseVector) (*)(Transpose(A), x) - @deprecate Ac_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, Adjoint(A), x, β, y) - @deprecate Ac_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, Adjoint(A), x) - @deprecate At_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, Transpose(A), x, β, y) - @deprecate At_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, Transpose(A), x) + @deprecate Ac_mul_B(A::SparseMatrixCSC, x::AbstractSparseVector) (*)(adjoint(A), x) + @deprecate At_mul_B(A::SparseMatrixCSC, x::AbstractSparseVector) (*)(transpose(A), x) + @deprecate Ac_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, adjoint(A), x, β, y) + @deprecate Ac_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, adjoint(A), x) + @deprecate At_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, transpose(A), x, β, y) + @deprecate At_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, transpose(A), x) @deprecate A_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, A, x, β, y) @deprecate A_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, A, x) - @deprecate At_mul_B!(α::Number, A::StridedMatrix, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, Transpose(A), x, β, y) - @deprecate At_mul_B!(y::StridedVector{Ty}, A::StridedMatrix, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, Transpose(A), x) - @deprecate At_mul_B(A::StridedMatrix{Ta}, x::AbstractSparseVector{Tx}) where {Ta,Tx} (*)(Transpose(A), x) + @deprecate At_mul_B!(α::Number, A::StridedMatrix, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, transpose(A), x, β, y) + @deprecate At_mul_B!(y::StridedVector{Ty}, A::StridedMatrix, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, transpose(A), x) + @deprecate At_mul_B(A::StridedMatrix{Ta}, x::AbstractSparseVector{Tx}) where {Ta,Tx} (*)(transpose(A), x) @deprecate A_mul_B!(α::Number, A::StridedMatrix, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, A, x, β, y) @deprecate A_mul_B!(y::StridedVector{Ty}, A::StridedMatrix, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, A, x) end - # methods involving RowVector from base/linalg/bidiag.jl, to deprecate @eval Base.LinAlg begin \(::Diagonal, ::RowVector) = _mat_ldiv_rowvec_error() @@ -3356,13 +2306,6 @@ end *(D::Diagonal, adjrowvec::Adjoint{<:Any,<:RowVector}) = (rowvec = adjrowvec.parent; D*rvadjoint(rowvec)) end -# methods involving RowVector from base/sparse/linalg.jl, to deprecate -@eval Base.SparseArrays begin - \(::SparseMatrixCSC, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector")) - \(::Adjoint{<:Any,<:SparseMatrixCSC}, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector")) - \(::Transpose{<:Any,<:SparseMatrixCSC}, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector")) -end - # methods involving RowVector from base/linalg/qr.jl, to deprecate @eval Base.LinAlg begin *(rowvec::RowVector, adjB::Adjoint{<:Any,<:AbstractQ}) = (B = adjB.parent; rvadjoint(B*rvadjoint(rowvec))) @@ -3421,11 +2364,6 @@ end \(A::Transpose{<:Any,<:Factorization{<:Real}}, B::RowVector) = transpose(A.parent) \ B end -# methods involving RowVector from base/sparse/higherorderfns.jl, to deprecate -@eval Base.SparseArrays.HigherOrderFns begin - BroadcastStyle(::Type{<:Base.RowVector{T,<:Vector}}) where T = Broadcast.MatrixStyle() -end - # methods involving RowVector from base/linalg/symmetric.jl, to deprecate @eval Base.LinAlg begin *(A::RowVector, transB::Transpose{<:Any,<:RealHermSymComplexSym}) = A * transB.parent @@ -3465,6 +2403,28 @@ end # issue #24822 @deprecate_binding Display AbstractDisplay +# PR #24874 +@deprecate_moved rand! "Random" true true +@deprecate_moved srand "Random" true true +@deprecate_moved AbstractRNG "Random" true true +@deprecate_moved randcycle "Random" true true +@deprecate_moved randcycle! "Random" true true +@deprecate_moved randperm "Random" true true +@deprecate_moved randperm! "Random" true true +@deprecate_moved shuffle "Random" true true +@deprecate_moved shuffle! "Random" true true +@deprecate_moved randsubseq "Random" true true +@deprecate_moved randsubseq! "Random" true true +@deprecate_moved randstring "Random" true true +@deprecate_moved MersenneTwister "Random" true true +@deprecate_moved RandomDevice "Random" true true +@deprecate_moved randn! "Random" true true +@deprecate_moved randexp "Random" true true +@deprecate_moved randexp! "Random" true true +@deprecate_moved bitrand "Random" true true +@deprecate_moved randjump "Random" true true +@deprecate_moved GLOBAL_RNG "Random" false true + # 24595 @deprecate falses(A::AbstractArray) falses(size(A)) @deprecate trues(A::AbstractArray) trues(size(A)) @@ -3712,27 +2672,39 @@ end @deprecate_moved sum_kbn "KahanSummation" @deprecate_moved cumsum_kbn "KahanSummation" +# PR #25249: SparseArrays to stdlib +## the Base.SparseArrays module itself and exported types are deprecated in base/sysimg.jl +## functions that were re-exported from Base +@deprecate_moved nonzeros "SparseArrays" true true +@deprecate_moved permute "SparseArrays" true true +@deprecate_moved blkdiag "SparseArrays" true true +@deprecate_moved dropzeros "SparseArrays" true true +@deprecate_moved dropzeros! "SparseArrays" true true +@deprecate_moved issparse "SparseArrays" true true +@deprecate_moved sparse "SparseArrays" true true +@deprecate_moved sparsevec "SparseArrays" true true +@deprecate_moved spdiagm "SparseArrays" true true +@deprecate_moved sprand "SparseArrays" true true +@deprecate_moved sprandn "SparseArrays" true true +@deprecate_moved spzeros "SparseArrays" true true +@deprecate_moved rowvals "SparseArrays" true true +@deprecate_moved nzrange "SparseArrays" true true +@deprecate_moved nnz "SparseArrays" true true +## functions that were exported from Base.SparseArrays but not from Base +@deprecate_moved droptol! "SparseArrays" false true +## deprecated functions that are moved to stdlib/SparseArrays/src/deprecated.jl +@deprecate_moved spones "SparseArrays" true true +@deprecate_moved speye "SparseArrays" true true + + # PR #25021 @deprecate_moved normalize_string "Unicode" true true @deprecate_moved graphemes "Unicode" true true @deprecate_moved is_assigned_char "Unicode" true true -@deprecate_moved textwidth "Unicode" true true -@deprecate_moved islower "Unicode" true true -@deprecate_moved isupper "Unicode" true true -@deprecate_moved isalpha "Unicode" true true -@deprecate_moved isdigit "Unicode" true true -@deprecate_moved isnumber "Unicode" true true -@deprecate_moved isalnum "Unicode" true true -@deprecate_moved iscntrl "Unicode" true true -@deprecate_moved ispunct "Unicode" true true -@deprecate_moved isspace "Unicode" true true -@deprecate_moved isprint "Unicode" true true -@deprecate_moved isgraph "Unicode" true true -@deprecate_moved lowercase "Unicode" true true -@deprecate_moved uppercase "Unicode" true true -@deprecate_moved titlecase "Unicode" true true -@deprecate_moved lcfirst "Unicode" true true -@deprecate_moved ucfirst "Unicode" true true + +@deprecate isalnum(c::Char) isalpha(c) || isnumeric(c) +@deprecate isgraph(c::Char) isprint(c) && !isspace(c) +@deprecate isnumber(c::Char) isnumeric(c) # PR #24647 @deprecate_binding Complex32 ComplexF16 @@ -3826,7 +2798,10 @@ end @deprecate substrides(s, parent, dim, I::Tuple) substrides(parent, strides(parent), I) -# END 0.7 deprecations +@deprecate *(A::LQ,B::QR) A*Matrix(B) +@deprecate *(A::QR,B::LQ) A*Matrix(B) +@deprecate *(A::Adjoint{<:Any,<:LQ}, B::LQ) A*Matrix(B) +@deprecate *(A::LQ, B::Adjoint{<:Any,<:LQ}) A*Matrix(B) @deprecate lexcmp(x::AbstractArray, y::AbstractArray) cmp(x, y) @deprecate lexcmp(x::Real, y::Real) cmp(isless, x, y) @@ -3835,6 +2810,16 @@ end @deprecate lexless isless +@deprecate_binding iteratorsize IteratorSize +@deprecate_binding iteratoreltype IteratorEltype + +# issue #25440 +@deprecate_binding TypeOrder OrderStyle +@deprecate_binding TypeArithmetic ArithmeticStyle +@deprecate_binding TypeRangeStep RangeStepStyle +@deprecate_binding HasOrder Ordered +@deprecate_binding ArithmeticOverflows ArithmeticWraps + @deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) findnext(re, str, idx) @deprecate search(s::AbstractString, r::Regex, idx::Integer) findnext(r, s, idx) @deprecate search(s::AbstractString, r::Regex) findfirst(r, s) @@ -3877,17 +2862,28 @@ end @deprecate rsearchindex(s::AbstractString, t::AbstractString) first(findlast(t, s)) @deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(findprev(t, s, i)) -@deprecate searchindex(s::AbstractString, c::Char) first(findfirst(equalto(c), s)) -@deprecate searchindex(s::AbstractString, c::Char, i::Integer) first(findnext(equalto(c), s, i)) -@deprecate rsearchindex(s::AbstractString, c::Char) first(findlast(equalto(c), s)) -@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) first(findprev(equalto(c), s, i)) +@deprecate searchindex(s::AbstractString, c::Char) findfirst(equalto(c), s) +@deprecate searchindex(s::AbstractString, c::Char, i::Integer) findnext(equalto(c), s, i) +@deprecate rsearchindex(s::AbstractString, c::Char) findlast(equalto(c), s) +@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) findprev(equalto(c), s, i) @deprecate ismatch(r::Regex, s::AbstractString) contains(s, r) @deprecate findin(a, b) find(occursin(b), a) +@deprecate findn(a::AbstractVector) (find(!iszero, a),) +@deprecate findn(x::AbstractMatrix) (I = find(!iszero, x); (getindex.(I, 1), getindex.(I, 2))) +@deprecate findn(a::AbstractArray{T, N}) where {T, N} (I = find(!iszero, x); ntuple(i -> getindex.(I, i), N)) + +# issue #9053 +if Sys.iswindows() +function Filesystem.tempname(uunique::UInt32) + error("`tempname(::UInt32)` is discontinued.") +end +end # END 0.7 deprecations + # BEGIN 1.0 deprecations # END 1.0 deprecations diff --git a/base/dict.jl b/base/dict.jl index 3e5534885318a..2f0df65d01a4d 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license function _truncate_at_width_or_chars(str, width, chars="", truncmark="…") - truncwidth = Unicode.textwidth(truncmark) + truncwidth = textwidth(truncmark) (width <= 0 || width < truncwidth) && return "" wid = truncidx = lastidx = 0 @@ -9,7 +9,7 @@ function _truncate_at_width_or_chars(str, width, chars="", truncmark="…") while !done(str, idx) lastidx = idx c, idx = next(str, idx) - wid += Unicode.textwidth(c) + wid += textwidth(c) wid >= width - truncwidth && truncidx == 0 && (truncidx = lastidx) (wid >= width || c in chars) && break end diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index efb32a122d350..401ad9932b7aa 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -641,7 +641,7 @@ finddoc(λ, def) = false # Predicates and helpers for `docm` expression selection: const FUNC_HEADS = [:function, :macro, :(=)] -const BINDING_HEADS = [:typealias, :const, :global, :(=)] # deprecation: remove `typealias` post-0.6 +const BINDING_HEADS = [:const, :global, :(=)] # For the special `:@mac` / `:(Base.@mac)` syntax for documenting a macro after definition. isquotedmacrocall(x) = isexpr(x, :copyast, 1) && diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index 6fc647cfae03a..c603487baf5d0 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -12,14 +12,14 @@ macro kw_str(text) Keyword(Symbol(text)) end https://docs.julialang.org/ -as well many great tutorials and learning resources: +as well as many great tutorials and learning resources: https://julialang.org/learning/ For help on a specific function or macro, type `?` followed by its name, e.g. `?cos`, or `?@time`, and press enter. """ -kw"help", kw"?", kw"julia" +kw"help", kw"?", kw"julia", kw"" """ using diff --git a/base/docs/utils.jl b/base/docs/utils.jl index 88d9db3c124d5..85db2c97ed81d 100644 --- a/base/docs/utils.jl +++ b/base/docs/utils.jl @@ -3,7 +3,6 @@ # Text / HTML objects import Base: print, show, ==, hash -using Base.Unicode export HTML, @html_str @@ -222,8 +221,8 @@ function matchinds(needle, haystack; acronym = false) for (i, char) in enumerate(haystack) isempty(chars) && break while chars[1] == ' ' popfirst!(chars) end # skip spaces - if Unicode.lowercase(char) == Unicode.lowercase(chars[1]) && - (!acronym || !Unicode.isalpha(lastc)) + if lowercase(char) == lowercase(chars[1]) && + (!acronym || !isalpha(lastc)) push!(is, i) popfirst!(chars) end diff --git a/base/error.jl b/base/error.jl index 1edf3bf5ee4ef..2065f71389d64 100644 --- a/base/error.jl +++ b/base/error.jl @@ -172,7 +172,7 @@ start(ebo::ExponentialBackOff) = (ebo.n, min(ebo.first_delay, ebo.max_delay)) function next(ebo::ExponentialBackOff, state) next_n = state[1]-1 curr_delay = state[2] - next_delay = min(ebo.max_delay, state[2] * ebo.factor * (1.0 - ebo.jitter + (rand() * 2.0 * ebo.jitter))) + next_delay = min(ebo.max_delay, state[2] * ebo.factor * (1.0 - ebo.jitter + (rand(Float64) * 2.0 * ebo.jitter))) (curr_delay, (next_n, next_delay)) end done(ebo::ExponentialBackOff, state) = state[1]<1 diff --git a/base/event.jl b/base/event.jl index 6f7cc45866a62..92ae58248ebbb 100644 --- a/base/event.jl +++ b/base/event.jl @@ -231,7 +231,7 @@ function ensure_rescheduled(othertask::Task) # also need to return it to the runnable state # before throwing an error i = findfirst(t->t===ct, Workqueue) - i == 0 || deleteat!(Workqueue, i) + i === nothing || deleteat!(Workqueue, i) ct.state = :runnable end nothing diff --git a/base/exports.jl b/base/exports.jl index bbc505393a62e..44c0bd03fe84b 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -8,7 +8,6 @@ export StackTraces, Sys, Libc, - Libdl, LinAlg, BLAS, LAPACK, @@ -434,7 +433,6 @@ export minimum, minmax, ndims, - nonzeros, ones, parent, parentindices, @@ -442,19 +440,12 @@ export partialsort!, partialsortperm, partialsortperm!, - permute, permute!, permutedims, permutedims!, prod!, prod, promote_shape, - randcycle, - randcycle!, - randperm, - randperm!, - randsubseq!, - randsubseq, range, reducedim, repmat, @@ -498,7 +489,6 @@ export findmin, findmin!, findmax!, - findn, findnext, findprev, findnz, @@ -513,7 +503,6 @@ export # linear algebra bkfact!, bkfact, - blkdiag, chol, cholfact!, cholfact, @@ -594,10 +583,6 @@ export ⋅, ×, -# sparse - dropzeros, - dropzeros!, - # bitarrays falses, flipbits!, @@ -642,6 +627,7 @@ export intersect, isempty, issubset, + issetequal, keys, keytype, length, @@ -703,7 +689,19 @@ export hex2bytes, hex2bytes!, info, + isalpha, isascii, + iscntrl, + isdigit, + islower, + isnumeric, + isprint, + ispunct, + isspace, + isupper, + isxdigit, + lcfirst, + lowercase, isvalid, join, logging, @@ -718,7 +716,6 @@ export print_shortest, print_with_color, println, - randstring, repeat, replace, replace!, @@ -735,9 +732,13 @@ export string, strip, summary, + textwidth, thisind, + titlecase, transcode, + ucfirst, unescape_string, + uppercase, warn, # logging frontend @@ -746,20 +747,6 @@ export @warn, @error, -# random numbers - AbstractRNG, - MersenneTwister, - RandomDevice, - rand!, - rand, - randn!, - randn, - randexp!, - randexp, - srand, - bitrand, - randjump, - # bigfloat & precision precision, rounding, @@ -1108,6 +1095,10 @@ export unsafe_store!, unsafe_write, +# implemented in Random module + rand, + randn, + # Macros # parser internal @__FILE__, @@ -1183,22 +1174,4 @@ export @goto, @view, @views, - @static, - -# SparseArrays module re-exports - SparseArrays, - AbstractSparseArray, - AbstractSparseMatrix, - AbstractSparseVector, - SparseMatrixCSC, - SparseVector, - issparse, - sparse, - sparsevec, - spdiagm, - sprand, - sprandn, - spzeros, - rowvals, - nzrange, - nnz + @static diff --git a/base/file.jl b/base/file.jl index 846da9b8eddae..104e8cc411d2d 100644 --- a/base/file.jl +++ b/base/file.jl @@ -265,13 +265,13 @@ function tempdir() resize!(temppath,lentemppath) return transcode(String, temppath) end -tempname(uunique::UInt32=UInt32(0)) = tempname(tempdir(), uunique) + const temp_prefix = cwstring("jl_") -function tempname(temppath::AbstractString,uunique::UInt32) +function _win_tempname(temppath::AbstractString, uunique::UInt32) tempp = cwstring(temppath) tname = Vector{UInt16}(uninitialized, 32767) uunique = ccall(:GetTempFileNameW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32,Ptr{UInt16}), tempp,temp_prefix,uunique,tname) - lentname = findfirst(iszero,tname)-1 + lentname = coalesce(findfirst(iszero,tname), 0)-1 if uunique == 0 || lentname <= 0 error("GetTempFileName failed: $(Libc.FormatMessage())") end @@ -280,17 +280,17 @@ function tempname(temppath::AbstractString,uunique::UInt32) end function mktemp(parent=tempdir()) - filename = tempname(parent, UInt32(0)) + filename = _win_tempname(parent, UInt32(0)) return (filename, Base.open(filename, "r+")) end function mktempdir(parent=tempdir()) - seed::UInt32 = rand(UInt32) + seed::UInt32 = Base.Crand(UInt32) while true if (seed & typemax(UInt16)) == 0 seed += 1 end - filename = tempname(parent, seed) + filename = _win_tempname(parent, seed) ret = ccall(:_wmkdir, Int32, (Ptr{UInt16},), cwstring(filename)) if ret == 0 return filename @@ -300,6 +300,21 @@ function mktempdir(parent=tempdir()) end end +function tempname() + parent = tempdir() + seed::UInt32 = rand(UInt32) + while true + if (seed & typemax(UInt16)) == 0 + seed += 1 + end + filename = _win_tempname(parent, seed) + if !ispath(filename) + return filename + end + seed += 1 + end +end + else # !windows # Obtain a temporary filename. function tempname() @@ -343,7 +358,14 @@ tempdir() """ tempname() -Generate a unique temporary file path. +Generate a temporary file path. This function only returns a path; no file is +created. The path is likely to be unique, but this cannot be guaranteed. + +!!! warning + + This can lead to race conditions if another process obtains the same + file name and creates the file before you are able to. + Using [`mktemp()`](@ref) is recommended instead. """ tempname() @@ -514,8 +536,8 @@ function rename(src::AbstractString, dst::AbstractString) end function sendfile(src::AbstractString, dst::AbstractString) - local src_open = false - local dst_open = false + src_open = false + dst_open = false local src_file, dst_file try src_file = open(src, JL_O_RDONLY) diff --git a/base/filesystem.jl b/base/filesystem.jl index 001a8fcb210bb..9f29ee127783d 100644 --- a/base/filesystem.jl +++ b/base/filesystem.jl @@ -43,6 +43,7 @@ import Base: nb_available, position, read, read!, readavailable, seek, seekend, show, skip, stat, unsafe_read, unsafe_write, transcode, uv_error, uvhandle, uvtype, write +using Base: coalesce if Sys.iswindows() import Base: cwstring diff --git a/base/generator.jl b/base/generator.jl index 28f9134e95547..b4974cba16c98 100644 --- a/base/generator.jl +++ b/base/generator.jl @@ -57,7 +57,7 @@ struct HasShape <: IteratorSize end struct IsInfinite <: IteratorSize end """ - iteratorsize(itertype::Type) -> IteratorSize + IteratorSize(itertype::Type) -> IteratorSize Given the type of an iterator, return one of the following values: @@ -74,22 +74,22 @@ This trait is generally used to select between algorithms that pre-allocate spac result, and algorithms that resize their result incrementally. ```jldoctest -julia> Base.iteratorsize(1:5) +julia> Base.IteratorSize(1:5) Base.HasShape() -julia> Base.iteratorsize((2,3)) +julia> Base.IteratorSize((2,3)) Base.HasLength() ``` """ -iteratorsize(x) = iteratorsize(typeof(x)) -iteratorsize(::Type) = HasLength() # HasLength is the default +IteratorSize(x) = IteratorSize(typeof(x)) +IteratorSize(::Type) = HasLength() # HasLength is the default abstract type IteratorEltype end struct EltypeUnknown <: IteratorEltype end struct HasEltype <: IteratorEltype end """ - iteratoreltype(itertype::Type) -> IteratorEltype + IteratorEltype(itertype::Type) -> IteratorEltype Given the type of an iterator, return one of the following values: @@ -103,20 +103,20 @@ type of result, and algorithms that pick a result type based on the types of yie values. ```jldoctest -julia> Base.iteratoreltype(1:5) +julia> Base.IteratorEltype(1:5) Base.HasEltype() ``` """ -iteratoreltype(x) = iteratoreltype(typeof(x)) -iteratoreltype(::Type) = HasEltype() # HasEltype is the default +IteratorEltype(x) = IteratorEltype(typeof(x)) +IteratorEltype(::Type) = HasEltype() # HasEltype is the default -iteratorsize(::Type{<:AbstractArray}) = HasShape() -iteratorsize(::Type{Generator{I,F}}) where {I,F} = iteratorsize(I) +IteratorSize(::Type{<:AbstractArray}) = HasShape() +IteratorSize(::Type{Generator{I,F}}) where {I,F} = IteratorSize(I) length(g::Generator) = length(g.iter) size(g::Generator) = size(g.iter) axes(g::Generator) = axes(g.iter) ndims(g::Generator) = ndims(g.iter) -iteratoreltype(::Type{Generator{I,T}}) where {I,T} = EltypeUnknown() +IteratorEltype(::Type{Generator{I,T}}) where {I,T} = EltypeUnknown() -haslength(iter) = iteratorsize(iter) isa Union{HasShape, HasLength} +haslength(iter) = IteratorSize(iter) isa Union{HasShape, HasLength} diff --git a/base/hashing.jl b/base/hashing.jl index caa1be81036aa..eb37bf0ba1157 100644 --- a/base/hashing.jl +++ b/base/hashing.jl @@ -25,7 +25,7 @@ hash(@nospecialize(x), h::UInt) = hash_uint(3h - object_id(x)) ## core data hashing functions ## function hash_64_64(n::UInt64) - local a::UInt64 = n + a::UInt64 = n a = ~a + a << 21 a = a ⊻ a >> 24 a = a + a << 3 + a << 8 @@ -37,7 +37,7 @@ function hash_64_64(n::UInt64) end function hash_64_32(n::UInt64) - local a::UInt64 = n + a::UInt64 = n a = ~a + a << 18 a = a ⊻ a >> 31 a = a * 21 @@ -48,7 +48,7 @@ function hash_64_32(n::UInt64) end function hash_32_32(n::UInt32) - local a::UInt32 = n + a::UInt32 = n a = a + 0x7ed55d16 + a << 12 a = a ⊻ 0xc761c23c ⊻ a >> 19 a = a + 0x165667b1 + a << 5 diff --git a/base/hashing2.jl b/base/hashing2.jl index 83ef9ea09683f..55d67ca9caef9 100644 --- a/base/hashing2.jl +++ b/base/hashing2.jl @@ -178,4 +178,4 @@ function hash(s::Union{String,SubString{String}}, h::UInt) # note: use pointer(s) here (see #6058). ccall(memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), pointer(s), sizeof(s), h % UInt32) + h end -hash(s::AbstractString, h::UInt) = hash(String(s), h) \ No newline at end of file +hash(s::AbstractString, h::UInt) = hash(String(s), h) diff --git a/base/inference.jl b/base/inference.jl index ab3b0bcff5424..a1f868ceae42a 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -171,11 +171,20 @@ struct Const Const(@nospecialize(v), a::Bool) = new(v, a) end -# The type of a value might be Bool, -# but where the value of the boolean can be used in back-propagation to -# limit the type of some other variable -# The Conditional type tracks the set of branches on variable type info -# that was used to create the boolean condition +# The type of this value might be Bool. +# However, to enable a limited amount of back-propagagation, +# we also keep some information about how this Bool value was created. +# In particular, if you branch on this value, then may assume that in +# the true branch, the type of `var` will be limited by `vtype` and in +# the false branch, it will be limited by `elsetype`. Example: +# ``` +# cond = isa(x::Union{Int, Float}, Int)::Conditional(x, Int, Float) +# if cond +# # May assume x is `Int` now +# else +# # May assume x is `Float` now +# end +# ``` mutable struct Conditional var::Union{Slot,SSAValue} vtype @@ -371,10 +380,14 @@ function _validate(linfo::MethodInstance, src::CodeInfo, kind::String) end function get_staged(li::MethodInstance) - return ccall(:jl_code_for_staged, Any, (Any,), li)::CodeInfo + try + # user code might throw errors – ignore them + return ccall(:jl_code_for_staged, Any, (Any,), li)::CodeInfo + catch + return nothing + end end - mutable struct OptimizationState linfo::MethodInstance vararg_type_container #::Type @@ -472,12 +485,7 @@ end function retrieve_code_info(linfo::MethodInstance) m = linfo.def::Method if isdefined(m, :generator) - try - # user code might throw errors – ignore them - c = get_staged(linfo) - catch - return nothing - end + return get_staged(linfo) else # TODO: post-inference see if we can swap back to the original arrays? if isa(m.source, Array{UInt8,1}) @@ -489,6 +497,35 @@ function retrieve_code_info(linfo::MethodInstance) return c end +# TODO: Use these functions instead of directly manipulating +# the "actual" method for appropriate places in inference (see #24676) +function method_for_inference_heuristics(cinfo, default) + if isa(cinfo, CodeInfo) + # appropriate format for `sig` is svec(ftype, argtypes, world) + sig = cinfo.signature_for_inference_heuristics + if isa(sig, SimpleVector) && length(sig) == 3 + methods = _methods(sig[1], sig[2], -1, sig[3]) + if length(methods) == 1 + _, _, m = methods[] + if isa(m, Method) + return m + end + end + end + end + return default +end + +function method_for_inference_heuristics(method::Method, @nospecialize(sig), sparams, world) + if isdefined(method, :generator) && method.generator.expand_early + method_instance = code_for_method(method, sig, sparams, world, false) + if isa(method_instance, MethodInstance) + return method_for_inference_heuristics(get_staged(method_instance), method) + end + end + return method +end + @inline slot_id(s) = isa(s, SlotNumber) ? (s::SlotNumber).id : (s::TypedSlot).id # using a function to ensure we can infer this # avoid cycle due to over-specializing `any` when used by inference @@ -1681,7 +1718,7 @@ function invoke_tfunc(@nospecialize(f), @nospecialize(types), @nospecialize(argt return Bottom end ft = type_typeof(f) - types = Tuple{ft, types.parameters...} + types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types) argtype = Tuple{ft, argtype.parameters...} entry = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), types, sv.params.world) if entry === nothing @@ -1794,7 +1831,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1}, tf = t_ifunc[iidx] else fidx = findfirst(x->x===f, t_ffunc_key) - if fidx == 0 + if fidx === nothing # unknown/unhandled builtin function return Any end @@ -3396,6 +3433,7 @@ function typeinf_code(linfo::MethodInstance, optimize::Bool, cached::Bool, method = linfo.def::Method tree = ccall(:jl_new_code_info_uninit, Ref{CodeInfo}, ()) tree.code = Any[ Expr(:return, quoted(linfo.inferred_const)) ] + tree.signature_for_inference_heuristics = nothing tree.slotnames = Any[ compiler_temp_sym for i = 1:method.nargs ] tree.slotflags = UInt8[ 0 for i = 1:method.nargs ] tree.slottypes = nothing @@ -4649,8 +4687,8 @@ function inlineable(@nospecialize(f), @nospecialize(ft), e::Expr, atypes::Vector invoke_tt.parameters[1] <: Tuple) return NF end - invoke_tt_params = invoke_tt.parameters[1].parameters - invoke_types = Tuple{ft, invoke_tt_params...} + invoke_tt = invoke_tt.parameters[1] + invoke_types = rewrap_unionall(Tuple{ft, unwrap_unionall(invoke_tt).parameters...}, invoke_tt) invoke_entry = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), invoke_types, sv.params.world) invoke_entry === nothing && return NF @@ -5118,7 +5156,7 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, mod::Module, params: return plus_saturate(argcost, isknowntype(ex.typ) ? 4 : params.inline_nonleaf_penalty) end fidx = findfirst(x->x===f, t_ffunc_key) - if fidx == 0 + if fidx === nothing # unknown/unhandled builtin or anonymous function # Use the generic cost of a direct function call return plus_saturate(argcost, 20) diff --git a/base/interactiveutil.jl b/base/interactiveutil.jl index 7627362cdca0f..b2e10bd3478e8 100644 --- a/base/interactiveutil.jl +++ b/base/interactiveutil.jl @@ -51,7 +51,7 @@ function edit(path::AbstractString, line::Integer=0) cmd = line != 0 ? `$command $path -l $line` : `$command $path` elseif startswith(name, "subl") || startswith(name, "atom") cmd = line != 0 ? `$command $path:$line` : `$command $path` - elseif name == "code" || (Sys.iswindows() && Unicode.uppercase(name) == "CODE.EXE") + elseif name == "code" || (Sys.iswindows() && uppercase(name) == "CODE.EXE") cmd = line != 0 ? `$command -g $path:$line` : `$command -g $path` elseif startswith(name, "notepad++") cmd = line != 0 ? `$command $path -n$line` : `$command $path` @@ -639,12 +639,14 @@ end downloadcmd = nothing if Sys.iswindows() + downloadcmd = :powershell function download(url::AbstractString, filename::AbstractString) - res = ccall((:URLDownloadToFileW,:urlmon),stdcall,Cuint, - (Ptr{Cvoid},Cwstring,Cwstring,Cuint,Ptr{Cvoid}),C_NULL,url,filename,0,C_NULL) - if res != 0 - error("automatic download failed (error: $res): $url") - end + ps = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" + tls12 = "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12" + client = "New-Object System.Net.Webclient" + # in the following we escape ' with '' (see https://ss64.com/ps/syntax-esc.html) + downloadfile = "($client).DownloadFile('$(replace(url, "'" => "''"))', '$(replace(filename, "'" => "''"))')" + run(`$ps -NoProfile -Command "$tls12; $downloadfile"`) filename end else @@ -740,7 +742,7 @@ function varinfo(m::Module=Main, pattern::Regex=r"") rows = Any[ let value = getfield(m, v) Any[string(v), - (value ∈ (Base, Main, Core) ? "" : format_bytes(summarysize(value))), + (any(x -> x === value, (Base, Main, Core)) ? "" : format_bytes(summarysize(value))), summary(value)] end for v in sort!(names(m)) if isdefined(m, v) && contains(string(v), pattern) ] diff --git a/base/intfuncs.jl b/base/intfuncs.jl index e60ab100fd2ce..722e701f78cac 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -284,8 +284,7 @@ function powermod(x::Integer, p::Integer, m::T) where T<:Integer b = oftype(m,mod(x,m)) # this also checks for divide by zero t = prevpow2(p) - local r::T - r = 1 + r::T = 1 while true if p >= t r = mod(widemul(r,b),m) @@ -900,7 +899,7 @@ function binomial(n::T, k::T) where T<:Integer rr = 2 while rr <= k xt = div(widemul(x, nn), rr) - x = xt + x = xt % T x == xt || throw(OverflowError("binomial($n0, $k0) overflows")) rr += 1 nn += 1 diff --git a/base/io.jl b/base/io.jl index b719a36edded7..7d2ceaf89b01a 100644 --- a/base/io.jl +++ b/base/io.jl @@ -191,7 +191,7 @@ to provide more efficient implementations: `unsafe_write(s::T, p::Ptr{UInt8}, n::UInt)` """ function unsafe_write(s::IO, p::Ptr{UInt8}, n::UInt) - local written::Int = 0 + written::Int = 0 for i = 1:n written += write(s, unsafe_load(p, i)) end @@ -272,7 +272,7 @@ reseteof(io::AbstractPipe) = reseteof(pipe_reader(io)) # Exception-safe wrappers (io = open(); try f(io) finally close(io)) -write(filename::AbstractString, args...) = open(io->write(io, args...), filename, "w") +write(filename::AbstractString, a1, args...) = open(io->write(io, a1, args...), filename, "w") """ read(filename::AbstractString, args...) @@ -484,8 +484,8 @@ isreadonly(s) = isreadable(s) && !iswritable(s) ## binary I/O ## write(io::IO, x) = throw(MethodError(write, (io, x))) -function write(io::IO, xs...) - local written::Int = 0 +function write(io::IO, x1, xs...) + written::Int = write(io, x1) for x in xs written += write(io, x) end @@ -845,7 +845,7 @@ next(itr::EachLine, ::Nothing) = (readline(itr.stream, chomp=itr.chomp), nothing eltype(::Type{EachLine}) = String -iteratorsize(::Type{EachLine}) = SizeUnknown() +IteratorSize(::Type{EachLine}) = SizeUnknown() # IOStream Marking # Note that these functions expect that io.mark exists for @@ -923,8 +923,6 @@ characters from that character until the start of the next line are ignored. julia> buf = IOBuffer(" text") IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=1, mark=-1) -julia> using Unicode - julia> skipchars(buf, isspace) IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=5, mark=-1) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index e91e8c30cd213..fea9cabea2a7f 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -429,8 +429,8 @@ read(io::GenericIOBuffer, nb::Integer) = read!(io,StringVector(min(nb, nb_availa function findfirst(delim::EqualTo{UInt8}, buf::IOBuffer) p = pointer(buf.data, buf.ptr) q = @gc_preserve buf ccall(:memchr,Ptr{UInt8},(Ptr{UInt8},Int32,Csize_t),p,delim.x,nb_available(buf)) - nb::Int = (q == C_NULL ? 0 : q-p+1) - return nb + q == C_NULL && return nothing + return Int(q-p+1) end function findfirst(delim::EqualTo{UInt8}, buf::GenericIOBuffer) @@ -441,7 +441,7 @@ function findfirst(delim::EqualTo{UInt8}, buf::GenericIOBuffer) return i - buf.ptr + 1 end end - return 0 + return nothing end function readuntil(io::GenericIOBuffer, delim::UInt8) diff --git a/base/iterators.jl b/base/iterators.jl index 37f29a49d5257..edb714fac1756 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -16,7 +16,7 @@ using .Base: import .Base: start, done, next, first, last, isempty, length, size, axes, ndims, - eltype, iteratorsize, iteratoreltype, + eltype, IteratorSize, IteratorEltype, haskey, keys, values, pairs, getindex, setindex!, get @@ -75,8 +75,8 @@ end eltype(r::Reverse) = eltype(r.itr) length(r::Reverse) = length(r.itr) size(r::Reverse) = size(r.itr) -iteratorsize(r::Reverse) = iteratorsize(r.itr) -iteratoreltype(r::Reverse) = iteratoreltype(r.itr) +IteratorSize(r::Reverse) = IteratorSize(r.itr) +IteratorEltype(r::Reverse) = IteratorEltype(r.itr) last(r::Reverse) = first(r.itr) # the first shall be last first(r::Reverse) = last(r.itr) # and the last shall be first @@ -138,8 +138,8 @@ end eltype(::Type{Enumerate{I}}) where {I} = Tuple{Int, eltype(I)} -iteratorsize(::Type{Enumerate{I}}) where {I} = iteratorsize(I) -iteratoreltype(::Type{Enumerate{I}}) where {I} = iteratoreltype(I) +IteratorSize(::Type{Enumerate{I}}) where {I} = IteratorSize(I) +IteratorEltype(::Type{Enumerate{I}}) where {I} = IteratorEltype(I) @inline function start(r::Reverse{<:Enumerate}) ri = reverse(r.itr.itr) @@ -233,8 +233,8 @@ end eltype(::Type{IndexValue{K, V}}) where {K, V} = Pair{K, V} -iteratorsize(::Type{IndexValue{<:Any, <:Any, I}}) where {I} = iteratorsize(I) -iteratoreltype(::Type{IndexValue{<:Any, <:Any, I}}) where {I} = iteratoreltype(I) +IteratorSize(::Type{IndexValue{<:Any, <:Any, I}}) where {I} = IteratorSize(I) +IteratorEltype(::Type{IndexValue{<:Any, <:Any, I}}) where {I} = IteratorEltype(I) reverse(v::IndexValue) = IndexValue(v.data, reverse(v.itr)) @@ -272,15 +272,15 @@ eltype(::Type{Zip1{I}}) where {I} = Tuple{eltype(I)} end @inline done(z::Zip1, st) = done(z.a,st) -iteratorsize(::Type{Zip1{I}}) where {I} = iteratorsize(I) -iteratoreltype(::Type{Zip1{I}}) where {I} = iteratoreltype(I) +IteratorSize(::Type{Zip1{I}}) where {I} = IteratorSize(I) +IteratorEltype(::Type{Zip1{I}}) where {I} = IteratorEltype(I) struct Zip2{I1, I2} <: AbstractZipIterator a::I1 b::I2 end zip(a, b) = Zip2(a, b) -length(z::Zip2) = _min_length(z.a, z.b, iteratorsize(z.a), iteratorsize(z.b)) +length(z::Zip2) = _min_length(z.a, z.b, IteratorSize(z.a), IteratorSize(z.b)) size(z::Zip2) = promote_shape(size(z.a), size(z.b)) axes(z::Zip2) = promote_shape(axes(z.a), axes(z.b)) eltype(::Type{Zip2{I1,I2}}) where {I1,I2} = Tuple{eltype(I1), eltype(I2)} @@ -292,8 +292,8 @@ eltype(::Type{Zip2{I1,I2}}) where {I1,I2} = Tuple{eltype(I1), eltype(I2)} end @inline done(z::Zip2, st) = done(z.a,st[1]) | done(z.b,st[2]) -iteratorsize(::Type{Zip2{I1,I2}}) where {I1,I2} = zip_iteratorsize(iteratorsize(I1),iteratorsize(I2)) -iteratoreltype(::Type{Zip2{I1,I2}}) where {I1,I2} = and_iteratoreltype(iteratoreltype(I1),iteratoreltype(I2)) +IteratorSize(::Type{Zip2{I1,I2}}) where {I1,I2} = zip_iteratorsize(IteratorSize(I1),IteratorSize(I2)) +IteratorEltype(::Type{Zip2{I1,I2}}) where {I1,I2} = and_iteratoreltype(IteratorEltype(I1),IteratorEltype(I2)) struct Zip{I, Z<:AbstractZipIterator} <: AbstractZipIterator a::I @@ -330,7 +330,7 @@ julia> first(c) ``` """ zip(a, b, c...) = Zip(a, zip(b, c...)) -length(z::Zip) = _min_length(z.a, z.z, iteratorsize(z.a), iteratorsize(z.z)) +length(z::Zip) = _min_length(z.a, z.z, IteratorSize(z.a), IteratorSize(z.z)) size(z::Zip) = promote_shape(size(z.a), size(z.z)) axes(z::Zip) = promote_shape(axes(z.a), axes(z.z)) eltype(::Type{Zip{I,Z}}) where {I,Z} = tuple_type_cons(eltype(I), eltype(Z)) @@ -342,8 +342,8 @@ eltype(::Type{Zip{I,Z}}) where {I,Z} = tuple_type_cons(eltype(I), eltype(Z)) end @inline done(z::Zip, st) = done(z.a,st[1]) | done(z.z,st[2]) -iteratorsize(::Type{Zip{I1,I2}}) where {I1,I2} = zip_iteratorsize(iteratorsize(I1),iteratorsize(I2)) -iteratoreltype(::Type{Zip{I1,I2}}) where {I1,I2} = and_iteratoreltype(iteratoreltype(I1),iteratoreltype(I2)) +IteratorSize(::Type{Zip{I1,I2}}) where {I1,I2} = zip_iteratorsize(IteratorSize(I1),IteratorSize(I2)) +IteratorEltype(::Type{Zip{I1,I2}}) where {I1,I2} = and_iteratoreltype(IteratorEltype(I1),IteratorEltype(I2)) reverse(z::Zip1) = Zip1(reverse(z.a)) reverse(z::Zip2) = Zip2(reverse(z.a), reverse(z.b)) @@ -413,8 +413,8 @@ end done(f::Filter, s) = s[1] eltype(::Type{Filter{F,I}}) where {F,I} = eltype(I) -iteratoreltype(::Type{Filter{F,I}}) where {F,I} = iteratoreltype(I) -iteratorsize(::Type{<:Filter}) = SizeUnknown() +IteratorEltype(::Type{Filter{F,I}}) where {F,I} = IteratorEltype(I) +IteratorSize(::Type{<:Filter}) = SizeUnknown() reverse(f::Filter) = Filter(f.flt, reverse(f.itr)) @@ -446,10 +446,10 @@ start(i::Rest) = i.st done(i::Rest, st) = done(i.itr, st) eltype(::Type{Rest{I}}) where {I} = eltype(I) -iteratoreltype(::Type{Rest{I,S}}) where {I,S} = iteratoreltype(I) +IteratorEltype(::Type{Rest{I,S}}) where {I,S} = IteratorEltype(I) rest_iteratorsize(a) = SizeUnknown() rest_iteratorsize(::IsInfinite) = IsInfinite() -iteratorsize(::Type{Rest{I,S}}) where {I,S} = rest_iteratorsize(iteratorsize(I)) +IteratorSize(::Type{Rest{I,S}}) where {I,S} = rest_iteratorsize(IteratorSize(I)) # Count -- infinite counting @@ -484,7 +484,7 @@ start(it::Count) = it.start next(it::Count, state) = (state, state + it.step) done(it::Count, state) = false -iteratorsize(::Type{<:Count}) = IsInfinite() +IteratorSize(::Type{<:Count}) = IsInfinite() # Take -- iterate through the first n elements @@ -523,11 +523,11 @@ take(xs, n::Integer) = Take(xs, Int(n)) take(xs::Take, n::Integer) = Take(xs.xs, min(Int(n), xs.n)) eltype(::Type{Take{I}}) where {I} = eltype(I) -iteratoreltype(::Type{Take{I}}) where {I} = iteratoreltype(I) +IteratorEltype(::Type{Take{I}}) where {I} = IteratorEltype(I) take_iteratorsize(a) = HasLength() take_iteratorsize(::SizeUnknown) = SizeUnknown() -iteratorsize(::Type{Take{I}}) where {I} = take_iteratorsize(iteratorsize(I)) -length(t::Take) = _min_length(t.xs, 1:t.n, iteratorsize(t.xs), HasLength()) +IteratorSize(::Type{Take{I}}) where {I} = take_iteratorsize(IteratorSize(I)) +length(t::Take) = _min_length(t.xs, 1:t.n, IteratorSize(t.xs), HasLength()) start(it::Take) = (it.n, start(it.xs)) @@ -579,12 +579,12 @@ drop(xs::Take, n::Integer) = Take(drop(xs.xs, Int(n)), max(0, xs.n - Int(n))) drop(xs::Drop, n::Integer) = Drop(xs.xs, Int(n) + xs.n) eltype(::Type{Drop{I}}) where {I} = eltype(I) -iteratoreltype(::Type{Drop{I}}) where {I} = iteratoreltype(I) +IteratorEltype(::Type{Drop{I}}) where {I} = IteratorEltype(I) drop_iteratorsize(::SizeUnknown) = SizeUnknown() drop_iteratorsize(::Union{HasShape, HasLength}) = HasLength() drop_iteratorsize(::IsInfinite) = IsInfinite() -iteratorsize(::Type{Drop{I}}) where {I} = drop_iteratorsize(iteratorsize(I)) -length(d::Drop) = _diff_length(d.xs, 1:d.n, iteratorsize(d.xs), HasLength()) +IteratorSize(::Type{Drop{I}}) where {I} = drop_iteratorsize(IteratorSize(I)) +length(d::Drop) = _diff_length(d.xs, 1:d.n, IteratorSize(d.xs), HasLength()) function start(it::Drop) xs_state = start(it.xs) @@ -624,8 +624,8 @@ hellohelloh cycle(xs) = Cycle(xs) eltype(::Type{Cycle{I}}) where {I} = eltype(I) -iteratoreltype(::Type{Cycle{I}}) where {I} = iteratoreltype(I) -iteratorsize(::Type{Cycle{I}}) where {I} = IsInfinite() +IteratorEltype(::Type{Cycle{I}}) where {I} = IteratorEltype(I) +IteratorSize(::Type{Cycle{I}}) where {I} = IsInfinite() function start(it::Cycle) s = start(it.xs) @@ -678,8 +678,8 @@ start(it::Repeated) = nothing next(it::Repeated, state) = (it.x, nothing) done(it::Repeated, state) = false -iteratorsize(::Type{<:Repeated}) = IsInfinite() -iteratoreltype(::Type{<:Repeated}) = HasEltype() +IteratorSize(::Type{<:Repeated}) = IsInfinite() +IteratorEltype(::Type{<:Repeated}) = HasEltype() reverse(it::Union{Repeated,Take{<:Repeated}}) = it @@ -705,9 +705,9 @@ julia> collect(Iterators.product(1:2,3:5)) """ product(iters...) = ProductIterator(iters) -iteratorsize(::Type{ProductIterator{Tuple{}}}) = HasShape() -iteratorsize(::Type{ProductIterator{T}}) where {T<:Tuple} = - prod_iteratorsize( iteratorsize(tuple_type_head(T)), iteratorsize(ProductIterator{tuple_type_tail(T)}) ) +IteratorSize(::Type{ProductIterator{Tuple{}}}) = HasShape() +IteratorSize(::Type{ProductIterator{T}}) where {T<:Tuple} = + prod_iteratorsize( IteratorSize(tuple_type_head(T)), IteratorSize(ProductIterator{tuple_type_tail(T)}) ) prod_iteratorsize(::Union{HasLength,HasShape}, ::Union{HasLength,HasShape}) = HasShape() # products can have an infinite iterator @@ -718,7 +718,7 @@ prod_iteratorsize(a, b) = SizeUnknown() size(P::ProductIterator) = _prod_size(P.iterators) _prod_size(::Tuple{}) = () -_prod_size(t::Tuple) = (_prod_size1(t[1], iteratorsize(t[1]))..., _prod_size(tail(t))...) +_prod_size(t::Tuple) = (_prod_size1(t[1], IteratorSize(t[1]))..., _prod_size(tail(t))...) _prod_size1(a, ::HasShape) = size(a) _prod_size1(a, ::HasLength) = (length(a),) _prod_size1(a, A) = @@ -726,7 +726,7 @@ _prod_size1(a, A) = axes(P::ProductIterator) = _prod_indices(P.iterators) _prod_indices(::Tuple{}) = () -_prod_indices(t::Tuple) = (_prod_indices1(t[1], iteratorsize(t[1]))..., _prod_indices(tail(t))...) +_prod_indices(t::Tuple) = (_prod_indices1(t[1], IteratorSize(t[1]))..., _prod_indices(tail(t))...) _prod_indices1(a, ::HasShape) = axes(a) _prod_indices1(a, ::HasLength) = (OneTo(length(a)),) _prod_indices1(a, A) = @@ -736,12 +736,12 @@ ndims(p::ProductIterator) = length(axes(p)) length(P::ProductIterator) = prod(size(P)) _length(p::ProductIterator) = prod(map(unsafe_length, axes(p))) -iteratoreltype(::Type{ProductIterator{Tuple{}}}) = HasEltype() -iteratoreltype(::Type{ProductIterator{Tuple{I}}}) where {I} = iteratoreltype(I) -function iteratoreltype(::Type{ProductIterator{T}}) where {T<:Tuple} +IteratorEltype(::Type{ProductIterator{Tuple{}}}) = HasEltype() +IteratorEltype(::Type{ProductIterator{Tuple{I}}}) where {I} = IteratorEltype(I) +function IteratorEltype(::Type{ProductIterator{T}}) where {T<:Tuple} I = tuple_type_head(T) P = ProductIterator{tuple_type_tail(T)} - iteratoreltype(I) == EltypeUnknown() ? EltypeUnknown() : iteratoreltype(P) + IteratorEltype(I) == EltypeUnknown() ? EltypeUnknown() : IteratorEltype(P) end eltype(P::ProductIterator) = _prod_eltype(P.iterators) @@ -848,8 +848,8 @@ julia> collect(Iterators.flatten((1:2, 8:9))) flatten(itr) = Flatten(itr) eltype(::Type{Flatten{I}}) where {I} = eltype(eltype(I)) -iteratoreltype(::Type{Flatten{I}}) where {I} = _flatteneltype(I, iteratoreltype(I)) -_flatteneltype(I, ::HasEltype) = iteratoreltype(eltype(I)) +IteratorEltype(::Type{Flatten{I}}) where {I} = _flatteneltype(I, IteratorEltype(I)) +_flatteneltype(I, ::HasEltype) = IteratorEltype(eltype(I)) _flatteneltype(I, et) = EltypeUnknown() flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:NTuple{N,Any}}) where {N} = HasLength() @@ -857,7 +857,7 @@ flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Tuple}) = SizeUnknow flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Number}) = HasLength() flatten_iteratorsize(a, b) = SizeUnknown() -iteratorsize(::Type{Flatten{I}}) where {I} = flatten_iteratorsize(iteratorsize(I), eltype(I)) +IteratorSize(::Type{Flatten{I}}) where {I} = flatten_iteratorsize(IteratorSize(I), eltype(I)) function flatten_length(f, T::Type{<:NTuple{N,Any}}) where {N} fieldcount(T)*length(f.it) @@ -924,8 +924,8 @@ end eltype(::Type{PartitionIterator{T}}) where {T} = Vector{eltype(T)} partition_iteratorsize(::HasShape) = HasLength() partition_iteratorsize(isz) = isz -function iteratorsize(::Type{PartitionIterator{T}}) where {T} - partition_iteratorsize(iteratorsize(T)) +function IteratorSize(::Type{PartitionIterator{T}}) where {T} + partition_iteratorsize(IteratorSize(T)) end function length(itr::PartitionIterator) diff --git a/base/libgit2/config.jl b/base/libgit2/config.jl index 25a686568feb3..e33e4ab46f448 100644 --- a/base/libgit2/config.jl +++ b/base/libgit2/config.jl @@ -223,4 +223,4 @@ function Base.next(ci::GitConfigIter, state) return (entry, state) end -Base.iteratorsize(::Type{GitConfigIter}) = Base.SizeUnknown() +Base.IteratorSize(::Type{GitConfigIter}) = Base.SizeUnknown() diff --git a/base/libgit2/reference.jl b/base/libgit2/reference.jl index df37339806cc1..b9297d0aa5dba 100644 --- a/base/libgit2/reference.jl +++ b/base/libgit2/reference.jl @@ -340,7 +340,7 @@ function Base.next(bi::GitBranchIter, state) return (state[1:2], (GitReference(bi.owner, ref_ptr_ptr[]), btype[], false)) end -Base.iteratorsize(::Type{GitBranchIter}) = Base.SizeUnknown() +Base.IteratorSize(::Type{GitBranchIter}) = Base.SizeUnknown() function Base.map(f::Function, bi::GitBranchIter) res = nothing diff --git a/base/libgit2/types.jl b/base/libgit2/types.jl index 7cd6c36f15917..45981a7d5801d 100644 --- a/base/libgit2/types.jl +++ b/base/libgit2/types.jl @@ -1,5 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Base: coalesce import Base.@kwdef import .Consts: GIT_SUBMODULE_IGNORE, GIT_MERGE_FILE_FAVOR, GIT_MERGE_FILE, GIT_CONFIG @@ -894,8 +895,8 @@ function Base.split(ce::ConfigEntry) key = unsafe_string(ce.name) # Determine the positions of the delimiters - subsection_delim = findfirst(equalto('.'), key) - name_delim = findlast(equalto('.'), key) + subsection_delim = coalesce(findfirst(equalto('.'), key), 0) + name_delim = coalesce(findlast(equalto('.'), key), 0) section = SubString(key, 1, subsection_delim - 1) subsection = SubString(key, subsection_delim + 1, name_delim - 1) diff --git a/base/libgit2/walker.jl b/base/libgit2/walker.jl index ac145ff68fd22..af49ff30a5754 100644 --- a/base/libgit2/walker.jl +++ b/base/libgit2/walker.jl @@ -43,7 +43,7 @@ function Base.next(w::GitRevWalker, state) return (state[1], (id_ptr[], false)) end -Base.iteratorsize(::Type{GitRevWalker}) = Base.SizeUnknown() +Base.IteratorSize(::Type{GitRevWalker}) = Base.SizeUnknown() """ LibGit2.push_head!(w::GitRevWalker) diff --git a/base/libuv.jl b/base/libuv.jl index 5ec3f16649b65..2809554550fce 100644 --- a/base/libuv.jl +++ b/base/libuv.jl @@ -20,10 +20,10 @@ function uv_sizeof_req(req) end for h in uv_handle_types -@eval const $(Symbol("_sizeof_",Unicode.lowercase(string(h)))) = uv_sizeof_handle($h) +@eval const $(Symbol("_sizeof_",lowercase(string(h)))) = uv_sizeof_handle($h) end for r in uv_req_types -@eval const $(Symbol("_sizeof_",Unicode.lowercase(string(r)))) = uv_sizeof_req($r) +@eval const $(Symbol("_sizeof_",lowercase(string(r)))) = uv_sizeof_req($r) end uv_handle_data(handle) = ccall(:jl_uv_handle_data,Ptr{Cvoid},(Ptr{Cvoid},),handle) diff --git a/base/linalg/adjtrans.jl b/base/linalg/adjtrans.jl index 46f1229d4cb97..7f462700e5601 100644 --- a/base/linalg/adjtrans.jl +++ b/base/linalg/adjtrans.jl @@ -11,62 +11,73 @@ import Base: length, size, axes, IndexStyle, getindex, setindex!, parent, vec, c struct Adjoint{T,S} <: AbstractMatrix{T} parent::S function Adjoint{T,S}(A::S) where {T,S} - checkeltype(Adjoint, T, eltype(A)) + checkeltype_adjoint(T, eltype(A)) new(A) end end struct Transpose{T,S} <: AbstractMatrix{T} parent::S function Transpose{T,S}(A::S) where {T,S} - checkeltype(Transpose, T, eltype(A)) + checkeltype_transpose(T, eltype(A)) new(A) end end -function checkeltype(::Type{Transform}, ::Type{ResultEltype}, ::Type{ParentEltype}) where {Transform, ResultEltype, ParentEltype} - if ResultEltype !== transformtype(Transform, ParentEltype) - error(string("Element type mismatch. Tried to create an `$Transform{$ResultEltype}` ", - "from an object with eltype `$ParentEltype`, but the element type of the ", - "`$Transform` of an object with eltype `$ParentEltype` must be ", - "`$(transformtype(Transform, ParentEltype))`")) - end +function checkeltype_adjoint(::Type{ResultEltype}, ::Type{ParentEltype}) where {ResultEltype,ParentEltype} + ResultEltype === Base.promote_op(adjoint, ParentEltype) || error(string( + "Element type mismatch. Tried to create an `Adjoint{$ResultEltype}` ", + "from an object with eltype `$ParentEltype`, but the element type of ", + "the adjoint of an object with eltype `$ParentEltype` must be ", + "`$(Base.promote_op(adjoint, ParentEltype))`.")) return nothing end -function transformtype(::Type{O}, ::Type{S}) where {O,S} - # similar to promote_op(::Any, ::Type) - @_inline_meta - T = _return_type(O, Tuple{_default_type(S)}) - _isleaftype(S) && return _isleaftype(T) ? T : Any - return typejoin(S, T) +function checkeltype_transpose(::Type{ResultEltype}, ::Type{ParentEltype}) where {ResultEltype,ParentEltype} + ResultEltype === Base.promote_op(transpose, ParentEltype) || error(string( + "Element type mismatch. Tried to create a `Transpose{$ResultEltype}` ", + "from an object with eltype `$ParentEltype`, but the element type of ", + "the transpose of an object with eltype `$ParentEltype` must be ", + "`$(Base.promote_op(transpose, ParentEltype))`.")) + return nothing end # basic outer constructors -Adjoint(A) = Adjoint{transformtype(Adjoint,eltype(A)),typeof(A)}(A) -Transpose(A) = Transpose{transformtype(Transpose,eltype(A)),typeof(A)}(A) - -# numbers are the end of the line -Adjoint(x::Number) = adjoint(x) -Transpose(x::Number) = transpose(x) - -# unwrapping constructors -Adjoint(A::Adjoint) = A.parent -Transpose(A::Transpose) = A.parent -# normalizing unwrapping constructors -# technically suspect, but at least fine for now -Adjoint(A::Transpose) = conj(A.parent) -Transpose(A::Adjoint) = conj(A.parent) - -# eager lowercase quasi-constructors, unwrapping -adjoint(A::Adjoint) = copy(A.parent) -transpose(A::Transpose) = copy(A.parent) -# eager lowercase quasi-constructors, normalizing -# technically suspect, but at least fine for now -adjoint(A::Transpose) = conj!(copy(A.parent)) -transpose(A::Adjoint) = conj!(copy(A.parent)) - -# lowercase quasi-constructors for vectors, TODO: deprecate -adjoint(sv::AbstractVector) = Adjoint(sv) -transpose(sv::AbstractVector) = Transpose(sv) +Adjoint(A) = Adjoint{Base.promote_op(adjoint,eltype(A)),typeof(A)}(A) +Transpose(A) = Transpose{Base.promote_op(transpose,eltype(A)),typeof(A)}(A) + +# wrapping lowercase quasi-constructors +adjoint(A::AbstractVecOrMat) = Adjoint(A) +""" + transpose(A::AbstractMatrix) + +Lazy matrix transpose. Mutating the returned object should appropriately mutate `A`. Often, +but not always, yields `Transpose(A)`, where `Transpose` is a lazy transpose wrapper. Note +that this operation is recursive. + +This operation is intended for linear algebra usage - for general data manipulation see +[`permutedims`](@ref), which is non-recursive. + +# Examples +```jldoctest +julia> A = [1 2 3; 4 5 6; 7 8 9] +3×3 Array{Int64,2}: + 1 2 3 + 4 5 6 + 7 8 9 + +julia> transpose(A) +3×3 Transpose{Int64,Array{Int64,2}}: + 1 4 7 + 2 5 8 + 3 6 9 +``` +""" +transpose(A::AbstractVecOrMat) = Transpose(A) + +# unwrapping lowercase quasi-constructors +adjoint(A::Adjoint) = A.parent +transpose(A::Transpose) = A.parent +adjoint(A::Transpose{<:Real}) = A.parent +transpose(A::Adjoint{<:Real}) = A.parent # some aliases for internal convenience use @@ -77,10 +88,8 @@ const AdjOrTransAbsVec{T} = AdjOrTrans{T,<:AbstractVector} const AdjOrTransAbsMat{T} = AdjOrTrans{T,<:AbstractMatrix} # for internal use below -wrappertype(A::Adjoint) = Adjoint -wrappertype(A::Transpose) = Transpose -wrappertype(::Type{<:Adjoint}) = Adjoint -wrappertype(::Type{<:Transpose}) = Transpose +wrapperop(A::Adjoint) = adjoint +wrapperop(A::Transpose) = transpose # AbstractArray interface, basic definitions length(A::AdjOrTrans) = length(A.parent) @@ -90,13 +99,13 @@ axes(v::AdjOrTransAbsVec) = (Base.OneTo(1), axes(v.parent)...) axes(A::AdjOrTransAbsMat) = reverse(axes(A.parent)) IndexStyle(::Type{<:AdjOrTransAbsVec}) = IndexLinear() IndexStyle(::Type{<:AdjOrTransAbsMat}) = IndexCartesian() -@propagate_inbounds getindex(v::AdjOrTransAbsVec, i::Int) = wrappertype(v)(v.parent[i]) -@propagate_inbounds getindex(A::AdjOrTransAbsMat, i::Int, j::Int) = wrappertype(A)(A.parent[j, i]) -@propagate_inbounds setindex!(v::AdjOrTransAbsVec, x, i::Int) = (setindex!(v.parent, wrappertype(v)(x), i); v) -@propagate_inbounds setindex!(A::AdjOrTransAbsMat, x, i::Int, j::Int) = (setindex!(A.parent, wrappertype(A)(x), j, i); A) +@propagate_inbounds getindex(v::AdjOrTransAbsVec, i::Int) = wrapperop(v)(v.parent[i]) +@propagate_inbounds getindex(A::AdjOrTransAbsMat, i::Int, j::Int) = wrapperop(A)(A.parent[j, i]) +@propagate_inbounds setindex!(v::AdjOrTransAbsVec, x, i::Int) = (setindex!(v.parent, wrapperop(v)(x), i); v) +@propagate_inbounds setindex!(A::AdjOrTransAbsMat, x, i::Int, j::Int) = (setindex!(A.parent, wrapperop(A)(x), j, i); A) # AbstractArray interface, additional definitions to retain wrapper over vectors where appropriate -@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, is::AbstractArray{Int}) = wrappertype(v)(v.parent[is]) -@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, ::Colon) = wrappertype(v)(v.parent[:]) +@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, is::AbstractArray{Int}) = wrapperop(v)(v.parent[is]) +@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, ::Colon) = wrapperop(v)(v.parent[:]) # conversion of underlying storage convert(::Type{Adjoint{T,S}}, A::Adjoint) where {T,S} = Adjoint{T,S}(convert(S, A.parent)) @@ -104,8 +113,8 @@ convert(::Type{Transpose{T,S}}, A::Transpose) where {T,S} = Transpose{T,S}(conve # for vectors, the semantics of the wrapped and unwrapped types differ # so attempt to maintain both the parent and wrapper type insofar as possible -similar(A::AdjOrTransAbsVec) = wrappertype(A)(similar(A.parent)) -similar(A::AdjOrTransAbsVec, ::Type{T}) where {T} = wrappertype(A)(similar(A.parent, transformtype(wrappertype(A), T))) +similar(A::AdjOrTransAbsVec) = wrapperop(A)(similar(A.parent)) +similar(A::AdjOrTransAbsVec, ::Type{T}) where {T} = wrapperop(A)(similar(A.parent, Base.promote_op(wrapperop(A), T))) # for matrices, the semantics of the wrapped and unwrapped types are generally the same # and as you are allocating with similar anyway, you might as well get something unwrapped similar(A::AdjOrTrans) = similar(A.parent, eltype(A), size(A)) @@ -116,21 +125,24 @@ similar(A::AdjOrTrans, ::Type{T}, dims::Dims{N}) where {T,N} = similar(A.parent, parent(A::AdjOrTrans) = A.parent vec(v::AdjOrTransAbsVec) = v.parent +cmp(A::AdjOrTransAbsVec, B::AdjOrTransAbsVec) = cmp(parent(A), parent(B)) +isless(A::AdjOrTransAbsVec, B::AdjOrTransAbsVec) = isless(parent(A), parent(B)) ### concatenation # preserve Adjoint/Transpose wrapper around vectors # to retain the associated semantics post-concatenation hcat(avs::Union{Number,AdjointAbsVec}...) = _adjoint_hcat(avs...) hcat(tvs::Union{Number,TransposeAbsVec}...) = _transpose_hcat(tvs...) -_adjoint_hcat(avs::Union{Number,AdjointAbsVec}...) = Adjoint(vcat(map(Adjoint, avs)...)) -_transpose_hcat(tvs::Union{Number,TransposeAbsVec}...) = Transpose(vcat(map(Transpose, tvs)...)) -typed_hcat(::Type{T}, avs::Union{Number,AdjointAbsVec}...) where {T} = Adjoint(typed_vcat(T, map(Adjoint, avs)...)) -typed_hcat(::Type{T}, tvs::Union{Number,TransposeAbsVec}...) where {T} = Transpose(typed_vcat(T, map(Transpose, tvs)...)) +_adjoint_hcat(avs::Union{Number,AdjointAbsVec}...) = adjoint(vcat(map(adjoint, avs)...)) +_transpose_hcat(tvs::Union{Number,TransposeAbsVec}...) = transpose(vcat(map(transpose, tvs)...)) +typed_hcat(::Type{T}, avs::Union{Number,AdjointAbsVec}...) where {T} = adjoint(typed_vcat(T, map(adjoint, avs)...)) +typed_hcat(::Type{T}, tvs::Union{Number,TransposeAbsVec}...) where {T} = transpose(typed_vcat(T, map(transpose, tvs)...)) # otherwise-redundant definitions necessary to prevent hitting the concat methods in sparse/sparsevector.jl hcat(avs::Adjoint{<:Any,<:Vector}...) = _adjoint_hcat(avs...) hcat(tvs::Transpose{<:Any,<:Vector}...) = _transpose_hcat(tvs...) hcat(avs::Adjoint{T,Vector{T}}...) where {T} = _adjoint_hcat(avs...) hcat(tvs::Transpose{T,Vector{T}}...) where {T} = _transpose_hcat(tvs...) +# TODO unify and allow mixed combinations ### higher order functions @@ -138,14 +150,14 @@ hcat(tvs::Transpose{T,Vector{T}}...) where {T} = _transpose_hcat(tvs...) # to retain the associated semantics post-map/broadcast # # note that the caller's operation f operates in the domain of the wrapped vectors' entries. -# hence the Adjoint->f->Adjoint shenanigans applied to the parent vectors' entries. -map(f, avs::AdjointAbsVec...) = Adjoint(map((xs...) -> Adjoint(f(Adjoint.(xs)...)), parent.(avs)...)) -map(f, tvs::TransposeAbsVec...) = Transpose(map((xs...) -> Transpose(f(Transpose.(xs)...)), parent.(tvs)...)) +# hence the adjoint->f->adjoint shenanigans applied to the parent vectors' entries. +map(f, avs::AdjointAbsVec...) = adjoint(map((xs...) -> adjoint(f(adjoint.(xs)...)), parent.(avs)...)) +map(f, tvs::TransposeAbsVec...) = transpose(map((xs...) -> transpose(f(transpose.(xs)...)), parent.(tvs)...)) quasiparentt(x) = parent(x); quasiparentt(x::Number) = x # to handle numbers in the defs below quasiparenta(x) = parent(x); quasiparenta(x::Number) = conj(x) # to handle numbers in the defs below -broadcast(f, avs::Union{Number,AdjointAbsVec}...) = Adjoint(broadcast((xs...) -> Adjoint(f(Adjoint.(xs)...)), quasiparenta.(avs)...)) -broadcast(f, tvs::Union{Number,TransposeAbsVec}...) = Transpose(broadcast((xs...) -> Transpose(f(Transpose.(xs)...)), quasiparentt.(tvs)...)) - +broadcast(f, avs::Union{Number,AdjointAbsVec}...) = adjoint(broadcast((xs...) -> adjoint(f(adjoint.(xs)...)), quasiparenta.(avs)...)) +broadcast(f, tvs::Union{Number,TransposeAbsVec}...) = transpose(broadcast((xs...) -> transpose(f(transpose.(xs)...)), quasiparentt.(tvs)...)) +# TODO unify and allow mixed combinations ### linear algebra @@ -166,11 +178,11 @@ end *(u::TransposeAbsVec, v::TransposeAbsVec) = throw(MethodError(*, (u, v))) # Adjoint/Transpose-vector * matrix -*(u::AdjointAbsVec, A::AbstractMatrix) = Adjoint(Adjoint(A) * u.parent) -*(u::TransposeAbsVec, A::AbstractMatrix) = Transpose(Transpose(A) * u.parent) +*(u::AdjointAbsVec, A::AbstractMatrix) = adjoint(adjoint(A) * u.parent) +*(u::TransposeAbsVec, A::AbstractMatrix) = transpose(transpose(A) * u.parent) # Adjoint/Transpose-vector * Adjoint/Transpose-matrix -*(u::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractMatrix}) = Adjoint(A.parent * u.parent) -*(u::TransposeAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = Transpose(A.parent * u.parent) +*(u::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractMatrix}) = adjoint(A.parent * u.parent) +*(u::TransposeAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = transpose(A.parent * u.parent) ## pseudoinversion @@ -183,15 +195,16 @@ pinv(v::TransposeAbsVec, tol::Real = 0) = pinv(conj(v.parent)).parent ## right-division \ -/(u::AdjointAbsVec, A::AbstractMatrix) = Adjoint(Adjoint(A) \ u.parent) -/(u::TransposeAbsVec, A::AbstractMatrix) = Transpose(Transpose(A) \ u.parent) - +/(u::AdjointAbsVec, A::AbstractMatrix) = adjoint(adjoint(A) \ u.parent) +/(u::TransposeAbsVec, A::AbstractMatrix) = transpose(transpose(A) \ u.parent) +/(u::AdjointAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = adjoint(conj(A.parent) \ u.parent) # technically should be adjoint(copy(adjoint(copy(A))) \ u.parent) +/(u::TransposeAbsVec, A::Adjoint{<:Any,<:AbstractMatrix}) = transpose(conj(A.parent) \ u.parent) # technically should be transpose(copy(transpose(copy(A))) \ u.parent) # dismabiguation methods -*(A::AdjointAbsVec, B::Transpose{<:Any,<:AbstractMatrix}) = A * transpose(B.parent) -*(A::TransposeAbsVec, B::Adjoint{<:Any,<:AbstractMatrix}) = A * adjoint(B.parent) -*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractMatrix}) = transpose(A.parent) * B -*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:AbstractMatrix}) = A * transpose(B.parent) +*(A::AdjointAbsVec, B::Transpose{<:Any,<:AbstractMatrix}) = A * copy(B) +*(A::TransposeAbsVec, B::Adjoint{<:Any,<:AbstractMatrix}) = A * copy(B) +*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractMatrix}) = copy(A) * B +*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:AbstractMatrix}) = A * copy(B) # Adj/Trans-vector * Trans/Adj-vector, shouldn't exist, here for ambiguity resolution? TODO: test removal *(A::Adjoint{<:Any,<:AbstractVector}, B::Transpose{<:Any,<:AbstractVector}) = throw(MethodError(*, (A, B))) *(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractVector}) = throw(MethodError(*, (A, B))) diff --git a/base/linalg/bidiag.jl b/base/linalg/bidiag.jl index 7c6ad8b1bd2eb..83215bff1d122 100644 --- a/base/linalg/bidiag.jl +++ b/base/linalg/bidiag.jl @@ -178,7 +178,8 @@ broadcast(::typeof(big), B::Bidiagonal) = Bidiagonal(big.(B.dv), big.(B.ev), B.u # On the other hand, similar(B, [neweltype,] shape...) should yield a sparse matrix. # The first method below effects the former, and the second the latter. similar(B::Bidiagonal, ::Type{T}) where {T} = Bidiagonal(similar(B.dv, T), similar(B.ev, T), B.uplo) -similar(B::Bidiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) +# The method below is moved to SparseArrays for now +# similar(B::Bidiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) ################### @@ -247,8 +248,14 @@ broadcast(::typeof(trunc), ::Type{T}, M::Bidiagonal) where {T<:Integer} = Bidiag broadcast(::typeof(floor), ::Type{T}, M::Bidiagonal) where {T<:Integer} = Bidiagonal(floor.(T, M.dv), floor.(T, M.ev), M.uplo) broadcast(::typeof(ceil), ::Type{T}, M::Bidiagonal) where {T<:Integer} = Bidiagonal(ceil.(T, M.dv), ceil.(T, M.ev), M.uplo) -transpose(M::Bidiagonal) = Bidiagonal(M.dv, M.ev, M.uplo == 'U' ? :L : :U) -adjoint(M::Bidiagonal) = Bidiagonal(conj(M.dv), conj(M.ev), M.uplo == 'U' ? :L : :U) +adjoint(B::Bidiagonal) = Adjoint(B) +transpose(B::Bidiagonal) = Transpose(B) +adjoint(B::Bidiagonal{<:Real}) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? :L : :U) +transpose(B::Bidiagonal{<:Number}) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? :L : :U) +Base.copy(aB::Adjoint{<:Any,<:Bidiagonal}) = + (B = aB.parent; Bidiagonal(map(x -> copy.(adjoint.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U)) +Base.copy(tB::Transpose{<:Any,<:Bidiagonal}) = + (B = tB.parent; Bidiagonal(map(x -> copy.(transpose.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U)) istriu(M::Bidiagonal) = M.uplo == 'U' || iszero(M.ev) istril(M::Bidiagonal) = M.uplo == 'L' || iszero(M.ev) @@ -494,15 +501,15 @@ const SpecialMatrix = Union{Bidiagonal,SymTridiagonal,Tridiagonal} #Generic multiplication *(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} = *(Array(A), B) -*(adjA::Adjoint{<:Any,<:Bidiagonal{T}}, B::AbstractVector{T}) where {T} = *(Adjoint(Array(adjA.parent)), B) -*(A::Bidiagonal{T}, adjB::Adjoint{<:Any,<:AbstractVector{T}}) where {T} = *(Array(A), Adjoint(adjB.parent)) +*(adjA::Adjoint{<:Any,<:Bidiagonal{T}}, B::AbstractVector{T}) where {T} = *(adjoint(Array(adjA.parent)), B) +*(A::Bidiagonal{T}, adjB::Adjoint{<:Any,<:AbstractVector{T}}) where {T} = *(Array(A), adjoint(adjB.parent)) /(A::Bidiagonal{T}, B::AbstractVector{T}) where {T} = /(Array(A), B) -/(A::Bidiagonal{T}, adjB::Adjoint{<:Any,<:AbstractVector{T}}) where {T} = /(Array(A), Adjoint(adjB.parent)) +/(A::Bidiagonal{T}, adjB::Adjoint{<:Any,<:AbstractVector{T}}) where {T} = /(Array(A), adjoint(adjB.parent)) #Linear solvers ldiv!(A::Union{Bidiagonal, AbstractTriangular}, b::AbstractVector) = naivesub!(A, b) -ldiv!(transA::Transpose{<:Any,<:Bidiagonal}, b::AbstractVector) = ldiv!(transpose(transA.parent), b) -ldiv!(adjA::Adjoint{<:Any,<:Bidiagonal}, b::AbstractVector) = ldiv!(adjoint(adjA.parent), b) +ldiv!(A::Transpose{<:Any,<:Bidiagonal}, b::AbstractVector) = ldiv!(copy(A), b) +ldiv!(A::Adjoint{<:Any,<:Bidiagonal}, b::AbstractVector) = ldiv!(copy(A), b) function ldiv!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix) nA,mA = size(A) tmp = similar(B,size(B,1)) @@ -527,7 +534,7 @@ function ldiv!(adjA::Adjoint{<:Any,<:Union{Bidiagonal,AbstractTriangular}}, B::A end for i = 1:size(B,2) copyto!(tmp, 1, B, (i - 1)*n + 1, n) - ldiv!(Adjoint(A), tmp) + ldiv!(adjoint(A), tmp) copyto!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented. end B @@ -542,7 +549,7 @@ function ldiv!(transA::Transpose{<:Any,<:Union{Bidiagonal,AbstractTriangular}}, end for i = 1:size(B,2) copyto!(tmp, 1, B, (i - 1)*n + 1, n) - ldiv!(Transpose(A), tmp) + ldiv!(transpose(A), tmp) copyto!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented. end B @@ -580,16 +587,16 @@ function \(transA::Transpose{<:Number,<:Bidiagonal{<:Number}}, B::AbstractVecOrM A = transA.parent TA, TB = eltype(A), eltype(B) TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) - ldiv!(Transpose(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB)) + ldiv!(transpose(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB)) end -\(transA::Transpose{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(Transpose(transA.parent), copy(B)) +\(transA::Transpose{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(transpose(transA.parent), copy(B)) function \(adjA::Adjoint{<:Number,<:Bidiagonal{<:Number}}, B::AbstractVecOrMat{<:Number}) A = adjA.parent TA, TB = eltype(A), eltype(B) TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA)) - ldiv!(Adjoint(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB)) + ldiv!(adjoint(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB)) end -\(adjA::Adjoint{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(Adjoint(adjA.parent), copy(B)) +\(adjA::Adjoint{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(adjoint(adjA.parent), copy(B)) factorize(A::Bidiagonal) = A diff --git a/base/linalg/bitarray.jl b/base/linalg/bitarray.jl index d2f1601f418ff..ea127ddfeebf4 100644 --- a/base/linalg/bitarray.jl +++ b/base/linalg/bitarray.jl @@ -123,7 +123,7 @@ end ## Structure query functions -issymmetric(A::BitMatrix) = size(A, 1)==size(A, 2) && count(!iszero, A - transpose(A))==0 +issymmetric(A::BitMatrix) = size(A, 1)==size(A, 2) && count(!iszero, A - copy(A'))==0 ishermitian(A::BitMatrix) = issymmetric(A) function nonzero_chunks(chunks::Vector{UInt64}, pos0::Int, pos1::Int) @@ -250,16 +250,19 @@ function put_8x8_chunk(Bc::Vector{UInt64}, i1::Int, i2::Int, x::UInt64, m::Int, return end -function transpose(B::BitMatrix) - l1 = size(B, 1) - l2 = size(B, 2) - Bt = falses(l2, l1) +adjoint(B::Union{BitVector,BitMatrix}) = Adjoint(B) +transpose(B::Union{BitVector,BitMatrix}) = Transpose(B) +Base.copy(B::Adjoint{Bool,BitMatrix}) = transpose!(falses(size(B)), B.parent) +Base.copy(B::Transpose{Bool,BitMatrix}) = transpose!(falses(size(B)), B.parent) +function transpose!(C::BitMatrix, B::BitMatrix) + @boundscheck size(C) == reverse(size(B)) || throw(DimensionMismatch()) + l1, l2 = size(B) cgap1, cinc1 = Base._div64(l1), Base._mod64(l1) cgap2, cinc2 = Base._div64(l2), Base._mod64(l2) Bc = B.chunks - Btc = Bt.chunks + Cc = C.chunks nc = length(Bc) @@ -278,10 +281,8 @@ function transpose(B::BitMatrix) msk8_2 >>>= j + 7 - l2 end - put_8x8_chunk(Btc, j, i, x, l2, cgap2, cinc2, nc, msk8_2) + put_8x8_chunk(Cc, j, i, x, l2, cgap2, cinc2, nc, msk8_2) end end - return Bt + return C end - -adjoint(B::Union{BitMatrix,BitVector}) = transpose(B) diff --git a/base/linalg/blas.jl b/base/linalg/blas.jl index 02faac2e8b362..36a39ae9895b5 100644 --- a/base/linalg/blas.jl +++ b/base/linalg/blas.jl @@ -65,6 +65,8 @@ const liblapack = Base.liblapack_name import ..LinAlg: BlasReal, BlasComplex, BlasFloat, BlasInt, DimensionMismatch, checksquare, stride1, chkstride1, axpy! +import Libdl + # utility routines function vendor() lib = Libdl.dlopen_e(Base.libblas_name) @@ -1000,7 +1002,7 @@ end """ syr!(uplo, alpha, x, A) -Rank-1 update of the symmetric matrix `A` with vector `x` as `alpha*x*Transpose(x) + A`. +Rank-1 update of the symmetric matrix `A` with vector `x` as `alpha*x*transpose(x) + A`. [`uplo`](@ref stdlib-blas-uplo) controls which triangle of `A` is updated. Returns `A`. """ function syr! end @@ -1243,7 +1245,7 @@ end """ syrk!(uplo, trans, alpha, A, beta, C) -Rank-k update of the symmetric matrix `C` as `alpha*A*Transpose(A) + beta*C` or `alpha*Transpose(A)*A + +Rank-k update of the symmetric matrix `C` as `alpha*A*transpose(A) + beta*C` or `alpha*transpose(A)*A + beta*C` according to [`trans`](@ref stdlib-blas-trans). Only the [`uplo`](@ref stdlib-blas-uplo) triangle of `C` is used. Returns `C`. """ @@ -1254,7 +1256,7 @@ function syrk! end Returns either the upper triangle or the lower triangle of `A`, according to [`uplo`](@ref stdlib-blas-uplo), -of `alpha*A*Transpose(A)` or `alpha*Transpose(A)*A`, +of `alpha*A*transpose(A)` or `alpha*transpose(A)*A`, according to [`trans`](@ref stdlib-blas-trans). """ function syrk end diff --git a/base/linalg/bunchkaufman.jl b/base/linalg/bunchkaufman.jl index e42d29f1b6c9b..fc36a1e888c25 100644 --- a/base/linalg/bunchkaufman.jl +++ b/base/linalg/bunchkaufman.jl @@ -43,7 +43,7 @@ end """ bkfact(A, rook::Bool=false) -> BunchKaufman -Compute the Bunch-Kaufman [^Bunch1977] factorization of a symmetric or Hermitian matrix `A` as ``P'*U*D*U'*P`` or ``P'*L*D*L'*P``, depending on which triangle is stored in `A`, and return a `BunchKaufman` object. Note that if `A` is complex symmetric then `U'` and `L'` denote the unconjugated transposes, i.e. `Transpose(U)` and `Transpose(L)`. +Compute the Bunch-Kaufman [^Bunch1977] factorization of a symmetric or Hermitian matrix `A` as ``P'*U*D*U'*P`` or ``P'*L*D*L'*P``, depending on which triangle is stored in `A`, and return a `BunchKaufman` object. Note that if `A` is complex symmetric then `U'` and `L'` denote the unconjugated transposes, i.e. `transpose(U)` and `transpose(L)`. If `rook` is `true`, rook pivoting is used. If `rook` is false, rook pivoting is not used. @@ -115,7 +115,7 @@ end getproperty(B::BunchKaufman, d::Symbol) Extract the factors of the Bunch-Kaufman factorization `B`. The factorization can take the -two forms `P'*L*D*L'*P` or `P'*U*D*U'*P` (or `L*D*Transpose(L)` in the complex symmetric case) +two forms `P'*L*D*L'*P` or `P'*U*D*U'*P` (or `L*D*transpose(L)` in the complex symmetric case) where `P` is a (symmetric) permutation matrix, `L` is a `UnitLowerTriangular` matrix, `U` is a `UnitUpperTriangular`, and `D` is a block diagonal symmetric or Hermitian matrix with 1x1 or 2x2 blocks. The argument `d` can be @@ -191,13 +191,13 @@ function getproperty(B::BunchKaufman{T}, d::Symbol) where {T<:BlasFloat} if getfield(B, :uplo) == 'L' return UnitLowerTriangular(LUD) else - throw(ArgumentError("factorization is U*D*Transpose(U) but you requested L")) + throw(ArgumentError("factorization is U*D*transpose(U) but you requested L")) end else # :U if B.uplo == 'U' return UnitUpperTriangular(LUD) else - throw(ArgumentError("factorization is L*D*Transpose(L) but you requested U")) + throw(ArgumentError("factorization is L*D*transpose(L) but you requested U")) end end else diff --git a/base/linalg/cholesky.jl b/base/linalg/cholesky.jl index bd8d1eb5db013..6ed5cdf6b2fc4 100644 --- a/base/linalg/cholesky.jl +++ b/base/linalg/cholesky.jl @@ -87,7 +87,7 @@ function _chol!(A::AbstractMatrix, ::Type{UpperTriangular}) return UpperTriangular(A), info end A[k,k] = Akk - AkkInv = inv(adjoint(Akk)) + AkkInv = inv(copy(Akk')) for j = k + 1:n for i = 1:k - 1 A[k,j] -= A[i,k]'A[i,j] @@ -384,9 +384,9 @@ function getproperty(C::Cholesky, d::Symbol) Cfactors = getfield(C, :factors) Cuplo = getfield(C, :uplo) if d == :U - return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors)) + return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors')) elseif d == :L - return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors)) + return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors')) elseif d == :UL return Symbol(Cuplo) == :U ? UpperTriangular(Cfactors) : LowerTriangular(Cfactors) else @@ -397,9 +397,9 @@ function getproperty(C::CholeskyPivoted{T}, d::Symbol) where T<:BlasFloat Cfactors = getfield(C, :factors) Cuplo = getfield(C, :uplo) if d == :U - return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors)) + return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors')) elseif d == :L - return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors)) + return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors')) elseif d == :p return getfield(C, :piv) elseif d == :P @@ -437,9 +437,9 @@ ldiv!(C::Cholesky{T,<:AbstractMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloa function ldiv!(C::Cholesky{<:Any,<:AbstractMatrix}, B::StridedVecOrMat) if C.uplo == 'L' - return ldiv!(Adjoint(LowerTriangular(C.factors)), ldiv!(LowerTriangular(C.factors), B)) + return ldiv!(adjoint(LowerTriangular(C.factors)), ldiv!(LowerTriangular(C.factors), B)) else - return ldiv!(UpperTriangular(C.factors), ldiv!(Adjoint(UpperTriangular(C.factors)), B)) + return ldiv!(UpperTriangular(C.factors), ldiv!(adjoint(UpperTriangular(C.factors)), B)) end end @@ -462,21 +462,21 @@ end function ldiv!(C::CholeskyPivoted, B::StridedVector) if C.uplo == 'L' - ldiv!(Adjoint(LowerTriangular(C.factors)), + ldiv!(adjoint(LowerTriangular(C.factors)), ldiv!(LowerTriangular(C.factors), B[C.piv]))[invperm(C.piv)] else ldiv!(UpperTriangular(C.factors), - ldiv!(Adjoint(UpperTriangular(C.factors)), B[C.piv]))[invperm(C.piv)] + ldiv!(adjoint(UpperTriangular(C.factors)), B[C.piv]))[invperm(C.piv)] end end function ldiv!(C::CholeskyPivoted, B::StridedMatrix) if C.uplo == 'L' - ldiv!(Adjoint(LowerTriangular(C.factors)), + ldiv!(adjoint(LowerTriangular(C.factors)), ldiv!(LowerTriangular(C.factors), B[C.piv,:]))[invperm(C.piv),:] else ldiv!(UpperTriangular(C.factors), - ldiv!(Adjoint(UpperTriangular(C.factors)), B[C.piv,:]))[invperm(C.piv),:] + ldiv!(adjoint(UpperTriangular(C.factors)), B[C.piv,:]))[invperm(C.piv),:] end end diff --git a/base/linalg/dense.jl b/base/linalg/dense.jl index 246c3ec059a71..76109f7fd63e8 100644 --- a/base/linalg/dense.jl +++ b/base/linalg/dense.jl @@ -303,8 +303,6 @@ Vector `kv.second` will be placed on the `kv.first` diagonal. versions with fast arithmetic, see [`Diagonal`](@ref), [`Bidiagonal`](@ref) [`Tridiagonal`](@ref) and [`SymTridiagonal`](@ref). -See also: [`spdiagm`](@ref) - # Examples ```jldoctest julia> diagm(1 => [1,2,3]) @@ -1238,7 +1236,7 @@ the pseudoinverse by inverting only singular values above a given threshold, The optimal choice of `tol` varies both with the value of `M` and the intended application of the pseudoinverse. The default value of `tol` is -`eps(real(float(one(eltype(M)))))*maximum(size(A))`, which is essentially machine epsilon +`eps(real(float(one(eltype(M)))))*maximum(size(M))`, which is essentially machine epsilon for the real part of a matrix element multiplied by the larger matrix dimension. For inverting dense ill-conditioned matrices in a least-squares sense, `tol = sqrt(eps(real(float(one(eltype(M))))))` is recommended. @@ -1336,7 +1334,7 @@ function nullspace(A::StridedMatrix{T}) where T (m == 0 || n == 0) && return Matrix{T}(I, n, n) SVD = svdfact(A, full = true) indstart = sum(SVD.S .> max(m,n)*maximum(SVD.S)*eps(eltype(SVD.S))) + 1 - return adjoint(SVD.Vt[indstart:end,:]) + return copy(SVD.Vt[indstart:end,:]') end nullspace(a::StridedVector) = nullspace(reshape(a, length(a), 1)) @@ -1402,9 +1400,9 @@ function sylvester(A::StridedMatrix{T},B::StridedMatrix{T},C::StridedMatrix{T}) RA, QA = schur(A) RB, QB = schur(B) - D = -(Adjoint(QA) * (C*QB)) + D = -(adjoint(QA) * (C*QB)) Y, scale = LAPACK.trsyl!('N','N', RA, RB, D) - scale!(QA*(Y * Adjoint(QB)), inv(scale)) + scale!(QA*(Y * adjoint(QB)), inv(scale)) end sylvester(A::StridedMatrix{T}, B::StridedMatrix{T}, C::StridedMatrix{T}) where {T<:Integer} = sylvester(float(A), float(B), float(C)) @@ -1445,9 +1443,9 @@ julia> A*X + X*A' + B function lyap(A::StridedMatrix{T}, C::StridedMatrix{T}) where {T<:BlasFloat} R, Q = schur(A) - D = -(Adjoint(Q) * (C*Q)) + D = -(adjoint(Q) * (C*Q)) Y, scale = LAPACK.trsyl!('N', T <: Complex ? 'C' : 'T', R, R, D) - scale!(Q*(Y * Adjoint(Q)), inv(scale)) + scale!(Q*(Y * adjoint(Q)), inv(scale)) end lyap(A::StridedMatrix{T}, C::StridedMatrix{T}) where {T<:Integer} = lyap(float(A), float(C)) lyap(a::T, c::T) where {T<:Number} = -c/(2a) diff --git a/base/linalg/diagonal.jl b/base/linalg/diagonal.jl index 25600afa2293f..8d0c8a67fb71c 100644 --- a/base/linalg/diagonal.jl +++ b/base/linalg/diagonal.jl @@ -59,7 +59,8 @@ Array(D::Diagonal) = Matrix(D) # On the other hand, similar(D, [neweltype,] shape...) should yield a sparse matrix. # The first method below effects the former, and the second the latter. similar(D::Diagonal, ::Type{T}) where {T} = Diagonal(similar(D.diag, T)) -similar(D::Diagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) +# The method below is moved to SparseArrays for now +# similar(D::Diagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) copyto!(D1::Diagonal, D2::Diagonal) = (copyto!(D1.diag, D2.diag); D1) @@ -150,103 +151,91 @@ end (*)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag .* Db.diag) (*)(D::Diagonal, V::AbstractVector) = D.diag .* V -(*)(A::AbstractTriangular, D::Diagonal) = mul!(copy(A), D) -(*)(D::Diagonal, B::AbstractTriangular) = mul!(D, copy(B)) +(*)(A::AbstractTriangular, D::Diagonal) = mul1!(copy(A), D) +(*)(D::Diagonal, B::AbstractTriangular) = mul2!(D, copy(B)) (*)(A::AbstractMatrix, D::Diagonal) = scale!(similar(A, promote_op(*, eltype(A), eltype(D.diag)), size(A)), A, D.diag) (*)(D::Diagonal, A::AbstractMatrix) = scale!(similar(A, promote_op(*, eltype(A), eltype(D.diag)), size(A)), D.diag, A) -mul!(A::Union{LowerTriangular,UpperTriangular}, D::Diagonal) = typeof(A)(mul!(A.data, D)) -function mul!(A::UnitLowerTriangular, D::Diagonal) - mul!(A.data, D) + +mul1!(A::Union{LowerTriangular,UpperTriangular}, D::Diagonal) = typeof(A)(mul1!(A.data, D)) +function mul1!(A::UnitLowerTriangular, D::Diagonal) + mul1!(A.data, D) for i = 1:size(A, 1) A.data[i,i] = D.diag[i] end LowerTriangular(A.data) end -function mul!(A::UnitUpperTriangular, D::Diagonal) - mul!(A.data, D) +function mul1!(A::UnitUpperTriangular, D::Diagonal) + mul1!(A.data, D) for i = 1:size(A, 1) A.data[i,i] = D.diag[i] end UpperTriangular(A.data) end -function mul!(D::Diagonal, B::UnitLowerTriangular) - mul!(D, B.data) + +function mul2!(D::Diagonal, B::UnitLowerTriangular) + mul2!(D, B.data) for i = 1:size(B, 1) B.data[i,i] = D.diag[i] end LowerTriangular(B.data) end -function mul!(D::Diagonal, B::UnitUpperTriangular) - mul!(D, B.data) +function mul2!(D::Diagonal, B::UnitUpperTriangular) + mul2!(D, B.data) for i = 1:size(B, 1) B.data[i,i] = D.diag[i] end UpperTriangular(B.data) end -*(adjD::Adjoint{<:Any,<:Diagonal}, B::Diagonal) = (D = adjD.parent; Diagonal(adjoint.(D.diag) .* B.diag)) -*(adjA::Adjoint{<:Any,<:AbstractTriangular}, D::Diagonal) = (A = adjA.parent; mul!(adjoint(A), D)) +*(D::Adjoint{<:Any,<:Diagonal}, B::Diagonal) = Diagonal(adjoint.(D.parent.diag) .* B.diag) +*(A::Adjoint{<:Any,<:AbstractTriangular}, D::Diagonal) = mul1!(copy(A), D) function *(adjA::Adjoint{<:Any,<:AbstractMatrix}, D::Diagonal) A = adjA.parent Ac = similar(A, promote_op(*, eltype(A), eltype(D.diag)), (size(A, 2), size(A, 1))) adjoint!(Ac, A) - mul!(Ac, D) + mul1!(Ac, D) end -*(transD::Transpose{<:Any,<:Diagonal}, B::Diagonal) = (D = transD.parent; Diagonal(transpose.(D.diag) .* B.diag)) -*(transA::Transpose{<:Any,<:AbstractTriangular}, D::Diagonal) = (A = transA.parent; mul!(transpose(A), D)) +*(D::Transpose{<:Any,<:Diagonal}, B::Diagonal) = Diagonal(transpose.(D.parent.diag) .* B.diag) +*(A::Transpose{<:Any,<:AbstractTriangular}, D::Diagonal) = mul1!(copy(A), D) function *(transA::Transpose{<:Any,<:AbstractMatrix}, D::Diagonal) A = transA.parent At = similar(A, promote_op(*, eltype(A), eltype(D.diag)), (size(A, 2), size(A, 1))) transpose!(At, A) - mul!(At, D) + mul1!(At, D) end -*(D::Diagonal, adjB::Adjoint{<:Any,<:Diagonal}) = (B = adjB.parent; Diagonal(D.diag .* adjoint.(B.diag))) -*(D::Diagonal, adjB::Adjoint{<:Any,<:AbstractTriangular}) = (B = adjB.parent; mul!(D, adjoint(B))) -*(D::Diagonal, adjQ::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = (Q = adjQ.parent; mul!(Array(D), Adjoint(Q))) +*(D::Diagonal, B::Adjoint{<:Any,<:Diagonal}) = Diagonal(D.diag .* adjoint.(B.parent.diag)) +*(D::Diagonal, B::Adjoint{<:Any,<:AbstractTriangular}) = mul2!(D, collect(B)) +*(D::Diagonal, adjQ::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = (Q = adjQ.parent; mul1!(Array(D), adjoint(Q))) function *(D::Diagonal, adjA::Adjoint{<:Any,<:AbstractMatrix}) A = adjA.parent Ac = similar(A, promote_op(*, eltype(A), eltype(D.diag)), (size(A, 2), size(A, 1))) adjoint!(Ac, A) - mul!(D, Ac) + mul2!(D, Ac) end -*(D::Diagonal, transB::Transpose{<:Any,<:Diagonal}) = (B = transB.parent; Diagonal(D.diag .* transpose.(B.diag))) -*(D::Diagonal, transB::Transpose{<:Any,<:AbstractTriangular}) = (B = transB.parent; mul!(D, transpose(B))) +*(D::Diagonal, B::Transpose{<:Any,<:Diagonal}) = Diagonal(D.diag .* transpose.(B.parent.diag)) +*(D::Diagonal, B::Transpose{<:Any,<:AbstractTriangular}) = mul2!(D, copy(B)) function *(D::Diagonal, transA::Transpose{<:Any,<:AbstractMatrix}) A = transA.parent At = similar(A, promote_op(*, eltype(A), eltype(D.diag)), (size(A, 2), size(A, 1))) transpose!(At, A) - mul!(D, At) + mul2!(D, At) end -*(adjD::Adjoint{<:Any,<:Diagonal}, adjB::Adjoint{<:Any,<:Diagonal}) = - (D = adjD.parent; B = adjB.parent; Diagonal(adjoint.(D.diag) .* adjoint.(B.diag))) -*(transD::Transpose{<:Any,<:Diagonal}, transB::Transpose{<:Any,<:Diagonal}) = - (D = transD.parent; B = transB.parent; Diagonal(transpose.(D.diag) .* transpose.(B.diag))) - -mul!(A::Diagonal, B::Diagonal) = throw(MethodError(mul!, Tuple{Diagonal,Diagonal})) -mul!(A::QRPackedQ, D::Diagonal) = throw(MethodError(mul!, Tuple{Diagonal,Diagonal})) -mul!(A::QRPackedQ, B::Adjoint{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::QRPackedQ, B::Transpose{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:QRPackedQ}, B::Diagonal) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:QRPackedQ}, B::Adjoint{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:QRPackedQ}, B::Transpose{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Diagonal, B::Adjoint{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Diagonal, B::Transpose{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Transpose{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Diagonal}) = throw(MethodError(mul!, (A, B))) -mul!(transA::Transpose{<:Any,<:Diagonal}, B::Diagonal) = - throw(MethodError(mul!, Tuple{Transpose{<:Any,<:Diagonal},Diagonal})) -mul!(adjA::Adjoint{<:Any,<:Diagonal}, B::Diagonal) = - throw(MethodError(mul!, Tuple{Adjoint{<:Any,<:Diagonal},Diagonal})) +*(D::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Diagonal}) = + Diagonal(adjoint.(D.parent.diag) .* adjoint.(B.parent.diag)) +*(D::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Diagonal}) = + Diagonal(transpose.(D.parent.diag) .* transpose.(B.parent.diag)) + +mul1!(A::Diagonal,B::Diagonal) = Diagonal(A.diag .*= B.diag) +mul2!(A::Diagonal,B::Diagonal) = Diagonal(B.diag .= A.diag .* B.diag) + mul!(A::Diagonal, B::AbstractMatrix) = scale!(A.diag, B) mul!(adjA::Adjoint{<:Any,<:Diagonal}, B::AbstractMatrix) = (A = adjA.parent; scale!(conj(A.diag),B)) mul!(transA::Transpose{<:Any,<:Diagonal}, B::AbstractMatrix) = (A = transA.parent; scale!(A.diag,B)) @@ -256,23 +245,19 @@ mul!(A::AbstractMatrix, transB::Transpose{<:Any,<:Diagonal}) = (B = transB.paren # Get ambiguous method if try to unify AbstractVector/AbstractMatrix here using AbstractVecOrMat mul!(out::AbstractVector, A::Diagonal, in::AbstractVector) = out .= A.diag .* in -mul!(out::AbstractVector, adjA::Adjoint{<:Any,<:Diagonal}, in::AbstractVector) = - (A = adjA.parent; out .= adjoint.(A.diag) .* in) -mul!(out::AbstractVector, transA::Transpose{<:Any,<:Diagonal}, in::AbstractVector) = - (A = transA.parent; out .= transpose.(A.diag) .* in) +mul!(out::AbstractVector, A::Adjoint{<:Any,<:Diagonal}, in::AbstractVector) = out .= adjoint.(A.parent.diag) .* in +mul!(out::AbstractVector, A::Transpose{<:Any,<:Diagonal}, in::AbstractVector) = out .= transpose.(A.parent.diag) .* in mul!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = out .= A.diag .* in -mul!(out::AbstractMatrix, adjA::Adjoint{<:Any,<:Diagonal}, in::AbstractMatrix) = - (A = adjA.parent; out .= adjoint.(A.diag) .* in) -mul!(out::AbstractMatrix, transA::Transpose{<:Any,<:Diagonal}, in::AbstractMatrix) = - (A = transA.parent; out .= transpose.(A.diag) .* in) +mul!(out::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= adjoint.(A.parent.diag) .* in +mul!(out::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= transpose.(A.parent.diag) .* in -mul!(C::AbstractMatrix, A::Diagonal, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, adjoint(B.parent)) -mul!(C::AbstractMatrix, A::Diagonal, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, transpose(B.parent)) -mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, adjoint(B.parent)) -mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, transpose(B.parent)) -mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, adjoint(B.parent)) -mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, transpose(B.parent)) +mul!(C::AbstractMatrix, A::Diagonal, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Diagonal, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) # ambiguities with Symmetric/Hermitian @@ -285,17 +270,14 @@ mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Abs *(transD::Transpose{<:Any,<:Diagonal}, transA::Transpose{<:Any,<:RealHermSymComplexSym}) = transD * transA.parent *(adjA::Adjoint{<:Any,<:RealHermSymComplexHerm}, adjD::Adjoint{<:Any,<:Diagonal}) = adjA.parent * adjD *(adjD::Adjoint{<:Any,<:Diagonal}, adjA::Adjoint{<:Any,<:RealHermSymComplexHerm}) = adjD * adjA.parent -mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:Diagonal}, adjB::Adjoint{<:Any,<:RealHermSymComplexHerm}) = - mul!(C, adjA, adjB.parent) -mul!(C::AbstractMatrix, transA::Transpose{<:Any,<:Diagonal}, transB::Transpose{<:Any,<:RealHermSymComplexSym}) = - mul!(C, transA, transB.parent) -mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:Diagonal}, adjB::Adjoint{<:Any,<:RealHermSymComplexSym}) = - (A = adjA.parent; C .= adjoint.(A.diag) .* adjB) -mul!(C::AbstractMatrix, transA::Transpose{<:Any,<:Diagonal}, transB::Transpose{<:Any,<:RealHermSymComplexHerm}) = - (A = transA.parent; C .= transpose.(A.diag) .* transB) +mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexHerm}) = mul!(C, A, B.parent) +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexSym}) = mul!(C, A, B.parent) +mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexSym}) = C .= adjoint.(A.parent.diag) .* B +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexHerm}) = C .= transpose.(A.parent.diag) .* B (/)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag ./ Db.diag) + function ldiv!(D::Diagonal{T}, v::AbstractVector{T}) where {T} if length(v) != length(D.diag) throw(DimensionMismatch("diagonal matrix is $(length(D.diag)) by $(length(D.diag)) but right hand side has $(length(v)) rows")) @@ -325,6 +307,7 @@ function ldiv!(D::Diagonal{T}, V::AbstractMatrix{T}) where {T} V end + ldiv!(adjD::Adjoint{<:Any,<:Diagonal{T}}, B::AbstractVecOrMat{T}) where {T} = (D = adjD.parent; ldiv!(conj(D), B)) ldiv!(transD::Transpose{<:Any,<:Diagonal{T}}, B::AbstractVecOrMat{T}) where {T} = @@ -348,6 +331,7 @@ function rdiv!(A::AbstractMatrix{T}, D::Diagonal{T}) where {T} A end + rdiv!(A::AbstractMatrix{T}, adjD::Adjoint{<:Any,<:Diagonal{T}}) where {T} = (D = adjD.parent; rdiv!(A, conj(D))) rdiv!(A::AbstractMatrix{T}, transD::Transpose{<:Any,<:Diagonal{T}}) where {T} = @@ -356,7 +340,7 @@ rdiv!(A::AbstractMatrix{T}, transD::Transpose{<:Any,<:Diagonal{T}}) where {T} = (\)(F::Factorization, D::Diagonal) = ldiv!(F, Matrix{typeof(oneunit(eltype(D))/oneunit(eltype(F)))}(D)) \(adjF::Adjoint{<:Any,<:Factorization}, D::Diagonal) = - (F = adjF.parent; ldiv!(Adjoint(F), Matrix{typeof(oneunit(eltype(D))/oneunit(eltype(F)))}(D))) + (F = adjF.parent; ldiv!(adjoint(F), Matrix{typeof(oneunit(eltype(D))/oneunit(eltype(F)))}(D))) conj(D::Diagonal) = Diagonal(conj(D.diag)) transpose(D::Diagonal{<:Number}) = D @@ -471,11 +455,12 @@ function svd(D::Diagonal{<:Number}) end function svdfact(D::Diagonal) U, s, V = svd(D) - SVD(U, s, adjoint(V)) + SVD(U, s, copy(V')) end # dismabiguation methods: * of Diagonal and Adj/Trans AbsVec -*(A::Diagonal, B::Adjoint{<:Any,<:AbstractVector}) = A * adjoint(B.parent) -*(A::Diagonal, B::Transpose{<:Any,<:AbstractVector}) = A * transpose(B.parent) -*(A::Adjoint{<:Any,<:AbstractVector}, B::Diagonal) = adjoint(A.parent) * B -*(A::Transpose{<:Any,<:AbstractVector}, B::Diagonal) = transpose(A.parent) * B +*(A::Diagonal, B::Adjoint{<:Any,<:AbstractVector}) = A * copy(B) +*(A::Diagonal, B::Transpose{<:Any,<:AbstractVector}) = A * copy(B) +*(A::Adjoint{<:Any,<:AbstractVector}, B::Diagonal) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractVector}, B::Diagonal) = copy(A) * B +# TODO: these methods will yield row matrices, rather than adjoint/transpose vectors diff --git a/base/linalg/factorization.jl b/base/linalg/factorization.jl index 3bef6499d1bb9..13fe9d8201da2 100644 --- a/base/linalg/factorization.jl +++ b/base/linalg/factorization.jl @@ -61,9 +61,9 @@ Base.isequal(F::T, G::T) where {T<:Factorization} = all(f -> isequal(getfield(F, # With a real lhs and complex rhs with the same precision, we can reinterpret # the complex rhs as a real rhs with twice the number of columns function (\)(F::Factorization{T}, B::VecOrMat{Complex{T}}) where T<:BlasReal - c2r = reshape(transpose(reinterpret(T, reshape(B, (1, length(B))))), size(B, 1), 2*size(B, 2)) + c2r = reshape(copy(transpose(reinterpret(T, reshape(B, (1, length(B)))))), size(B, 1), 2*size(B, 2)) x = ldiv!(F, c2r) - return reshape(collect(reinterpret(Complex{T}, transpose(reshape(x, div(length(x), 2), 2)))), _ret_size(F, B)) + return reshape(copy(reinterpret(Complex{T}, copy(transpose(reshape(x, div(length(x), 2), 2))))), _ret_size(F, B)) end function \(F::Factorization, B::AbstractVecOrMat) @@ -77,16 +77,16 @@ function \(adjF::Adjoint{<:Any,<:Factorization}, B::AbstractVecOrMat) TFB = typeof(oneunit(eltype(B)) / oneunit(eltype(F))) BB = similar(B, TFB, size(B)) copyto!(BB, B) - ldiv!(Adjoint(F), BB) + ldiv!(adjoint(F), BB) end # support the same 3-arg idiom as in our other in-place A_*_B functions: ldiv!(Y::AbstractVecOrMat, A::Factorization, B::AbstractVecOrMat) = ldiv!(A, copyto!(Y, B)) ldiv!(Y::AbstractVecOrMat, adjA::Adjoint{<:Any,<:Factorization}, B::AbstractVecOrMat) = - (A = adjA.parent; ldiv!(Adjoint(A), copyto!(Y, B))) + (A = adjA.parent; ldiv!(adjoint(A), copyto!(Y, B))) ldiv!(Y::AbstractVecOrMat, transA::Transpose{<:Any,<:Factorization}, B::AbstractVecOrMat) = - (A = transA.parent; ldiv!(Transpose(A), copyto!(Y, B))) + (A = transA.parent; ldiv!(transpose(A), copyto!(Y, B))) # fallback methods for transposed solves -\(transF::Transpose{<:Any,<:Factorization{<:Real}}, B::AbstractVecOrMat) = (F = transF.parent; \(Adjoint(F), B)) -\(transF::Transpose{<:Any,<:Factorization}, B::AbstractVecOrMat) = (F = transF.parent; conj.(\(Adjoint(F), conj.(B)))) +\(F::Transpose{<:Any,<:Factorization{<:Real}}, B::AbstractVecOrMat) = adjoint(F.parent) \ B +\(F::Transpose{<:Any,<:Factorization}, B::AbstractVecOrMat) = conj.(adjoint(F.parent) \ conj.(B)) \ No newline at end of file diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 805bc4202c066..215d8b21d189a 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -243,10 +243,11 @@ tril!(M::AbstractMatrix) = tril!(M,0) diff(a::AbstractVector) = [ a[i+1] - a[i] for i=1:length(a)-1 ] """ - diff(A, [dim::Integer=1]) + diff(A::AbstractVector) + diff(A::AbstractMatrix, dim::Integer) Finite difference operator of matrix or vector `A`. If `A` is a matrix, -compute the finite difference over a dimension `dim` (default `1`). +specify the dimension over which to operate with the `dim` argument. # Examples ```jldoctest @@ -259,9 +260,15 @@ julia> diff(a,2) 2×1 Array{Int64,2}: 2 10 + +julia> diff(vec(a)) +3-element Array{Int64,1}: + 4 + -2 + 12 ``` """ -function diff(A::AbstractMatrix, dim::Integer=1) +function diff(A::AbstractMatrix, dim::Integer) if dim == 1 [A[i+1,j] - A[i,j] for i=1:size(A,1)-1, j=1:size(A,2)] elseif dim == 2 @@ -816,9 +823,9 @@ function inv(A::AbstractMatrix{T}) where T ldiv!(factorize(convert(AbstractMatrix{S}, A)), dest) end -pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Real} = _vectorpinv(Transpose, v, tol) -pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Complex} = _vectorpinv(Adjoint, v, tol) -pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T} = _vectorpinv(Adjoint, v, tol) +pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Real} = _vectorpinv(transpose, v, tol) +pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Complex} = _vectorpinv(adjoint, v, tol) +pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T} = _vectorpinv(adjoint, v, tol) function _vectorpinv(dualfn::Tf, v::AbstractVector{Tv}, tol) where {Tv,Tf} res = dualfn(similar(v, typeof(zero(Tv) / (abs2(one(Tv)) + abs2(one(Tv)))))) den = sum(abs2, v) @@ -885,7 +892,7 @@ function (\)(A::AbstractMatrix, B::AbstractVecOrMat) end (\)(a::AbstractVector, b::AbstractArray) = pinv(a) * b -(/)(A::AbstractVecOrMat, B::AbstractVecOrMat) = adjoint(Adjoint(B) \ Adjoint(A)) +(/)(A::AbstractVecOrMat, B::AbstractVecOrMat) = copy(adjoint(adjoint(B) \ adjoint(A))) # \(A::StridedMatrix,x::Number) = inv(A)*x Should be added at some point when the old elementwise version has been deprecated long enough # /(x::Number,A::StridedMatrix) = x*inv(A) /(x::Number, v::AbstractVector) = x*pinv(v) diff --git a/base/linalg/givens.jl b/base/linalg/givens.jl index daa3cebb0416d..5b5648a30838c 100644 --- a/base/linalg/givens.jl +++ b/base/linalg/givens.jl @@ -7,14 +7,14 @@ transpose(R::AbstractRotation) = error("transpose not implemented for $(typeof(R function *(R::AbstractRotation{T}, A::AbstractVecOrMat{S}) where {T,S} TS = typeof(zero(T)*zero(S) + zero(T)*zero(S)) - mul!(convert(AbstractRotation{TS}, R), TS == S ? copy(A) : convert(AbstractArray{TS}, A)) + mul2!(convert(AbstractRotation{TS}, R), TS == S ? copy(A) : convert(AbstractArray{TS}, A)) end *(A::AbstractVector, adjR::Adjoint{<:Any,<:AbstractRotation}) = _absvecormat_mul_adjrot(A, adjR) *(A::AbstractMatrix, adjR::Adjoint{<:Any,<:AbstractRotation}) = _absvecormat_mul_adjrot(A, adjR) function _absvecormat_mul_adjrot(A::AbstractVecOrMat{T}, adjR::Adjoint{<:Any,<:AbstractRotation{S}}) where {T,S} R = adjR.parent TS = typeof(zero(T)*zero(S) + zero(T)*zero(S)) - mul!(TS == T ? copy(A) : convert(AbstractArray{TS}, A), Adjoint(convert(AbstractRotation{TS}, R))) + mul1!(TS == T ? copy(A) : convert(AbstractArray{TS}, A), adjoint(convert(AbstractRotation{TS}, R))) end """ LinAlg.Givens(i1,i2,c,s) -> G @@ -47,8 +47,10 @@ Rotation{T}(R::Rotation) where {T} = Rotation{T}([Givens{T}(g) for g in R.rotati AbstractRotation{T}(G::Givens) where {T} = Givens{T}(G) AbstractRotation{T}(R::Rotation) where {T} = Rotation{T}(R) -adjoint(G::Givens) = Givens(G.i1, G.i2, conj(G.c), -G.s) -adjoint(R::Rotation{T}) where {T} = Rotation{T}(reverse!([adjoint(r) for r in R.rotations])) +adjoint(G::Givens) = Adjoint(G) +adjoint(R::Rotation) = Adjoint(R) +Base.copy(aG::Adjoint{<:Any,<:Givens}) = (G = aG.parent; Givens(G.i1, G.i2, conj(G.c), -G.s)) +Base.copy(aR::Adjoint{<:Any,Rotation{T}}) where {T} = Rotation{T}(reverse!([copy(r') for r in aR.parent.rotations])) realmin2(::Type{Float32}) = reinterpret(Float32, 0x26000000) realmin2(::Type{Float64}) = reinterpret(Float64, 0x21a0000000000000) @@ -323,10 +325,7 @@ function getindex(G::Givens, i::Integer, j::Integer) end end - -mul!(G1::Givens, G2::Givens) = error("Operation not supported. Consider *") - -function mul!(G::Givens, A::AbstractVecOrMat) +function mul2!(G::Givens, A::AbstractVecOrMat) m, n = size(A, 1), size(A, 2) if G.i2 > m throw(DimensionMismatch("column indices for rotation are outside the matrix")) @@ -338,7 +337,7 @@ function mul!(G::Givens, A::AbstractVecOrMat) end return A end -function mul!(A::AbstractMatrix, adjG::Adjoint{<:Any,<:Givens}) +function mul1!(A::AbstractMatrix, adjG::Adjoint{<:Any,<:Givens}) G = adjG.parent m, n = size(A, 1), size(A, 2) if G.i2 > n @@ -351,46 +350,39 @@ function mul!(A::AbstractMatrix, adjG::Adjoint{<:Any,<:Givens}) end return A end -function mul!(G::Givens, R::Rotation) + +function mul2!(G::Givens, R::Rotation) push!(R.rotations, G) return R end -function mul!(R::Rotation, A::AbstractMatrix) +function mul2!(R::Rotation, A::AbstractMatrix) @inbounds for i = 1:length(R.rotations) - mul!(R.rotations[i], A) + mul2!(R.rotations[i], A) end return A end -function mul!(A::AbstractMatrix, adjR::Adjoint{<:Any,<:Rotation}) +function mul1!(A::AbstractMatrix, adjR::Adjoint{<:Any,<:Rotation}) R = adjR.parent @inbounds for i = 1:length(R.rotations) - mul!(A, Adjoint(R.rotations[i])) + mul1!(A, adjoint(R.rotations[i])) end return A end *(G1::Givens{T}, G2::Givens{T}) where {T} = Rotation(push!(push!(Givens{T}[], G2), G1)) +# TODO: None of the following disambiguation methods are great. They should perhaps +# instead be MethodErrors, or revised. +# # dismabiguation methods: *(Adj/Trans of AbsVec or AbsMat, Adj of AbstractRotation) -*(A::Adjoint{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractRotation}) = adjoint(A.parent) * B -*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractRotation}) = adjoint(A.parent) * B -*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractRotation}) = transpose(A.parent) * B -*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractRotation}) = transpose(A.parent) * B +*(A::Adjoint{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B +*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B # dismabiguation methods: *(Adj/Trans of AbsTri or RealHermSymComplex{Herm|Sym}, Adj of AbstractRotation) -*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractRotation}) = adjoint(A.parent) * B -*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractRotation}) = transpose(A.parent) * B -*(A::Adjoint{<:Any,<:RealHermSymComplexHerm}, B::Adjoint{<:Any,<:AbstractRotation}) = A.parent * B -*(A::Transpose{<:Any,<:RealHermSymComplexSym}, B::Adjoint{<:Any,<:AbstractRotation}) = A.parent * B -# dismabiguation methods: *(Diag/RowVec/AbsTri, Adj of AbstractRotation) -*(A::Diagonal, B::Adjoint{<:Any,<:AbstractRotation}) = A * adjoint(B.parent) -*(A::AbstractTriangular, B::Adjoint{<:Any,<:AbstractRotation}) = A * adjoint(B.parent) -# moar disambiguation -mul!(A::QRPackedQ, B::Adjoint{<:Any,<:Givens}) = throw(MethodError(mul!, (A, B))) -mul!(A::QRPackedQ, B::Adjoint{<:Any,<:Rotation}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:QRPackedQ}, B::Adjoint{<:Any,<:Givens}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:QRPackedQ}, B::Adjoint{<:Any,<:Rotation}) = throw(MethodError(mul!, (A, B))) -mul!(A::Diagonal, B::Adjoint{<:Any,<:Givens}) = throw(MethodError(mul!, (A, B))) -mul!(A::Diagonal, B::Adjoint{<:Any,<:Rotation}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Givens}) = throw(MethodError(mul!, (A, B))) -mul!(A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Rotation}) = throw(MethodError(mul!, (A, B))) -mul!(A::Transpose{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Rotation}) = throw(MethodError(mul!, (A, B))) -mul!(A::Transpose{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Givens}) = throw(MethodError(mul!, (A, B))) +*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B +*(A::Adjoint{<:Any,<:RealHermSymComplexHerm}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B +*(A::Transpose{<:Any,<:RealHermSymComplexSym}, B::Adjoint{<:Any,<:AbstractRotation}) = copy(A) * B +# dismabiguation methods: *(Diag/AbsTri, Adj of AbstractRotation) +*(A::Diagonal, B::Adjoint{<:Any,<:AbstractRotation}) = A * copy(B) +*(A::AbstractTriangular, B::Adjoint{<:Any,<:AbstractRotation}) = A * copy(B) diff --git a/base/linalg/hessenberg.jl b/base/linalg/hessenberg.jl index f9c0520e78b07..8ba45b75a10a3 100644 --- a/base/linalg/hessenberg.jl +++ b/base/linalg/hessenberg.jl @@ -71,7 +71,7 @@ function getindex(A::HessenbergQ, i::Integer, j::Integer) x[i] = 1 y = zeros(eltype(A), size(A, 2)) y[j] = 1 - return dot(x, mul!(A, y)) + return dot(x, mul2!(A, y)) end ## reconstruct the original matrix @@ -82,31 +82,30 @@ AbstractArray(F::Hessenberg) = AbstractMatrix(F) Matrix(F::Hessenberg) = Array(AbstractArray(F)) Array(F::Hessenberg) = Matrix(F) -mul!(Q::HessenbergQ{T}, X::StridedVecOrMat{T}) where {T<:BlasFloat} = +mul2!(Q::HessenbergQ{T}, X::StridedVecOrMat{T}) where {T<:BlasFloat} = LAPACK.ormhr!('L', 'N', 1, size(Q.factors, 1), Q.factors, Q.τ, X) -mul!(X::StridedMatrix{T}, Q::HessenbergQ{T}) where {T<:BlasFloat} = +mul1!(X::StridedMatrix{T}, Q::HessenbergQ{T}) where {T<:BlasFloat} = LAPACK.ormhr!('R', 'N', 1, size(Q.factors, 1), Q.factors, Q.τ, X) -mul!(adjQ::Adjoint{<:Any,<:HessenbergQ{T}}, X::StridedVecOrMat{T}) where {T<:BlasFloat} = +mul2!(adjQ::Adjoint{<:Any,<:HessenbergQ{T}}, X::StridedVecOrMat{T}) where {T<:BlasFloat} = (Q = adjQ.parent; LAPACK.ormhr!('L', ifelse(T<:Real, 'T', 'C'), 1, size(Q.factors, 1), Q.factors, Q.τ, X)) -mul!(X::StridedMatrix{T}, adjQ::Adjoint{<:Any,<:HessenbergQ{T}}) where {T<:BlasFloat} = +mul1!(X::StridedMatrix{T}, adjQ::Adjoint{<:Any,<:HessenbergQ{T}}) where {T<:BlasFloat} = (Q = adjQ.parent; LAPACK.ormhr!('R', ifelse(T<:Real, 'T', 'C'), 1, size(Q.factors, 1), Q.factors, Q.τ, X)) - function (*)(Q::HessenbergQ{T}, X::StridedVecOrMat{S}) where {T,S} TT = typeof(zero(T)*zero(S) + zero(T)*zero(S)) - return mul!(Q, copy_oftype(X, TT)) + return mul2!(Q, copy_oftype(X, TT)) end function (*)(X::StridedVecOrMat{S}, Q::HessenbergQ{T}) where {T,S} TT = typeof(zero(T)*zero(S) + zero(T)*zero(S)) - return mul!(copy_oftype(X, TT), Q) + return mul1!(copy_oftype(X, TT), Q) end function *(adjQ::Adjoint{<:Any,<:HessenbergQ{T}}, X::StridedVecOrMat{S}) where {T,S} Q = adjQ.parent TT = typeof(zero(T)*zero(S) + zero(T)*zero(S)) - return mul!(Adjoint(Q), copy_oftype(X, TT)) + return mul2!(adjoint(Q), copy_oftype(X, TT)) end function *(X::StridedVecOrMat{S}, adjQ::Adjoint{<:Any,<:HessenbergQ{T}}) where {T,S} Q = adjQ.parent TT = typeof(zero(T)*zero(S) + zero(T)*zero(S)) - return mul!(copy_oftype(X, TT), Adjoint(Q)) + return mul1!(copy_oftype(X, TT), adjoint(Q)) end diff --git a/base/linalg/lapack.jl b/base/linalg/lapack.jl index 93d8fe662e4a7..27141c6c8ae25 100644 --- a/base/linalg/lapack.jl +++ b/base/linalg/lapack.jl @@ -973,7 +973,7 @@ end """ gels!(trans, A, B) -> (F, B, ssr) -Solves the linear equation `A * X = B`, `Transpose(A) * X = B`, or `Adjoint(A) * X = B` using +Solves the linear equation `A * X = B`, `transpose(A) * X = B`, or `adjoint(A) * X = B` using a QR or LQ factorization. Modifies the matrix/vector `B` in place with the solution. `A` is overwritten with its `QR` or `LQ` factorization. `trans` may be one of `N` (no modification), `T` (transpose), or `C` (conjugate @@ -995,7 +995,7 @@ gesv!(A::AbstractMatrix, B::AbstractVecOrMat) """ getrs!(trans, A, ipiv, B) -Solves the linear equation `A * X = B`, `Transpose(A) * X = B`, or `Adjoint(A) * X = B` for +Solves the linear equation `A * X = B`, `transpose(A) * X = B`, or `adjoint(A) * X = B` for square `A`. Modifies the matrix/vector `B` in place with the solution. `A` is the `LU` factorization from `getrf!`, with `ipiv` the pivoting information. `trans` may be one of `N` (no modification), `T` (transpose), @@ -1156,8 +1156,8 @@ end """ gesvx!(fact, trans, A, AF, ipiv, equed, R, C, B) -> (X, equed, R, C, B, rcond, ferr, berr, work) -Solves the linear equation `A * X = B` (`trans = N`), `Transpose(A) * X = B` -(`trans = T`), or `Adjoint(A) * X = B` (`trans = C`) using the `LU` factorization +Solves the linear equation `A * X = B` (`trans = N`), `transpose(A) * X = B` +(`trans = T`), or `adjoint(A) * X = B` (`trans = C`) using the `LU` factorization of `A`. `fact` may be `E`, in which case `A` will be equilibrated and copied to `AF`; `F`, in which case `AF` and `ipiv` from a previous `LU` factorization are inputs; or `N`, in which case `A` will be copied to `AF` and then @@ -2437,8 +2437,8 @@ gttrf!(dl::AbstractVector, d::AbstractVector, du::AbstractVector) """ gttrs!(trans, dl, d, du, du2, ipiv, B) -Solves the equation `A * X = B` (`trans = N`), `Transpose(A) * X = B` (`trans = T`), -or `Adjoint(A) * X = B` (`trans = C`) using the `LU` factorization computed by +Solves the equation `A * X = B` (`trans = N`), `transpose(A) * X = B` (`trans = T`), +or `adjoint(A) * X = B` (`trans = C`) using the `LU` factorization computed by `gttrf!`. `B` is overwritten with the solution `X`. """ gttrs!(trans::Char, dl::AbstractVector, d::AbstractVector, du::AbstractVector, du2::AbstractVector, @@ -2867,7 +2867,7 @@ orgrq!(A::AbstractMatrix, tau::AbstractVector, k::Integer = length(tau)) """ ormlq!(side, trans, A, tau, C) -Computes `Q * C` (`trans = N`), `Transpose(Q) * C` (`trans = T`), `Adjoint(Q) * C` +Computes `Q * C` (`trans = N`), `transpose(Q) * C` (`trans = T`), `adjoint(Q) * C` (`trans = C`) for `side = L` or the equivalent right-sided multiplication for `side = R` using `Q` from a `LQ` factorization of `A` computed using `gelqf!`. `C` is overwritten. @@ -2877,7 +2877,7 @@ ormlq!(side::Char, trans::Char, A::AbstractMatrix, tau::AbstractVector, C::Abstr """ ormqr!(side, trans, A, tau, C) -Computes `Q * C` (`trans = N`), `Transpose(Q) * C` (`trans = T`), `Adjoint(Q) * C` +Computes `Q * C` (`trans = N`), `transpose(Q) * C` (`trans = T`), `adjoint(Q) * C` (`trans = C`) for `side = L` or the equivalent right-sided multiplication for `side = R` using `Q` from a `QR` factorization of `A` computed using `geqrf!`. `C` is overwritten. @@ -2887,7 +2887,7 @@ ormqr!(side::Char, trans::Char, A::AbstractMatrix, tau::AbstractVector, C::Abstr """ ormql!(side, trans, A, tau, C) -Computes `Q * C` (`trans = N`), `Transpose(Q) * C` (`trans = T`), `Adjoint(Q) * C` +Computes `Q * C` (`trans = N`), `transpose(Q) * C` (`trans = T`), `adjoint(Q) * C` (`trans = C`) for `side = L` or the equivalent right-sided multiplication for `side = R` using `Q` from a `QL` factorization of `A` computed using `geqlf!`. `C` is overwritten. @@ -2897,7 +2897,7 @@ ormql!(side::Char, trans::Char, A::AbstractMatrix, tau::AbstractVector, C::Abstr """ ormrq!(side, trans, A, tau, C) -Computes `Q * C` (`trans = N`), `Transpose(Q) * C` (`trans = T`), `Adjoint(Q) * C` +Computes `Q * C` (`trans = N`), `transpose(Q) * C` (`trans = T`), `adjoint(Q) * C` (`trans = C`) for `side = L` or the equivalent right-sided multiplication for `side = R` using `Q` from a `RQ` factorization of `A` computed using `gerqf!`. `C` is overwritten. @@ -2907,7 +2907,7 @@ ormrq!(side::Char, trans::Char, A::AbstractMatrix, tau::AbstractVector, C::Abstr """ gemqrt!(side, trans, V, T, C) -Computes `Q * C` (`trans = N`), `Transpose(Q) * C` (`trans = T`), `Adjoint(Q) * C` +Computes `Q * C` (`trans = N`), `transpose(Q) * C` (`trans = T`), `adjoint(Q) * C` (`trans = C`) for `side = L` or the equivalent right-sided multiplication for `side = R` using `Q` from a `QR` factorization of `A` computed using `geqrt!`. `C` is overwritten. @@ -3307,8 +3307,8 @@ trtri!(uplo::Char, diag::Char, A::AbstractMatrix) """ trtrs!(uplo, trans, diag, A, B) -Solves `A * X = B` (`trans = N`), `Transpose(A) * X = B` (`trans = T`), or -`Adjoint(A) * X = B` (`trans = C`) for (upper if `uplo = U`, lower if `uplo = L`) +Solves `A * X = B` (`trans = N`), `transpose(A) * X = B` (`trans = T`), or +`adjoint(A) * X = B` (`trans = C`) for (upper if `uplo = U`, lower if `uplo = L`) triangular matrix `A`. If `diag = N`, `A` has non-unit diagonal elements. If `diag = U`, all diagonal elements of `A` are one. `B` is overwritten with the solution `X`. @@ -3604,7 +3604,7 @@ trevc!(side::Char, howmny::Char, select::AbstractVector{BlasInt}, T::AbstractMat trrfs!(uplo, trans, diag, A, B, X, Ferr, Berr) -> (Ferr, Berr) Estimates the error in the solution to `A * X = B` (`trans = N`), -`Transpose(A) * X = B` (`trans = T`), `Adjoint(A) * X = B` (`trans = C`) for `side = L`, +`transpose(A) * X = B` (`trans = T`), `adjoint(A) * X = B` (`trans = C`) for `side = L`, or the equivalent equations a right-handed `side = R` `X * A` after computing `X` using `trtrs!`. If `uplo = U`, `A` is upper triangular. If `uplo = L`, `A` is lower triangular. If `diag = N`, `A` has non-unit @@ -3759,7 +3759,7 @@ for (stev, stebz, stegr, stein, elty) in chklapackerror(info[]) if any(ifail .!= 0) # TODO: better error message / type - error("failed to converge eigenvectors:\n$(nonzeros(ifail))") + error("failed to converge eigenvectors:\n$(find(!iszero, ifail))") end z end diff --git a/base/linalg/linalg.jl b/base/linalg/linalg.jl index 99d308b764426..3e774211bdd90 100644 --- a/base/linalg/linalg.jl +++ b/base/linalg/linalg.jl @@ -238,11 +238,9 @@ function char_uplo(uplo::Symbol) end """ - ldiv!([Y,] A, B) -> Y + ldiv!(Y, A, B) -> Y Compute `A \\ B` in-place and store the result in `Y`, returning the result. -If only two arguments are passed, then `ldiv!(A, B)` overwrites `B` with -the result. The argument `A` should *not* be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by [`factorize`](@ref) or [`cholfact`](@ref)). @@ -254,11 +252,24 @@ control over the factorization of `A`. ldiv!(Y, A, B) """ - rdiv!([Y,] A, B) -> Y + ldiv!(A, B) -Compute `A / B` in-place and store the result in `Y`, returning the result. -If only two arguments are passed, then `rdiv!(A, B)` overwrites `A` with -the result. +Compute `A \\ B` in-place and overwriting `B` to store the result. + +The argument `A` should *not* be a matrix. Rather, instead of matrices it should be a +factorization object (e.g. produced by [`factorize`](@ref) or [`cholfact`](@ref)). +The reason for this is that factorization itself is both expensive and typically allocates memory +(although it can also be done in-place via, e.g., [`lufact!`](@ref)), +and performance-critical situations requiring `ldiv!` usually also require fine-grained +control over the factorization of `A`. +""" +ldiv!(A, B) + + +""" + rdiv!(A, B) + +Compute `A / B` in-place and overwriting `A` to store the result. The argument `B` should *not* be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by [`factorize`](@ref) or [`cholfact`](@ref)). @@ -267,7 +278,7 @@ The reason for this is that factorization itself is both expensive and typically and performance-critical situations requiring `rdiv!` usually also require fine-grained control over the factorization of `B`. """ -rdiv!(Y, A, B) +rdiv!(A, B) copy_oftype(A::AbstractArray{T}, ::Type{T}) where {T} = copy(A) copy_oftype(A::AbstractArray{T,N}, ::Type{S}) where {T,N,S} = convert(AbstractArray{S,N}, A) diff --git a/base/linalg/lq.jl b/base/linalg/lq.jl index a080151b1de2c..685f78d52c6c0 100644 --- a/base/linalg/lq.jl +++ b/base/linalg/lq.jl @@ -37,7 +37,7 @@ lqfact(x::Number) = lqfact(fill(x,1,1)) Perform an LQ factorization of `A` such that `A = L*Q`. The default (`full = false`) computes a factorization with possibly-rectangular `L` and `Q`, commonly the "thin" -factorization. The LQ factorization is the QR factorization of `Transpose(A)`. If the explicit, +factorization. The LQ factorization is the QR factorization of `transpose(A)`. If the explicit, full/square form of `Q` is requested via `full = true`, `L` is not extended with zeros. !!! note @@ -57,7 +57,7 @@ function lq(A::Union{Number,AbstractMatrix}; full::Bool = false, thin::Union{Boo end F = lqfact(A) L, Q = F.L, F.Q - return L, !full ? Array(Q) : mul!(Q, Matrix{eltype(Q)}(I, size(Q.factors, 2), size(Q.factors, 2))) + return L, !full ? Array(Q) : mul2!(Q, Matrix{eltype(Q)}(I, size(Q.factors, 2), size(Q.factors, 2))) end copy(A::LQ) = LQ(copy(A.factors), copy(A.τ)) @@ -70,7 +70,9 @@ AbstractArray(A::LQ) = AbstractMatrix(A) Matrix(A::LQ) = Array(AbstractArray(A)) Array(A::LQ) = Matrix(A) -adjoint(A::LQ{T}) where {T} = QR{T,typeof(A.factors)}(adjoint(A.factors), A.τ) +adjoint(A::LQ) = Adjoint(A) +Base.copy(F::Adjoint{T,<:LQ{T}}) where {T} = + QR{T,typeof(F.parent.factors)}(copy(adjoint(F.parent.factors)), copy(F.parent.τ)) function getproperty(F::LQ, d::Symbol) m, n = size(F) @@ -84,7 +86,7 @@ function getproperty(F::LQ, d::Symbol) end getindex(A::LQPackedQ, i::Integer, j::Integer) = - mul!(A, setindex!(zeros(eltype(A), size(A, 2)), 1, j))[i] + mul2!(A, setindex!(zeros(eltype(A), size(A, 2)), 1, j))[i] function show(io::IO, C::LQ) println(io, "$(typeof(C)) with factors L and Q:") @@ -118,47 +120,34 @@ end ## Multiplication by LQ -mul!(A::LQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} = - A.L * LAPACK.ormlq!('L', 'N', A.factors, A.τ, B) -mul!(A::LQ{T}, B::QR{T}) where {T<:BlasFloat} = - A.L * LAPACK.ormlq!('L', 'N', A.factors, A.τ, Matrix(B)) -mul!(A::QR{T}, B::LQ{T}) where {T<:BlasFloat} = - mul!(zeros(eltype(A), size(A)), Matrix(A), Matrix(B)) +mul2!(A::LQ, B::StridedVecOrMat) = + mul2!(LowerTriangular(A.L), mul2!(A.Q, B)) function *(A::LQ{TA}, B::StridedVecOrMat{TB}) where {TA,TB} TAB = promote_type(TA, TB) - mul!(Factorization{TAB}(A), copy_oftype(B, TAB)) + mul2!(Factorization{TAB}(A), copy_oftype(B, TAB)) end -function *(A::LQ{TA},B::QR{TB}) where {TA,TB} - TAB = promote_type(TA, TB) - mul!(Factorization{TAB}(A), Factorization{TAB}(B)) -end -function *(A::QR{TA},B::LQ{TB}) where {TA,TB} - TAB = promote_type(TA, TB) - mul!(Factorization{TAB}(A), Factorization{TAB}(B)) -end -*(A::Adjoint{<:Any,<:LQ}, B::LQ) = adjoint(A.parent) * B -*(A::LQ, B::Adjoint{<:Any,<:LQ}) = A * adjoint(B.parent) ## Multiplication by Q ### QB -mul!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} = LAPACK.ormlq!('L','N',A.factors,A.τ,B) +mul2!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} = LAPACK.ormlq!('L','N',A.factors,A.τ,B) function (*)(A::LQPackedQ, B::StridedVecOrMat) TAB = promote_type(eltype(A), eltype(B)) - mul!(AbstractMatrix{TAB}(A), copy_oftype(B, TAB)) + mul2!(AbstractMatrix{TAB}(A), copy_oftype(B, TAB)) end ### QcB -mul!(adjA::Adjoint{<:Any,<:LQPackedQ{T}}, B::StridedVecOrMat{T}) where {T<:BlasReal} = +mul2!(adjA::Adjoint{<:Any,<:LQPackedQ{T}}, B::StridedVecOrMat{T}) where {T<:BlasReal} = (A = adjA.parent; LAPACK.ormlq!('L','T',A.factors,A.τ,B)) -mul!(adjA::Adjoint{<:Any,<:LQPackedQ{T}}, B::StridedVecOrMat{T}) where {T<:BlasComplex} = +mul2!(adjA::Adjoint{<:Any,<:LQPackedQ{T}}, B::StridedVecOrMat{T}) where {T<:BlasComplex} = (A = adjA.parent; LAPACK.ormlq!('L','C',A.factors,A.τ,B)) + function *(adjA::Adjoint{<:Any,<:LQPackedQ}, B::StridedVecOrMat) A = adjA.parent TAB = promote_type(eltype(A), eltype(B)) if size(B,1) == size(A.factors,2) - mul!(Adjoint(AbstractMatrix{TAB}(A)), copy_oftype(B, TAB)) + mul2!(adjoint(AbstractMatrix{TAB}(A)), copy_oftype(B, TAB)) elseif size(B,1) == size(A.factors,1) - mul!(Adjoint(AbstractMatrix{TAB}(A)), [B; zeros(TAB, size(A.factors, 2) - size(A.factors, 1), size(B, 2))]) + mul2!(adjoint(AbstractMatrix{TAB}(A)), [B; zeros(TAB, size(A.factors, 2) - size(A.factors, 1), size(B, 2))]) else throw(DimensionMismatch("first dimension of B, $(size(B,1)), must equal one of the dimensions of A, $(size(A))")) end @@ -170,14 +159,14 @@ function *(A::LQPackedQ, adjB::Adjoint{<:Any,<:StridedVecOrMat}) TAB = promote_type(eltype(A), eltype(B)) BB = similar(B, TAB, (size(B, 2), size(B, 1))) adjoint!(BB, B) - return mul!(A, BB) + return mul2!(A, BB) end function *(adjA::Adjoint{<:Any,<:LQPackedQ}, adjB::Adjoint{<:Any,<:StridedVecOrMat}) A, B = adjA.parent, adjB.parent TAB = promote_type(eltype(A), eltype(B)) BB = similar(B, TAB, (size(B, 2), size(B, 1))) adjoint!(BB, B) - return mul!(Adjoint(A), BB) + return mul2!(adjoint(A), BB) end # in-place right-application of LQPackedQs @@ -185,11 +174,11 @@ end # match the number of columns (nQ) of the LQPackedQ (Q) (necessary for in-place # operation, and the underlying LAPACK routine (ormlq) treats the implicit Q # as its (nQ-by-nQ) square form) -mul!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasFloat} = +mul1!(A::StridedMatrix{T}, B::LQPackedQ{T}) where {T<:BlasFloat} = LAPACK.ormlq!('R', 'N', B.factors, B.τ, A) -mul!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:LQPackedQ{T}}) where {T<:BlasReal} = +mul1!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:LQPackedQ{T}}) where {T<:BlasReal} = (B = adjB.parent; LAPACK.ormlq!('R', 'T', B.factors, B.τ, A)) -mul!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:LQPackedQ{T}}) where {T<:BlasComplex} = +mul1!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:LQPackedQ{T}}) where {T<:BlasComplex} = (B = adjB.parent; LAPACK.ormlq!('R', 'C', B.factors, B.τ, A)) # out-of-place right application of LQPackedQs @@ -207,13 +196,13 @@ mul!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:LQPackedQ{T}}) where {T<:BlasCom function *(A::StridedVecOrMat, adjQ::Adjoint{<:Any,<:LQPackedQ}) Q = adjQ.parent TR = promote_type(eltype(A), eltype(Q)) - return mul!(copy_oftype(A, TR), Adjoint(AbstractMatrix{TR}(Q))) + return mul1!(copy_oftype(A, TR), adjoint(AbstractMatrix{TR}(Q))) end function *(adjA::Adjoint{<:Any,<:StridedMatrix}, adjQ::Adjoint{<:Any,<:LQPackedQ}) A, Q = adjA.parent, adjQ.parent TR = promote_type(eltype(A), eltype(Q)) C = adjoint!(similar(A, TR, reverse(size(A))), A) - return mul!(C, Adjoint(AbstractMatrix{TR}(Q))) + return mul1!(C, adjoint(AbstractMatrix{TR}(Q))) end # # (2) the inner dimension in the multiplication is the LQPackedQ's first dimension. @@ -238,7 +227,7 @@ function *(A::StridedVecOrMat, Q::LQPackedQ) else _rightappdimmismatch("columns") end - return mul!(C, AbstractMatrix{TR}(Q)) + return mul1!(C, AbstractMatrix{TR}(Q)) end function *(adjA::Adjoint{<:Any,<:StridedMatrix}, Q::LQPackedQ) A = adjA.parent @@ -251,7 +240,7 @@ function *(adjA::Adjoint{<:Any,<:StridedMatrix}, Q::LQPackedQ) else _rightappdimmismatch("rows") end - return mul!(C, AbstractMatrix{TR}(Q)) + return mul1!(C, AbstractMatrix{TR}(Q)) end _rightappdimmismatch(rowsorcols) = throw(DimensionMismatch(string("the number of $(rowsorcols) of the matrix on the left ", @@ -279,14 +268,14 @@ end # With a real lhs and complex rhs with the same precision, we can reinterpret # the complex rhs as a real rhs with twice the number of columns function (\)(F::LQ{T}, B::VecOrMat{Complex{T}}) where T<:BlasReal - c2r = reshape(transpose(reinterpret(T, reshape(B, (1, length(B))))), size(B, 1), 2*size(B, 2)) + c2r = reshape(copy(transpose(reinterpret(T, reshape(B, (1, length(B)))))), size(B, 1), 2*size(B, 2)) x = ldiv!(F, c2r) - return reshape(collect(reinterpret(Complex{T}, transpose(reshape(x, div(length(x), 2), 2)))), + return reshape(copy(reinterpret(Complex{T}, copy(transpose(reshape(x, div(length(x), 2), 2))))), isa(B, AbstractVector) ? (size(F,2),) : (size(F,2), size(B,2))) end function ldiv!(A::LQ{T}, B::StridedVecOrMat{T}) where T - mul!(Adjoint(A.Q), ldiv!(LowerTriangular(A.L),B)) + mul2!(adjoint(A.Q), ldiv!(LowerTriangular(A.L),B)) return B end diff --git a/base/linalg/lu.jl b/base/linalg/lu.jl index 8c391b8292607..c38340afe5066 100644 --- a/base/linalg/lu.jl +++ b/base/linalg/lu.jl @@ -11,6 +11,9 @@ struct LU{T,S<:AbstractMatrix} <: Factorization{T} end LU(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) where {T} = LU{T,typeof(factors)}(factors, ipiv, info) +adjoint(F::LU) = Adjoint(F) +transpose(F::LU) = Transpose(F) + # StridedMatrix function lufact!(A::StridedMatrix{T}, pivot::Union{Val{false}, Val{true}} = Val(true)) where T<:BlasFloat if pivot === Val(false) @@ -315,36 +318,27 @@ ldiv!(transA::Transpose{T,<:LU{T,<:StridedMatrix}}, B::StridedVecOrMat{T}) where function ldiv!(transA::Transpose{<:Any,<:LU{<:Any,<:StridedMatrix}}, B::StridedVecOrMat) A = transA.parent - ldiv!(Transpose(UnitLowerTriangular(A.factors)), ldiv!(Transpose(UpperTriangular(A.factors)), B)) + ldiv!(transpose(UnitLowerTriangular(A.factors)), ldiv!(transpose(UpperTriangular(A.factors)), B)) _apply_inverse_ipiv!(A, B) end ldiv!(adjF::Adjoint{T,<:LU{T,<:StridedMatrix}}, B::StridedVecOrMat{T}) where {T<:Real} = - (F = adjF.parent; ldiv!(Transpose(F), B)) + (F = adjF.parent; ldiv!(transpose(F), B)) ldiv!(adjA::Adjoint{T,<:LU{T,<:StridedMatrix}}, B::StridedVecOrMat{T}) where {T<:BlasComplex} = (A = adjA.parent; @assertnonsingular(LAPACK.getrs!('C', A.factors, A.ipiv, B), A.info)) function ldiv!(adjA::Adjoint{<:Any,<:LU{<:Any,<:StridedMatrix}}, B::StridedVecOrMat) A = adjA.parent - ldiv!(Adjoint(UnitLowerTriangular(A.factors)), ldiv!(Adjoint(UpperTriangular(A.factors)), B)) + ldiv!(adjoint(UnitLowerTriangular(A.factors)), ldiv!(adjoint(UpperTriangular(A.factors)), B)) _apply_inverse_ipiv!(A, B) end -function \(transA::Transpose{T,<:LU{T,<:StridedMatrix}}, - transB::Transpose{T,<:StridedVecOrMat{T}}) where {T<:BlasFloat} - A, B = transA.parent, transB.parent - @assertnonsingular LAPACK.getrs!('T', A.factors, A.ipiv, transpose(B)) A.info -end -\(transA::Transpose{<:Any,<:LU}, transB::Transpose{<:Any,<:StridedVecOrMat}) = - (A = transA.parent; B = transB.parent; \(Transpose(A), transpose(B))) - -function \(adjA::Adjoint{T,<:LU{T,<:StridedMatrix}}, - adjB::Adjoint{T,<:StridedVecOrMat{T}}) where {T<:BlasComplex} - A, B = adjA.parent, adjB.parent - @assertnonsingular LAPACK.getrs!('C', A.factors, A.ipiv, adjoint(B)) A.info -end -\(adjA::Adjoint{<:Any,<:LU}, adjB::Adjoint{<:Any,<:StridedVecOrMat}) = - (A = adjA.parent; B = adjB.parent; \(Adjoint(A), adjoint(B))) +\(A::Adjoint{<:Any,<:LU}, B::Adjoint{<:Any,<:StridedVecOrMat}) = A \ copy(B) +\(A::Transpose{<:Any,<:LU}, B::Transpose{<:Any,<:StridedVecOrMat}) = A \ copy(B) +\(A::Adjoint{T,<:LU{T,<:StridedMatrix}}, B::Adjoint{T,<:StridedVecOrMat{T}}) where {T<:BlasComplex} = + @assertnonsingular LAPACK.getrs!('C', A.parent.factors, A.parent.ipiv, copy(B)) A.parent.info +\(A::Transpose{T,<:LU{T,<:StridedMatrix}}, B::Transpose{T,<:StridedVecOrMat{T}}) where {T<:BlasFloat} = + @assertnonsingular LAPACK.getrs!('T', A.parent.factors, A.parent.ipiv, copy(B)) A.parent.info function det(F::LU{T}) where T n = checksquare(F) @@ -590,7 +584,7 @@ function ldiv!(adjA::Adjoint{<:Any,LU{T,Tridiagonal{T,V}}}, B::AbstractVecOrMat) return B end -/(B::AbstractMatrix,A::LU) = transpose(Transpose(A) \ Transpose(B)) +/(B::AbstractMatrix, A::LU) = copy(transpose(transpose(A) \ transpose(B))) # Conversions AbstractMatrix(F::LU) = (F.L * F.U)[invperm(F.p),:] diff --git a/base/linalg/matmul.jl b/base/linalg/matmul.jl index 78838f019451e..7434ee066fd2a 100644 --- a/base/linalg/matmul.jl +++ b/base/linalg/matmul.jl @@ -82,13 +82,13 @@ end # these will throw a DimensionMismatch unless B has 1 row (or 1 col for transposed case): *(a::AbstractVector, transB::Transpose{<:Any,<:AbstractMatrix}) = - (B = transB.parent; *(reshape(a,length(a),1), Transpose(B))) + (B = transB.parent; *(reshape(a,length(a),1), transpose(B))) *(A::AbstractMatrix, transb::Transpose{<:Any,<:AbstractVector}) = - (b = transb.parent; *(A, Transpose(reshape(b,length(b),1)))) + (b = transb.parent; *(A, transpose(reshape(b,length(b),1)))) *(a::AbstractVector, adjB::Adjoint{<:Any,<:AbstractMatrix}) = - (B = adjB.parent; *(reshape(a,length(a),1), Adjoint(B))) + (B = adjB.parent; *(reshape(a,length(a),1), adjoint(B))) *(A::AbstractMatrix, adjb::Adjoint{<:Any,<:AbstractVector}) = - (b = adjb.parent; *(A, Adjoint(reshape(b,length(b),1)))) + (b = adjb.parent; *(A, adjoint(reshape(b,length(b),1)))) (*)(a::AbstractVector, B::AbstractMatrix) = reshape(a,length(a),1)*B mul!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where {T<:BlasFloat} = gemv!(y, 'N', A, x) @@ -107,12 +107,12 @@ mul!(y::AbstractVector, A::AbstractVecOrMat, x::AbstractVector) = generic_matvec function *(transA::Transpose{<:Any,<:StridedMatrix{T}}, x::StridedVector{S}) where {T<:BlasFloat,S} A = transA.parent TS = promote_op(matprod, T, S) - mul!(similar(x,TS,size(A,2)), Transpose(A), convert(AbstractVector{TS}, x)) + mul!(similar(x,TS,size(A,2)), transpose(A), convert(AbstractVector{TS}, x)) end function *(transA::Transpose{<:Any,<:AbstractMatrix{T}}, x::AbstractVector{S}) where {T,S} A = transA.parent TS = promote_op(matprod, T, S) - mul!(similar(x,TS,size(A,2)), Transpose(A), x) + mul!(similar(x,TS,size(A,2)), transpose(A), x) end mul!(y::StridedVector{T}, transA::Transpose{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T}) where {T<:BlasFloat} = (A = transA.parent; gemv!(y, 'T', A, x)) @@ -122,16 +122,16 @@ mul!(y::AbstractVector, transA::Transpose{<:Any,<:AbstractVecOrMat}, x::Abstract function *(adjA::Adjoint{<:Any,<:StridedMatrix{T}}, x::StridedVector{S}) where {T<:BlasFloat,S} A = adjA.parent TS = promote_op(matprod, T, S) - mul!(similar(x,TS,size(A,2)), Adjoint(A) ,convert(AbstractVector{TS},x)) + mul!(similar(x,TS,size(A,2)), adjoint(A) ,convert(AbstractVector{TS},x)) end function *(adjA::Adjoint{<:Any,<:AbstractMatrix{T}}, x::AbstractVector{S}) where {T,S} A = adjA.parent TS = promote_op(matprod, T, S) - mul!(similar(x,TS,size(A,2)), Adjoint(A), x) + mul!(similar(x,TS,size(A,2)), adjoint(A), x) end mul!(y::StridedVector{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T}) where {T<:BlasReal} = - (A = adjA.parent; mul!(y, Transpose(A), x)) + (A = adjA.parent; mul!(y, transpose(A), x)) mul!(y::StridedVector{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T}) where {T<:BlasComplex} = (A = adjA.parent; gemv!(y, 'C', A, x)) mul!(y::AbstractVector, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, x::AbstractVector) = @@ -190,17 +190,23 @@ julia> Y mul!(C::AbstractMatrix, A::AbstractVecOrMat, B::AbstractVecOrMat) = generic_matmatmul!(C, 'N', 'N', A, B) """ - mul!(A, B) + mul1!(A, B) -Calculate the matrix-matrix product ``AB``, overwriting one of `A` or `B` (but not both), -and return the result (the overwritten argument). +Calculate the matrix-matrix product ``AB``, overwriting `A`, and return the result. """ -mul!(A, B) +mul1!(A, B) + +""" + mul2!(A, B) + +Calculate the matrix-matrix product ``AB``, overwriting `B`, and return the result. +""" +mul2!(A, B) function *(transA::Transpose{<:Any,<:AbstractMatrix}, B::AbstractMatrix) A = transA.parent TS = promote_op(matprod, eltype(A), eltype(B)) - mul!(similar(B, TS, (size(A,2), size(B,2))), Transpose(A), B) + mul!(similar(B, TS, (size(A,2), size(B,2))), transpose(A), B) end mul!(C::StridedMatrix{T}, transA::Transpose{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T}) where {T<:BlasFloat} = (A = transA.parent; A===B ? syrk_wrapper!(C, 'T', A) : gemm_wrapper!(C, 'T', 'N', A, B)) @@ -210,7 +216,7 @@ mul!(C::AbstractMatrix, transA::Transpose{<:Any,<:AbstractVecOrMat}, B::Abstract function *(A::AbstractMatrix, transB::Transpose{<:Any,<:AbstractMatrix}) B = transB.parent TS = promote_op(matprod, eltype(A), eltype(B)) - mul!(similar(B, TS, (size(A,1), size(B,1))), A, Transpose(B)) + mul!(similar(B, TS, (size(A,1), size(B,1))), A, transpose(B)) end mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, transB::Transpose{<:Any,<:StridedVecOrMat{T}}) where {T<:BlasFloat} = (B = transB.parent; A===B ? syrk_wrapper!(C, 'N', A) : gemm_wrapper!(C, 'N', 'T', A, B)) @@ -241,22 +247,22 @@ _disambigmul!(C::AbstractVecOrMat, A::AbstractVecOrMat, transB::Transpose{<:Any, function _disambigmul(transA::Transpose{<:Any,<:AbstractMatrix{T}}, transB::Transpose{<:Any,<:AbstractVecOrMat{S}}) where {T,S} A, B = transA.parent, transB.parent TS = promote_op(matprod, T, S) - mul!(similar(B, TS, (size(A,2), size(B,1))), Transpose(A), Transpose(B)) + mul!(similar(B, TS, (size(A,2), size(B,1))), transpose(A), transpose(B)) end mul!(C::StridedMatrix{T}, transA::Transpose{<:Any,<:StridedVecOrMat{T}}, transB::Transpose{<:Any,<:StridedVecOrMat{T}}) where {T<:BlasFloat} = (A = transA.parent; B = transB.parent; gemm_wrapper!(C, 'T', 'T', A, B)) mul!(C::AbstractMatrix, transA::Transpose{<:Any,<:AbstractVecOrMat}, transB::Transpose{<:Any,<:AbstractVecOrMat}) = (A = transA.parent; B = transB.parent; generic_matmatmul!(C, 'T', 'T', A, B)) -mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractVecOrMat}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, adjoint(B.parent)) +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractVecOrMat}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) *(adjA::Adjoint{<:Any,<:StridedMatrix{T}}, B::StridedMatrix{T}) where {T<:BlasReal} = - (A = adjA.parent; *(Transpose(A), B)) + (A = adjA.parent; *(transpose(A), B)) mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T}) where {T<:BlasReal} = - (A = adjA.parent; mul!(C, Transpose(A), B)) + (A = adjA.parent; mul!(C, transpose(A), B)) function *(adjA::Adjoint{<:Any,<:AbstractMatrix}, B::AbstractMatrix) A = adjA.parent TS = promote_op(matprod, eltype(A), eltype(B)) - mul!(similar(B, TS, (size(A,2), size(B,2))), Adjoint(A), B) + mul!(similar(B, TS, (size(A,2), size(B,2))), adjoint(A), B) end mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T}) where {T<:BlasComplex} = (A = adjA.parent; A===B ? herk_wrapper!(C,'C',A) : gemm_wrapper!(C,'C', 'N', A, B)) @@ -264,13 +270,13 @@ mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, B::AbstractVecO (A = adjA.parent; generic_matmatmul!(C, 'C', 'N', A, B)) *(A::StridedMatrix{<:BlasFloat}, adjB::Adjoint{<:Any,<:StridedMatrix{<:BlasReal}}) = - (B = adjB.parent; *(A, Transpose(B))) + (B = adjB.parent; *(A, transpose(B))) mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:StridedVecOrMat{<:BlasReal}}) where {T<:BlasFloat} = - (B = adjB.parent; mul!(C, A, Transpose(B))) + (B = adjB.parent; mul!(C, A, transpose(B))) function *(A::AbstractMatrix, adjB::Adjoint{<:Any,<:AbstractMatrix}) B = adjB.parent TS = promote_op(matprod, eltype(A), eltype(B)) - mul!(similar(B,TS,(size(A,1),size(B,1))), A, Adjoint(B)) + mul!(similar(B,TS,(size(A,1),size(B,1))), A, adjoint(B)) end mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:StridedVecOrMat{T}}) where {T<:BlasComplex} = (B = adjB.parent; A===B ? herk_wrapper!(C, 'N', A) : gemm_wrapper!(C, 'N', 'C', A, B)) @@ -278,7 +284,7 @@ mul!(C::AbstractMatrix, A::AbstractVecOrMat, adjB::Adjoint{<:Any,<:AbstractVecOr (B = adjB.parent; generic_matmatmul!(C, 'N', 'C', A, B)) *(adjA::Adjoint{<:Any,<:AbstractMatrix}, adjB::Adjoint{<:Any,<:AbstractMatrix}) = - (A = adjA.parent; B = adjB.parent; mul!(similar(B, promote_op(matprod, eltype(A), eltype(B)), (size(A,2), size(B,1))), Adjoint(A), Adjoint(B))) + (A = adjA.parent; B = adjB.parent; mul!(similar(B, promote_op(matprod, eltype(A), eltype(B)), (size(A,2), size(B,1))), adjoint(A), adjoint(B))) mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, adjB::Adjoint{<:Any,<:StridedVecOrMat{T}}) where {T<:BlasFloat} = (A = adjA.parent; B = adjB.parent; gemm_wrapper!(C, 'C', 'C', A, B)) mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, adjB::Adjoint{<:Any,<:AbstractVecOrMat}) = @@ -475,7 +481,7 @@ function generic_matvecmul!(C::AbstractVector{R}, tA, A::AbstractVecOrMat, B::Ab s = zero(A[aoffs + 1]*B[1] + A[aoffs + 1]*B[1]) end for i = 1:nA - s += Transpose(A[aoffs+i]) * B[i] + s += transpose(A[aoffs+i]) * B[i] end C[k] = s end @@ -629,7 +635,7 @@ function _generic_matmatmul!(C::AbstractVecOrMat{R}, tA, tB, A::AbstractVecOrMat z2 = zero(A[i, 1]*B[j, 1] + A[i, 1]*B[j, 1]) Ctmp = convert(promote_type(R, typeof(z2)), z2) for k = 1:nA - Ctmp += A[i, k] * Transpose(B[j, k]) + Ctmp += A[i, k] * transpose(B[j, k]) end C[i,j] = Ctmp end @@ -649,7 +655,7 @@ function _generic_matmatmul!(C::AbstractVecOrMat{R}, tA, tB, A::AbstractVecOrMat z2 = zero(A[1, i]*B[1, j] + A[1, i]*B[1, j]) Ctmp = convert(promote_type(R, typeof(z2)), z2) for k = 1:nA - Ctmp += Transpose(A[k, i]) * B[k, j] + Ctmp += transpose(A[k, i]) * B[k, j] end C[i,j] = Ctmp end @@ -658,7 +664,7 @@ function _generic_matmatmul!(C::AbstractVecOrMat{R}, tA, tB, A::AbstractVecOrMat z2 = zero(A[1, i]*B[j, 1] + A[1, i]*B[j, 1]) Ctmp = convert(promote_type(R, typeof(z2)), z2) for k = 1:nA - Ctmp += Transpose(A[k, i]) * Transpose(B[j, k]) + Ctmp += transpose(A[k, i]) * transpose(B[j, k]) end C[i,j] = Ctmp end @@ -667,7 +673,7 @@ function _generic_matmatmul!(C::AbstractVecOrMat{R}, tA, tB, A::AbstractVecOrMat z2 = zero(A[1, i]*B[j, 1] + A[1, i]*B[j, 1]) Ctmp = convert(promote_type(R, typeof(z2)), z2) for k = 1:nA - Ctmp += Transpose(A[k, i]) * Adjoint(B[j, k]) + Ctmp += transpose(A[k, i]) * adjoint(B[j, k]) end C[i,j] = Ctmp end @@ -687,7 +693,7 @@ function _generic_matmatmul!(C::AbstractVecOrMat{R}, tA, tB, A::AbstractVecOrMat z2 = zero(A[1, i]*B[j, 1] + A[1, i]*B[j, 1]) Ctmp = convert(promote_type(R, typeof(z2)), z2) for k = 1:nA - Ctmp += Adjoint(A[k, i]) * Transpose(B[j, k]) + Ctmp += adjoint(A[k, i]) * transpose(B[j, k]) end C[i,j] = Ctmp end @@ -719,18 +725,27 @@ function matmul2x2!(C::AbstractMatrix, tA, tB, A::AbstractMatrix, B::AbstractMat end @inbounds begin if tA == 'T' - A11 = transpose(A[1,1]); A12 = transpose(A[2,1]); A21 = transpose(A[1,2]); A22 = transpose(A[2,2]) + # TODO making these lazy could improve perf + A11 = copy(transpose(A[1,1])); A12 = copy(transpose(A[2,1])) + A21 = copy(transpose(A[1,2])); A22 = copy(transpose(A[2,2])) elseif tA == 'C' - A11 = adjoint(A[1,1]); A12 = adjoint(A[2,1]); A21 = adjoint(A[1,2]); A22 = adjoint(A[2,2]) + # TODO making these lazy could improve perf + A11 = copy(A[1,1]'); A12 = copy(A[2,1]') + A21 = copy(A[1,2]'); A22 = copy(A[2,2]') else A11 = A[1,1]; A12 = A[1,2]; A21 = A[2,1]; A22 = A[2,2] end if tB == 'T' - B11 = transpose(B[1,1]); B12 = transpose(B[2,1]); B21 = transpose(B[1,2]); B22 = transpose(B[2,2]) + # TODO making these lazy could improve perf + B11 = copy(transpose(B[1,1])); B12 = copy(transpose(B[2,1])) + B21 = copy(transpose(B[1,2])); B22 = copy(transpose(B[2,2])) elseif tB == 'C' - B11 = adjoint(B[1,1]); B12 = adjoint(B[2,1]); B21 = adjoint(B[1,2]); B22 = adjoint(B[2,2]) + # TODO making these lazy could improve perf + B11 = copy(B[1,1]'); B12 = copy(B[2,1]') + B21 = copy(B[1,2]'); B22 = copy(B[2,2]') else - B11 = B[1,1]; B12 = B[1,2]; B21 = B[2,1]; B22 = B[2,2] + B11 = B[1,1]; B12 = B[1,2]; + B21 = B[2,1]; B22 = B[2,2] end C[1,1] = A11*B11 + A12*B21 C[1,2] = A11*B12 + A12*B22 @@ -751,13 +766,15 @@ function matmul3x3!(C::AbstractMatrix, tA, tB, A::AbstractMatrix, B::AbstractMat end @inbounds begin if tA == 'T' - A11 = transpose(A[1,1]); A12 = transpose(A[2,1]); A13 = transpose(A[3,1]) - A21 = transpose(A[1,2]); A22 = transpose(A[2,2]); A23 = transpose(A[3,2]) - A31 = transpose(A[1,3]); A32 = transpose(A[2,3]); A33 = transpose(A[3,3]) + # TODO making these lazy could improve perf + A11 = copy(transpose(A[1,1])); A12 = copy(transpose(A[2,1])); A13 = copy(transpose(A[3,1])) + A21 = copy(transpose(A[1,2])); A22 = copy(transpose(A[2,2])); A23 = copy(transpose(A[3,2])) + A31 = copy(transpose(A[1,3])); A32 = copy(transpose(A[2,3])); A33 = copy(transpose(A[3,3])) elseif tA == 'C' - A11 = adjoint(A[1,1]); A12 = adjoint(A[2,1]); A13 = adjoint(A[3,1]) - A21 = adjoint(A[1,2]); A22 = adjoint(A[2,2]); A23 = adjoint(A[3,2]) - A31 = adjoint(A[1,3]); A32 = adjoint(A[2,3]); A33 = adjoint(A[3,3]) + # TODO making these lazy could improve perf + A11 = copy(A[1,1]'); A12 = copy(A[2,1]'); A13 = copy(A[3,1]') + A21 = copy(A[1,2]'); A22 = copy(A[2,2]'); A23 = copy(A[3,2]') + A31 = copy(A[1,3]'); A32 = copy(A[2,3]'); A33 = copy(A[3,3]') else A11 = A[1,1]; A12 = A[1,2]; A13 = A[1,3] A21 = A[2,1]; A22 = A[2,2]; A23 = A[2,3] @@ -765,13 +782,15 @@ function matmul3x3!(C::AbstractMatrix, tA, tB, A::AbstractMatrix, B::AbstractMat end if tB == 'T' - B11 = transpose(B[1,1]); B12 = transpose(B[2,1]); B13 = transpose(B[3,1]) - B21 = transpose(B[1,2]); B22 = transpose(B[2,2]); B23 = transpose(B[3,2]) - B31 = transpose(B[1,3]); B32 = transpose(B[2,3]); B33 = transpose(B[3,3]) + # TODO making these lazy could improve perf + B11 = copy(transpose(B[1,1])); B12 = copy(transpose(B[2,1])); B13 = copy(transpose(B[3,1])) + B21 = copy(transpose(B[1,2])); B22 = copy(transpose(B[2,2])); B23 = copy(transpose(B[3,2])) + B31 = copy(transpose(B[1,3])); B32 = copy(transpose(B[2,3])); B33 = copy(transpose(B[3,3])) elseif tB == 'C' - B11 = adjoint(B[1,1]); B12 = adjoint(B[2,1]); B13 = adjoint(B[3,1]) - B21 = adjoint(B[1,2]); B22 = adjoint(B[2,2]); B23 = adjoint(B[3,2]) - B31 = adjoint(B[1,3]); B32 = adjoint(B[2,3]); B33 = adjoint(B[3,3]) + # TODO making these lazy could improve perf + B11 = copy(B[1,1]'); B12 = copy(B[2,1]'); B13 = copy(B[3,1]') + B21 = copy(B[1,2]'); B22 = copy(B[2,2]'); B23 = copy(B[3,2]') + B31 = copy(B[1,3]'); B32 = copy(B[2,3]'); B33 = copy(B[3,3]') else B11 = B[1,1]; B12 = B[1,2]; B13 = B[1,3] B21 = B[2,1]; B22 = B[2,2]; B23 = B[2,3] diff --git a/base/linalg/qr.jl b/base/linalg/qr.jl index 21e5263dc3c87..ecebffef3290e 100644 --- a/base/linalg/qr.jl +++ b/base/linalg/qr.jl @@ -161,7 +161,7 @@ end function qrfactPivotedUnblocked!(A::StridedMatrix) m, n = size(A) - piv = collect(UnitRange{BlasInt}(1,n)) + piv = Vector(UnitRange{BlasInt}(1,n)) τ = Vector{eltype(A)}(uninitialized, min(m,n)) for j = 1:min(m,n) @@ -329,13 +329,13 @@ function _qr(A::Union{Number,AbstractMatrix}, ::Val{false}; full::Bool = false) F = qrfact(A, Val(false)) Q, R = F.Q, F.R sQf1 = size(Q.factors, 1) - return (!full ? Array(Q) : mul!(Q, Matrix{eltype(Q)}(I, sQf1, sQf1))), R + return (!full ? Array(Q) : mul2!(Q, Matrix{eltype(Q)}(I, sQf1, sQf1))), R end function _qr(A::Union{Number, AbstractMatrix}, ::Val{true}; full::Bool = false) F = qrfact(A, Val(true)) Q, R, p = F.Q, F.R, F.p sQf1 = size(Q.factors, 1) - return (!full ? Array(Q) : mul!(Q, Matrix{eltype(Q)}(I, sQf1, sQf1))), R, p + return (!full ? Array(Q) : mul2!(Q, Matrix{eltype(Q)}(I, sQf1, sQf1))), R, p end """ @@ -504,7 +504,7 @@ AbstractMatrix{T}(Q::QRPackedQ) where {T} = QRPackedQ{T}(Q) QRCompactWYQ{S}(Q::QRCompactWYQ) where {S} = QRCompactWYQ(convert(AbstractMatrix{S}, Q.factors), convert(AbstractMatrix{S}, Q.T)) AbstractMatrix{S}(Q::QRCompactWYQ{S}) where {S} = Q AbstractMatrix{S}(Q::QRCompactWYQ) where {S} = QRCompactWYQ{S}(Q) -Matrix(A::AbstractQ{T}) where {T} = mul!(A, Matrix{T}(I, size(A.factors, 1), min(size(A.factors)...))) +Matrix(A::AbstractQ{T}) where {T} = mul2!(A, Matrix{T}(I, size(A.factors, 1), min(size(A.factors)...))) Array(A::AbstractQ) = Matrix(A) size(A::Union{QR,QRCompactWY,QRPivoted}, dim::Integer) = size(getfield(A, :factors), dim) @@ -518,16 +518,16 @@ function getindex(A::AbstractQ, i::Integer, j::Integer) x[i] = 1 y = zeros(eltype(A), size(A, 2)) y[j] = 1 - return dot(x, mul!(A, y)) + return dot(x, mul2!(A, y)) end ## Multiplication by Q ### QB -mul!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} = +mul2!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} = LAPACK.gemqrt!('L','N',A.factors,A.T,B) -mul!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} = +mul2!(A::QRPackedQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} = LAPACK.ormqr!('L','N',A.factors,A.τ,B) -function mul!(A::QRPackedQ, B::AbstractVecOrMat) +function mul2!(A::QRPackedQ, B::AbstractVecOrMat) mA, nA = size(A.factors) mB, nB = size(B,1), size(B,2) if mA != mB @@ -562,7 +562,7 @@ function (*)(A::AbstractQ, b::StridedVector) else throw(DimensionMismatch("vector must have length either $(size(A.factors, 1)) or $(size(A.factors, 2))")) end - mul!(Anew, bnew) + mul2!(Anew, bnew) end function (*)(A::AbstractQ, B::StridedMatrix) TAB = promote_type(eltype(A), eltype(B)) @@ -574,19 +574,19 @@ function (*)(A::AbstractQ, B::StridedMatrix) else throw(DimensionMismatch("first dimension of matrix must have size either $(size(A.factors, 1)) or $(size(A.factors, 2))")) end - mul!(Anew, Bnew) + mul2!(Anew, Bnew) end ### QcB -mul!(adjA::Adjoint{<:Any,<:QRCompactWYQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} = +mul2!(adjA::Adjoint{<:Any,<:QRCompactWYQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} = (A = adjA.parent; LAPACK.gemqrt!('L','T',A.factors,A.T,B)) -mul!(adjA::Adjoint{<:Any,<:QRCompactWYQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} = +mul2!(adjA::Adjoint{<:Any,<:QRCompactWYQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} = (A = adjA.parent; LAPACK.gemqrt!('L','C',A.factors,A.T,B)) -mul!(adjA::Adjoint{<:Any,<:QRPackedQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} = +mul2!(adjA::Adjoint{<:Any,<:QRPackedQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasReal,S<:StridedMatrix} = (A = adjA.parent; LAPACK.ormqr!('L','T',A.factors,A.τ,B)) -mul!(adjA::Adjoint{<:Any,<:QRPackedQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} = +mul2!(adjA::Adjoint{<:Any,<:QRPackedQ{T,S}}, B::StridedVecOrMat{T}) where {T<:BlasComplex,S<:StridedMatrix} = (A = adjA.parent; LAPACK.ormqr!('L','C',A.factors,A.τ,B)) -function mul!(adjA::Adjoint{<:Any,<:QRPackedQ}, B::AbstractVecOrMat) +function mul2!(adjA::Adjoint{<:Any,<:QRPackedQ}, B::AbstractVecOrMat) A = adjA.parent mA, nA = size(A.factors) mB, nB = size(B,1), size(B,2) @@ -614,7 +614,7 @@ end function *(adjQ::Adjoint{<:Any,<:AbstractQ}, B::StridedVecOrMat) Q = adjQ.parent TQB = promote_type(eltype(Q), eltype(B)) - return mul!(Adjoint(convert(AbstractMatrix{TQB}, Q)), copy_oftype(B, TQB)) + return mul2!(adjoint(convert(AbstractMatrix{TQB}, Q)), copy_oftype(B, TQB)) end ### QBc/QcBc @@ -623,22 +623,22 @@ function *(Q::AbstractQ, adjB::Adjoint{<:Any,<:StridedVecOrMat}) TQB = promote_type(eltype(Q), eltype(B)) Bc = similar(B, TQB, (size(B, 2), size(B, 1))) adjoint!(Bc, B) - return mul!(convert(AbstractMatrix{TQB}, Q), Bc) + return mul2!(convert(AbstractMatrix{TQB}, Q), Bc) end function *(adjQ::Adjoint{<:Any,<:AbstractQ}, adjB::Adjoint{<:Any,<:StridedVecOrMat}) Q, B = adjQ.parent, adjB.parent TQB = promote_type(eltype(Q), eltype(B)) Bc = similar(B, TQB, (size(B, 2), size(B, 1))) adjoint!(Bc, B) - return mul!(Adjoint(convert(AbstractMatrix{TQB}, Q)), Bc) + return mul2!(adjoint(convert(AbstractMatrix{TQB}, Q)), Bc) end ### AQ -mul!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} = +mul1!(A::StridedVecOrMat{T}, B::QRCompactWYQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} = LAPACK.gemqrt!('R','N', B.factors, B.T, A) -mul!(A::StridedVecOrMat{T}, B::QRPackedQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} = +mul1!(A::StridedVecOrMat{T}, B::QRPackedQ{T,S}) where {T<:BlasFloat,S<:StridedMatrix} = LAPACK.ormqr!('R', 'N', B.factors, B.τ, A) -function mul!(A::StridedMatrix,Q::QRPackedQ) +function mul1!(A::StridedMatrix,Q::QRPackedQ) mQ, nQ = size(Q.factors) mA, nA = size(A,1), size(A,2) if nA != mQ @@ -665,19 +665,20 @@ end function (*)(A::StridedMatrix, Q::AbstractQ) TAQ = promote_type(eltype(A), eltype(Q)) - return mul!(copy_oftype(A, TAQ), convert(AbstractMatrix{TAQ}, Q)) + + return mul1!(copy_oftype(A, TAQ), convert(AbstractMatrix{TAQ}, Q)) end ### AQc -mul!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRCompactWYQ{T}}) where {T<:BlasReal} = +mul1!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRCompactWYQ{T}}) where {T<:BlasReal} = (B = adjB.parent; LAPACK.gemqrt!('R','T',B.factors,B.T,A)) -mul!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRCompactWYQ{T}}) where {T<:BlasComplex} = +mul1!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRCompactWYQ{T}}) where {T<:BlasComplex} = (B = adjB.parent; LAPACK.gemqrt!('R','C',B.factors,B.T,A)) -mul!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRPackedQ{T}}) where {T<:BlasReal} = +mul1!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRPackedQ{T}}) where {T<:BlasReal} = (B = adjB.parent; LAPACK.ormqr!('R','T',B.factors,B.τ,A)) -mul!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRPackedQ{T}}) where {T<:BlasComplex} = +mul1!(A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:QRPackedQ{T}}) where {T<:BlasComplex} = (B = adjB.parent; LAPACK.ormqr!('R','C',B.factors,B.τ,A)) -function mul!(A::StridedMatrix, adjQ::Adjoint{<:Any,<:QRPackedQ}) +function mul1!(A::StridedMatrix, adjQ::Adjoint{<:Any,<:QRPackedQ}) Q = adjQ.parent mQ, nQ = size(Q.factors) mA, nA = size(A,1), size(A,2) @@ -709,14 +710,14 @@ function *(A::StridedMatrix, adjB::Adjoint{<:Any,<:AbstractQ}) if size(A,2) == size(B.factors, 1) AA = similar(A, TAB, size(A)) copyto!(AA, A) - return mul!(AA, Adjoint(BB)) + return mul1!(AA, adjoint(BB)) elseif size(A,2) == size(B.factors,2) - return mul!([A zeros(TAB, size(A, 1), size(B.factors, 1) - size(B.factors, 2))], Adjoint(BB)) + return mul1!([A zeros(TAB, size(A, 1), size(B.factors, 1) - size(B.factors, 2))], adjoint(BB)) else throw(DimensionMismatch("matrix A has dimensions $(size(A)) but matrix B has dimensions $(size(B))")) end end -*(u::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractQ}) = Adjoint(A.parent * u.parent) +*(u::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractQ}) = adjoint(A.parent * u.parent) ### AcQ/AcQc @@ -725,20 +726,20 @@ function *(adjA::Adjoint{<:Any,<:StridedVecOrMat}, Q::AbstractQ) TAQ = promote_type(eltype(A), eltype(Q)) Ac = similar(A, TAQ, (size(A, 2), size(A, 1))) adjoint!(Ac, A) - return mul!(Ac, convert(AbstractMatrix{TAQ}, Q)) + return mul1!(Ac, convert(AbstractMatrix{TAQ}, Q)) end function *(adjA::Adjoint{<:Any,<:StridedVecOrMat}, adjQ::Adjoint{<:Any,<:AbstractQ}) A, Q = adjA.parent, adjQ.parent TAQ = promote_type(eltype(A), eltype(Q)) Ac = similar(A, TAQ, (size(A, 2), size(A, 1))) adjoint!(Ac, A) - return mul!(Ac, Adjoint(convert(AbstractMatrix{TAQ}, Q))) + return mul1!(Ac, adjoint(convert(AbstractMatrix{TAQ}, Q))) end ldiv!(A::QRCompactWY{T}, b::StridedVector{T}) where {T<:BlasFloat} = - (ldiv!(UpperTriangular(A.R), view(mul!(Adjoint(A.Q), b), 1:size(A, 2))); b) + (ldiv!(UpperTriangular(A.R), view(mul2!(adjoint(A.Q), b), 1:size(A, 2))); b) ldiv!(A::QRCompactWY{T}, B::StridedMatrix{T}) where {T<:BlasFloat} = - (ldiv!(UpperTriangular(A.R), view(mul!(Adjoint(A.Q), B), 1:size(A, 2), 1:size(B, 2))); B) + (ldiv!(UpperTriangular(A.R), view(mul2!(adjoint(A.Q), B), 1:size(A, 2), 1:size(B, 2))); B) # Julia implementation similar to xgelsy function ldiv!(A::QRPivoted{T}, B::StridedMatrix{T}, rcond::Real) where T<:BlasFloat @@ -770,7 +771,7 @@ function ldiv!(A::QRPivoted{T}, B::StridedMatrix{T}, rcond::Real) where T<:BlasF rnk += 1 end C, τ = LAPACK.tzrzf!(A.factors[1:rnk,:]) - ldiv!(UpperTriangular(C[1:rnk,1:rnk]),view(mul!(Adjoint(A.Q), view(B, 1:mA, 1:nrhs)), 1:rnk, 1:nrhs)) + ldiv!(UpperTriangular(C[1:rnk,1:rnk]),view(mul2!(adjoint(A.Q), view(B, 1:mA, 1:nrhs)), 1:rnk, 1:nrhs)) B[rnk+1:end,:] = zero(T) LAPACK.ormrz!('L', eltype(B)<:Complex ? 'C' : 'T', C, τ, view(B,1:nA,1:nrhs)) B[1:nA,:] = view(B, 1:nA, :)[invperm(A.p),:] @@ -784,7 +785,7 @@ function ldiv!(A::QR{T}, B::StridedMatrix{T}) where T m, n = size(A) minmn = min(m,n) mB, nB = size(B) - mul!(Adjoint(A.Q), view(B, 1:m, :)) + mul2!(adjoint(A.Q), view(B, 1:m, :)) R = A.R @inbounds begin if n > m # minimum norm solution @@ -792,7 +793,7 @@ function ldiv!(A::QR{T}, B::StridedMatrix{T}) where T for k = m:-1:1 # Trapezoid to triangular by elementary operation x = view(R, k, [k; m + 1:n]) τk = reflector!(x) - τ[k] = adjoint(τk) + τ[k] = conj(τk) for i = 1:k - 1 vRi = R[i,k] for j = m + 1:n @@ -857,9 +858,7 @@ function (\)(A::Union{QR{TA},QRCompactWY{TA},QRPivoted{TA}}, B::AbstractVecOrMat X = _zeros(S, B, n) X[1:size(B, 1), :] = B - ldiv!(AA, X) - return _cut_B(X, 1:n) end @@ -878,7 +877,7 @@ function (\)(A::Union{QR{T},QRCompactWY{T},QRPivoted{T}}, BIn::VecOrMat{Complex{ # |z2|z4| -> |y1|y2|y3|y4| -> |x2|y2| -> |x2|y2|x4|y4| # |x3|y3| # |x4|y4| - B = reshape(transpose(reinterpret(T, reshape(BIn, (1, length(BIn))))), size(BIn, 1), 2*size(BIn, 2)) + B = reshape(copy(transpose(reinterpret(T, reshape(BIn, (1, length(BIn)))))), size(BIn, 1), 2*size(BIn, 2)) X = _zeros(T, B, n) X[1:size(B, 1), :] = B @@ -889,7 +888,7 @@ function (\)(A::Union{QR{T},QRCompactWY{T},QRPivoted{T}}, BIn::VecOrMat{Complex{ # |z2|z4| <- |y1|y2|y3|y4| <- |x2|y2| <- |x2|y2|x4|y4| # |x3|y3| # |x4|y4| - XX = reshape(collect(reinterpret(Complex{T}, transpose(reshape(X, div(length(X), 2), 2)))), _ret_size(A, BIn)) + XX = reshape(collect(reinterpret(Complex{T}, copy(transpose(reshape(X, div(length(X), 2), 2))))), _ret_size(A, BIn)) return _cut_B(XX, 1:n) end diff --git a/base/linalg/rowvector.jl b/base/linalg/rowvector.jl index 73182b0a38c13..1b63a35d70625 100644 --- a/base/linalg/rowvector.jl +++ b/base/linalg/rowvector.jl @@ -10,7 +10,7 @@ shaped row vector and represents the transpose of a vector (the elements are als recursively). By convention, a vector can be multiplied by a matrix on its left (`A * v`) whereas a row -vector can be multiplied by a matrix on its right (such that `RowVector(v) * A = RowVector(Transpose(A) * v)`). It +vector can be multiplied by a matrix on its right (such that `RowVector(v) * A = RowVector(transpose(A) * v)`). It differs from a `1×n`-sized matrix by the facts that its transpose returns a vector and the inner product `RowVector(v1) * v2` returns a scalar, but will otherwise behave similarly. diff --git a/base/linalg/special.jl b/base/linalg/special.jl index 40d13824fbcbf..06ec00d34b312 100644 --- a/base/linalg/special.jl +++ b/base/linalg/special.jl @@ -118,10 +118,10 @@ for op in (:+, :-) end end -mul!(A::AbstractTriangular, adjB::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = - (B = adjB.parent; mul!(full!(A), Adjoint(B))) +mul1!(A::AbstractTriangular, adjB::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = + (B = adjB.parent; mul1!(full!(A), adjoint(B))) *(A::AbstractTriangular, adjB::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = - (B = adjB.parent; *(copyto!(similar(parent(A)), A), Adjoint(B))) + (B = adjB.parent; *(copyto!(similar(parent(A)), A), adjoint(B))) # fill[stored]! methods fillstored!(A::Diagonal, x) = (fill!(A.diag, x); A) diff --git a/base/linalg/svd.jl b/base/linalg/svd.jl index f8daef26e5f5a..ceaab76430cfe 100644 --- a/base/linalg/svd.jl +++ b/base/linalg/svd.jl @@ -165,7 +165,7 @@ function svd(A::AbstractArray; full::Bool = false, thin::Union{Bool,Nothing} = n full::Bool = !thin end F = svdfact(A, full = full) - F.U, F.S, adjoint(F.Vt) + F.U, F.S, copy(F.Vt') end function svd(x::Number; full::Bool = false, thin::Union{Bool,Nothing} = nothing) # DEPRECATION TODO: remove deprecated thin argument and associated logic after 0.7 diff --git a/base/linalg/symmetric.jl b/base/linalg/symmetric.jl index c019375b7cfcf..3d7745d16a916 100644 --- a/base/linalg/symmetric.jl +++ b/base/linalg/symmetric.jl @@ -38,7 +38,7 @@ julia> Slower = Symmetric(A, :L) 2 0 3 0 4 ``` -Note that `Supper` will not be equal to `Slower` unless `A` is itself symmetric (e.g. if `A == Transpose(A)`). +Note that `Supper` will not be equal to `Slower` unless `A` is itself symmetric (e.g. if `A == transpose(A)`). """ Symmetric(A::AbstractMatrix, uplo::Symbol=:U) = (checksquare(A); Symmetric{eltype(A),typeof(A)}(A, char_uplo(uplo))) @@ -244,18 +244,21 @@ ishermitian(A::Symmetric{<:Complex}) = isreal(A) issymmetric(A::Hermitian{<:Real}) = true issymmetric(A::Hermitian{<:Complex}) = isreal(A) issymmetric(A::Symmetric) = true + +adjoint(A::Hermitian) = A transpose(A::Symmetric) = A -transpose(A::Hermitian{<:Real}) = A adjoint(A::Symmetric{<:Real}) = A -function adjoint(A::Symmetric) - AC = adjoint(A.data) - return Symmetric(AC, ifelse(A.uplo == 'U', :L, :U)) -end -function transpose(A::Hermitian) - AT = transpose(A.data) - return Hermitian(AT, ifelse(A.uplo == 'U', :L, :U)) -end -adjoint(A::Hermitian) = A +transpose(A::Hermitian{<:Real}) = A +adjoint(A::Symmetric) = Adjoint(A) +transpose(A::Hermitian) = Transpose(A) + +Base.copy(A::Adjoint{<:Any,<:Hermitian}) = copy(A.parent) +Base.copy(A::Transpose{<:Any,<:Symmetric}) = copy(A.parent) +Base.copy(A::Adjoint{<:Any,<:Symmetric}) = + Symmetric(copy(adjoint(A.parent.data)), ifelse(A.parent.uplo == 'U', :L, :U)) +Base.collect(A::Transpose{<:Any,<:Hermitian}) = + Hermitian(copy(transpose(A.parent.data)), ifelse(A.parent.uplo == 'U', :L, :U)) + trace(A::Hermitian) = real(trace(A.data)) Base.conj(A::HermOrSym) = typeof(A)(conj(A.data), A.uplo) @@ -264,25 +267,25 @@ Base.conj!(A::HermOrSym) = typeof(A)(conj!(A.data), A.uplo) # tril/triu function tril(A::Hermitian, k::Integer=0) if A.uplo == 'U' && k <= 0 - return tril!(adjoint(A.data),k) + return tril!(copy(A.data'),k) elseif A.uplo == 'U' && k > 0 - return tril!(adjoint(A.data),-1) + tril!(triu(A.data),k) + return tril!(copy(A.data'),-1) + tril!(triu(A.data),k) elseif A.uplo == 'L' && k <= 0 return tril(A.data,k) else - return tril(A.data,-1) + tril!(triu!(adjoint(A.data)),k) + return tril(A.data,-1) + tril!(triu!(copy(A.data')),k) end end function tril(A::Symmetric, k::Integer=0) if A.uplo == 'U' && k <= 0 - return tril!(transpose(A.data),k) + return tril!(copy(transpose(A.data)),k) elseif A.uplo == 'U' && k > 0 - return tril!(transpose(A.data),-1) + tril!(triu(A.data),k) + return tril!(copy(transpose(A.data)),-1) + tril!(triu(A.data),k) elseif A.uplo == 'L' && k <= 0 return tril(A.data,k) else - return tril(A.data,-1) + tril!(triu!(transpose(A.data)),k) + return tril(A.data,-1) + tril!(triu!(copy(transpose(A.data))),k) end end @@ -290,11 +293,11 @@ function triu(A::Hermitian, k::Integer=0) if A.uplo == 'U' && k >= 0 return triu(A.data,k) elseif A.uplo == 'U' && k < 0 - return triu(A.data,1) + triu!(tril!(adjoint(A.data)),k) + return triu(A.data,1) + triu!(tril!(copy(A.data')),k) elseif A.uplo == 'L' && k >= 0 - return triu!(adjoint(A.data),k) + return triu!(copy(A.data'),k) else - return triu!(adjoint(A.data),1) + triu!(tril(A.data),k) + return triu!(copy(A.data'),1) + triu!(tril(A.data),k) end end @@ -302,11 +305,11 @@ function triu(A::Symmetric, k::Integer=0) if A.uplo == 'U' && k >= 0 return triu(A.data,k) elseif A.uplo == 'U' && k < 0 - return triu(A.data,1) + triu!(tril!(transpose(A.data)),k) + return triu(A.data,1) + triu!(tril!(copy(transpose(A.data))),k) elseif A.uplo == 'L' && k >= 0 - return triu!(transpose(A.data),k) + return triu!(copy(transpose(A.data)),k) else - return triu!(transpose(A.data),1) + triu!(tril(A.data),k) + return triu!(copy(transpose(A.data)),1) + triu!(tril(A.data),k) end end @@ -551,18 +554,18 @@ eigmax(A::RealHermSymComplexHerm{<:Real,<:StridedMatrix}) = eigvals(A, size(A, 1 eigmin(A::RealHermSymComplexHerm{<:Real,<:StridedMatrix}) = eigvals(A, 1:1)[1] function eigfact!(A::HermOrSym{T,S}, B::HermOrSym{T,S}) where {T<:BlasReal,S<:StridedMatrix} - vals, vecs, _ = LAPACK.sygvd!(1, 'V', A.uplo, A.data, B.uplo == A.uplo ? B.data : adjoint(B.data)) + vals, vecs, _ = LAPACK.sygvd!(1, 'V', A.uplo, A.data, B.uplo == A.uplo ? B.data : copy(B.data')) GeneralizedEigen(vals, vecs) end function eigfact!(A::Hermitian{T,S}, B::Hermitian{T,S}) where {T<:BlasComplex,S<:StridedMatrix} - vals, vecs, _ = LAPACK.sygvd!(1, 'V', A.uplo, A.data, B.uplo == A.uplo ? B.data : adjoint(B.data)) + vals, vecs, _ = LAPACK.sygvd!(1, 'V', A.uplo, A.data, B.uplo == A.uplo ? B.data : copy(B.data')) GeneralizedEigen(vals, vecs) end eigvals!(A::HermOrSym{T,S}, B::HermOrSym{T,S}) where {T<:BlasReal,S<:StridedMatrix} = - LAPACK.sygvd!(1, 'N', A.uplo, A.data, B.uplo == A.uplo ? B.data : adjoint(B.data))[1] + LAPACK.sygvd!(1, 'N', A.uplo, A.data, B.uplo == A.uplo ? B.data : copy(B.data'))[1] eigvals!(A::Hermitian{T,S}, B::Hermitian{T,S}) where {T<:BlasComplex,S<:StridedMatrix} = - LAPACK.sygvd!(1, 'N', A.uplo, A.data, B.uplo == A.uplo ? B.data : adjoint(B.data))[1] + LAPACK.sygvd!(1, 'N', A.uplo, A.data, B.uplo == A.uplo ? B.data : copy(B.data'))[1] eigvecs(A::HermOrSym) = eigvecs(eigfact(A)) diff --git a/base/linalg/transpose.jl b/base/linalg/transpose.jl index a6a8c1622a378..5b67703c57ee7 100644 --- a/base/linalg/transpose.jl +++ b/base/linalg/transpose.jl @@ -169,19 +169,8 @@ julia> transpose(A) 3 6 9 ``` """ -function transpose(A::AbstractMatrix) - ind1, ind2 = axes(A) - B = similar(A, (ind2, ind1)) - transpose!(B, A) -end -function adjoint(A::AbstractMatrix) - ind1, ind2 = axes(A) - B = similar(A, (ind2, ind1)) - adjoint!(B, A) -end - -@inline adjoint(A::AbstractVector{<:Real}) = transpose(A) -@inline adjoint(A::AbstractMatrix{<:Real}) = transpose(A) +Base.copy(A::Transpose{<:Any,<:AbstractMatrix}) = transpose!(similar(A.parent, reverse(axes(A.parent))), A.parent) +Base.copy(A::Adjoint{<:Any,<:AbstractMatrix}) = adjoint!(similar(A.parent, reverse(axes(A.parent))), A.parent) function copy_transpose!(B::AbstractVecOrMat, ir_dest::AbstractRange{Int}, jr_dest::AbstractRange{Int}, A::AbstractVecOrMat, ir_src::AbstractRange{Int}, jr_src::AbstractRange{Int}) diff --git a/base/linalg/triangular.jl b/base/linalg/triangular.jl index 3685b38c88647..69f18d57e25ab 100644 --- a/base/linalg/triangular.jl +++ b/base/linalg/triangular.jl @@ -328,14 +328,25 @@ function tril!(A::UnitLowerTriangular, k::Integer=0) return tril!(LowerTriangular(A.data),k) end -transpose(A::LowerTriangular) = UpperTriangular(transpose(A.data)) -transpose(A::UnitLowerTriangular) = UnitUpperTriangular(transpose(A.data)) -transpose(A::UpperTriangular) = LowerTriangular(transpose(A.data)) -transpose(A::UnitUpperTriangular) = UnitLowerTriangular(transpose(A.data)) -adjoint(A::LowerTriangular) = UpperTriangular(adjoint(A.data)) -adjoint(A::UnitLowerTriangular) = UnitUpperTriangular(adjoint(A.data)) -adjoint(A::UpperTriangular) = LowerTriangular(adjoint(A.data)) -adjoint(A::UnitUpperTriangular) = UnitLowerTriangular(adjoint(A.data)) +# TODO consolidate +adjoint(A::LowerTriangular) = Adjoint(A) +adjoint(A::UpperTriangular) = Adjoint(A) +adjoint(A::UnitLowerTriangular) = Adjoint(A) +adjoint(A::UnitUpperTriangular) = Adjoint(A) +transpose(A::LowerTriangular) = Transpose(A) +transpose(A::UpperTriangular) = Transpose(A) +transpose(A::UnitLowerTriangular) = Transpose(A) +transpose(A::UnitUpperTriangular) = Transpose(A) + +# TODO consolidate +Base.copy(A::Adjoint{<:Any,<:LowerTriangular}) = adjoint!(copy(A.parent)) +Base.copy(A::Adjoint{<:Any,<:UpperTriangular}) = adjoint!(copy(A.parent)) +Base.copy(A::Adjoint{<:Any,<:UnitLowerTriangular}) = adjoint!(copy(A.parent)) +Base.copy(A::Adjoint{<:Any,<:UnitUpperTriangular}) = adjoint!(copy(A.parent)) +Base.copy(A::Transpose{<:Any,<:LowerTriangular}) = transpose!(copy(A.parent)) +Base.copy(A::Transpose{<:Any,<:UpperTriangular}) = transpose!(copy(A.parent)) +Base.copy(A::Transpose{<:Any,<:UnitLowerTriangular}) = transpose!(copy(A.parent)) +Base.copy(A::Transpose{<:Any,<:UnitUpperTriangular}) = transpose!(copy(A.parent)) transpose!(A::LowerTriangular) = UpperTriangular(copytri!(A.data, 'L')) transpose!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L')) @@ -446,74 +457,75 @@ fillstored!(A::UnitUpperTriangular, x) = (fillband!(A.data, x, 1, size(A,2)-1); # BlasFloat routines # ###################### -mul!(A::Tridiagonal, B::AbstractTriangular) = A*full!(B) +mul2!(A::Tridiagonal, B::AbstractTriangular) = A*full!(B) # is this necessary? + mul!(C::AbstractMatrix, A::AbstractTriangular, B::Tridiagonal) = mul!(C, copyto!(similar(parent(A)), A), B) mul!(C::AbstractMatrix, A::Tridiagonal, B::AbstractTriangular) = mul!(C, A, copyto!(similar(parent(B)), B)) mul!(C::AbstractVector, A::AbstractTriangular, transB::Transpose{<:Any,<:AbstractVecOrMat}) = - (B = transB.parent; mul!(A, transpose!(C, B))) + (B = transB.parent; mul2!(A, transpose!(C, B))) mul!(C::AbstractMatrix, A::AbstractTriangular, transB::Transpose{<:Any,<:AbstractVecOrMat}) = - (B = transB.parent; mul!(A, transpose!(C, B))) + (B = transB.parent; mul2!(A, transpose!(C, B))) mul!(C::AbstractMatrix, A::AbstractTriangular, adjB::Adjoint{<:Any,<:AbstractVecOrMat}) = - (B = adjB.parent; mul!(A, adjoint!(C, B))) + (B = adjB.parent; mul2!(A, adjoint!(C, B))) mul!(C::AbstractVecOrMat, A::AbstractTriangular, adjB::Adjoint{<:Any,<:AbstractVecOrMat}) = - (B = adjB.parent; mul!(A, adjoint!(C, B))) + (B = adjB.parent; mul2!(A, adjoint!(C, B))) + # The three methods for each op are neceesary to avoid ambiguities with definitions in matmul.jl -mul!(C::AbstractVector , A::AbstractTriangular, B::AbstractVector) = mul!(A, copyto!(C, B)) -mul!(C::AbstractMatrix , A::AbstractTriangular, B::AbstractVecOrMat) = mul!(A, copyto!(C, B)) -mul!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) = mul!(A, copyto!(C, B)) +mul!(C::AbstractVector , A::AbstractTriangular, B::AbstractVector) = mul2!(A, copyto!(C, B)) +mul!(C::AbstractMatrix , A::AbstractTriangular, B::AbstractVecOrMat) = mul2!(A, copyto!(C, B)) +mul!(C::AbstractVecOrMat, A::AbstractTriangular, B::AbstractVecOrMat) = mul2!(A, copyto!(C, B)) mul!(C::AbstractVector , adjA::Adjoint{<:Any,<:AbstractTriangular}, B::AbstractVector) = - (A = adjA.parent; mul!(Adjoint(A), copyto!(C, B))) + (A = adjA.parent; mul2!(adjoint(A), copyto!(C, B))) mul!(C::AbstractMatrix , adjA::Adjoint{<:Any,<:AbstractTriangular}, B::AbstractVecOrMat) = - (A = adjA.parent; mul!(Adjoint(A), copyto!(C, B))) + (A = adjA.parent; mul2!(adjoint(A), copyto!(C, B))) mul!(C::AbstractVecOrMat, adjA::Adjoint{<:Any,<:AbstractTriangular}, B::AbstractVecOrMat) = - (A = adjA.parent; mul!(Adjoint(A), copyto!(C, B))) + (A = adjA.parent; mul2!(adjoint(A), copyto!(C, B))) mul!(C::AbstractVector , transA::Transpose{<:Any,<:AbstractTriangular}, B::AbstractVector) = - (A = transA.parent; mul!(Transpose(A), copyto!(C, B))) + (A = transA.parent; mul2!(transpose(A), copyto!(C, B))) mul!(C::AbstractMatrix , transA::Transpose{<:Any,<:AbstractTriangular}, B::AbstractVecOrMat) = - (A = transA.parent; mul!(Transpose(A), copyto!(C, B))) + (A = transA.parent; mul2!(transpose(A), copyto!(C, B))) mul!(C::AbstractVecOrMat, transA::Transpose{<:Any,<:AbstractTriangular}, B::AbstractVecOrMat) = - (A = transA.parent; mul!(Transpose(A), copyto!(C, B))) -mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, adjoint(B.parent)) -mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, adjoint(B.parent)) -mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, adjoint(B.parent)) -mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, transpose(B.parent)) + (A = transA.parent; mul2!(transpose(A), copyto!(C, B))) +mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) mul!(C::AbstractVector, A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVecOrMat}) = throw(MethodError(mul!, (C, A, B))) mul!(C::AbstractVector, A::Transpose{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVecOrMat}) = throw(MethodError(mul!, (C, A, B))) - for (t, uploc, isunitc) in ((:LowerTriangular, 'L', 'N'), (:UnitLowerTriangular, 'L', 'U'), (:UpperTriangular, 'U', 'N'), (:UnitUpperTriangular, 'U', 'U')) @eval begin # Vector multiplication - mul!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasFloat} = + mul2!(A::$t{T,<:StridedMatrix}, b::StridedVector{T}) where {T<:BlasFloat} = BLAS.trmv!($uploc, 'N', $isunitc, A.data, b) - mul!(transA::Transpose{<:Any,<:$t{T,<:StridedMatrix}}, b::StridedVector{T}) where {T<:BlasFloat} = + mul2!(transA::Transpose{<:Any,<:$t{T,<:StridedMatrix}}, b::StridedVector{T}) where {T<:BlasFloat} = (A = transA.parent; BLAS.trmv!($uploc, 'T', $isunitc, A.data, b)) - mul!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, b::StridedVector{T}) where {T<:BlasReal} = + mul2!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, b::StridedVector{T}) where {T<:BlasReal} = (A = adjA.parent; BLAS.trmv!($uploc, 'T', $isunitc, A.data, b)) - mul!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, b::StridedVector{T}) where {T<:BlasComplex} = + mul2!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, b::StridedVector{T}) where {T<:BlasComplex} = (A = adjA.parent; BLAS.trmv!($uploc, 'C', $isunitc, A.data, b)) # Matrix multiplication - mul!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasFloat} = + mul2!(A::$t{T,<:StridedMatrix}, B::StridedMatrix{T}) where {T<:BlasFloat} = BLAS.trmm!('L', $uploc, 'N', $isunitc, one(T), A.data, B) - mul!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} = + mul1!(A::StridedMatrix{T}, B::$t{T,<:StridedMatrix}) where {T<:BlasFloat} = BLAS.trmm!('R', $uploc, 'N', $isunitc, one(T), B.data, A) - mul!(transA::Transpose{<:Any,<:$t{T,<:StridedMatrix}}, B::StridedMatrix{T}) where {T<:BlasFloat} = + mul2!(transA::Transpose{<:Any,<:$t{T,<:StridedMatrix}}, B::StridedMatrix{T}) where {T<:BlasFloat} = (A = transA.parent; BLAS.trmm!('L', $uploc, 'T', $isunitc, one(T), A.data, B)) - mul!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, B::StridedMatrix{T}) where {T<:BlasComplex} = + mul2!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, B::StridedMatrix{T}) where {T<:BlasComplex} = (A = adjA.parent; BLAS.trmm!('L', $uploc, 'C', $isunitc, one(T), A.data, B)) - mul!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, B::StridedMatrix{T}) where {T<:BlasReal} = + mul2!(adjA::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}, B::StridedMatrix{T}) where {T<:BlasReal} = (A = adjA.parent; BLAS.trmm!('L', $uploc, 'T', $isunitc, one(T), A.data, B)) - mul!(A::StridedMatrix{T}, transB::Transpose{<:Any,<:$t{T,<:StridedMatrix}}) where {T<:BlasFloat} = + mul1!(A::StridedMatrix{T}, transB::Transpose{<:Any,<:$t{T,<:StridedMatrix}}) where {T<:BlasFloat} = (B = transB.parent; BLAS.trmm!('R', $uploc, 'T', $isunitc, one(T), B.data, A)) - mul!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}) where {T<:BlasComplex} = + mul1!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}) where {T<:BlasComplex} = (B = adjB.parent; BLAS.trmm!('R', $uploc, 'C', $isunitc, one(T), B.data, A)) - mul!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}) where {T<:BlasReal} = + mul1!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:$t{T,<:StridedMatrix}}) where {T<:BlasReal} = (B = adjB.parent; BLAS.trmm!('R', $uploc, 'T', $isunitc, one(T), B.data, A)) # Left division @@ -588,13 +600,13 @@ function eigvecs(A::UnitUpperTriangular{<:BlasFloat,<:StridedMatrix}) LAPACK.trevc!('R', 'A', BlasInt[], triu!(A.data)) end function eigvecs(A::LowerTriangular{<:BlasFloat,<:StridedMatrix}) - LAPACK.trevc!('L', 'A', BlasInt[], adjoint(tril!(A.data))) + LAPACK.trevc!('L', 'A', BlasInt[], copy(tril!(A.data)')) end function eigvecs(A::UnitLowerTriangular{<:BlasFloat,<:StridedMatrix}) for i = 1:size(A, 1) A.data[i,i] = 1 end - LAPACK.trevc!('L', 'A', BlasInt[], adjoint(tril!(A.data))) + LAPACK.trevc!('L', 'A', BlasInt[], copy(tril!(A.data)')) end #################### @@ -649,7 +661,7 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular), end ## Generic triangular multiplication -function mul!(A::UpperTriangular, B::StridedVecOrMat) +function mul2!(A::UpperTriangular, B::StridedVecOrMat) m, n = size(B, 1), size(B, 2) if m != size(A, 1) throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m")) @@ -665,7 +677,8 @@ function mul!(A::UpperTriangular, B::StridedVecOrMat) end B end -function mul!(A::UnitUpperTriangular, B::StridedVecOrMat) + +function mul2!(A::UnitUpperTriangular, B::StridedVecOrMat) m, n = size(B, 1), size(B, 2) if m != size(A, 1) throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m")) @@ -682,7 +695,7 @@ function mul!(A::UnitUpperTriangular, B::StridedVecOrMat) B end -function mul!(A::LowerTriangular, B::StridedVecOrMat) +function mul2!(A::LowerTriangular, B::StridedVecOrMat) m, n = size(B, 1), size(B, 2) if m != size(A, 1) throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m")) @@ -698,7 +711,7 @@ function mul!(A::LowerTriangular, B::StridedVecOrMat) end B end -function mul!(A::UnitLowerTriangular, B::StridedVecOrMat) +function mul2!(A::UnitLowerTriangular, B::StridedVecOrMat) m, n = size(B, 1), size(B, 2) if m != size(A, 1) throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m")) @@ -715,7 +728,7 @@ function mul!(A::UnitLowerTriangular, B::StridedVecOrMat) B end -function mul!(adjA::Adjoint{<:Any,<:UpperTriangular}, B::StridedVecOrMat) +function mul2!(adjA::Adjoint{<:Any,<:UpperTriangular}, B::StridedVecOrMat) A = adjA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -732,7 +745,8 @@ function mul!(adjA::Adjoint{<:Any,<:UpperTriangular}, B::StridedVecOrMat) end B end -function mul!(adjA::Adjoint{<:Any,<:UnitUpperTriangular}, B::StridedVecOrMat) + +function mul2!(adjA::Adjoint{<:Any,<:UnitUpperTriangular}, B::StridedVecOrMat) A = adjA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -750,7 +764,7 @@ function mul!(adjA::Adjoint{<:Any,<:UnitUpperTriangular}, B::StridedVecOrMat) B end -function mul!(adjA::Adjoint{<:Any,<:LowerTriangular}, B::StridedVecOrMat) +function mul2!(adjA::Adjoint{<:Any,<:LowerTriangular}, B::StridedVecOrMat) A = adjA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -767,7 +781,7 @@ function mul!(adjA::Adjoint{<:Any,<:LowerTriangular}, B::StridedVecOrMat) end B end -function mul!(adjA::Adjoint{<:Any,<:UnitLowerTriangular}, B::StridedVecOrMat) +function mul2!(adjA::Adjoint{<:Any,<:UnitLowerTriangular}, B::StridedVecOrMat) A = adjA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -785,7 +799,7 @@ function mul!(adjA::Adjoint{<:Any,<:UnitLowerTriangular}, B::StridedVecOrMat) B end -function mul!(transA::Transpose{<:Any,<:UpperTriangular}, B::StridedVecOrMat) +function mul2!(transA::Transpose{<:Any,<:UpperTriangular}, B::StridedVecOrMat) A = transA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -793,16 +807,16 @@ function mul!(transA::Transpose{<:Any,<:UpperTriangular}, B::StridedVecOrMat) end for j = 1:n for i = m:-1:1 - Bij = Transpose(A.data[i,i]) * B[i,j] + Bij = transpose(A.data[i,i]) * B[i,j] for k = 1:i - 1 - Bij += Transpose(A.data[k,i]) * B[k,j] + Bij += transpose(A.data[k,i]) * B[k,j] end B[i,j] = Bij end end B end -function mul!(transA::Transpose{<:Any,<:UnitUpperTriangular}, B::StridedVecOrMat) +function mul2!(transA::Transpose{<:Any,<:UnitUpperTriangular}, B::StridedVecOrMat) A = transA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -812,7 +826,7 @@ function mul!(transA::Transpose{<:Any,<:UnitUpperTriangular}, B::StridedVecOrMat for i = m:-1:1 Bij = B[i,j] for k = 1:i - 1 - Bij += Transpose(A.data[k,i]) * B[k,j] + Bij += transpose(A.data[k,i]) * B[k,j] end B[i,j] = Bij end @@ -820,7 +834,7 @@ function mul!(transA::Transpose{<:Any,<:UnitUpperTriangular}, B::StridedVecOrMat B end -function mul!(transA::Transpose{<:Any,<:LowerTriangular}, B::StridedVecOrMat) +function mul2!(transA::Transpose{<:Any,<:LowerTriangular}, B::StridedVecOrMat) A = transA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -828,16 +842,16 @@ function mul!(transA::Transpose{<:Any,<:LowerTriangular}, B::StridedVecOrMat) end for j = 1:n for i = 1:m - Bij = Transpose(A.data[i,i]) * B[i,j] + Bij = transpose(A.data[i,i]) * B[i,j] for k = i + 1:m - Bij += Transpose(A.data[k,i]) * B[k,j] + Bij += transpose(A.data[k,i]) * B[k,j] end B[i,j] = Bij end end B end -function mul!(transA::Transpose{<:Any,<:UnitLowerTriangular}, B::StridedVecOrMat) +function mul2!(transA::Transpose{<:Any,<:UnitLowerTriangular}, B::StridedVecOrMat) A = transA.parent m, n = size(B, 1), size(B, 2) if m != size(A, 1) @@ -847,7 +861,7 @@ function mul!(transA::Transpose{<:Any,<:UnitLowerTriangular}, B::StridedVecOrMat for i = 1:m Bij = B[i,j] for k = i + 1:m - Bij += Transpose(A.data[k,i]) * B[k,j] + Bij += transpose(A.data[k,i]) * B[k,j] end B[i,j] = Bij end @@ -855,7 +869,7 @@ function mul!(transA::Transpose{<:Any,<:UnitLowerTriangular}, B::StridedVecOrMat B end -function mul!(A::StridedMatrix, B::UpperTriangular) +function mul1!(A::StridedMatrix, B::UpperTriangular) m, n = size(A) if size(B, 1) != n throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(size(B,1))")) @@ -871,7 +885,7 @@ function mul!(A::StridedMatrix, B::UpperTriangular) end A end -function mul!(A::StridedMatrix, B::UnitUpperTriangular) +function mul1!(A::StridedMatrix, B::UnitUpperTriangular) m, n = size(A) if size(B, 1) != n throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(size(B,1))")) @@ -888,7 +902,7 @@ function mul!(A::StridedMatrix, B::UnitUpperTriangular) A end -function mul!(A::StridedMatrix, B::LowerTriangular) +function mul1!(A::StridedMatrix, B::LowerTriangular) m, n = size(A) if size(B, 1) != n throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(size(B,1))")) @@ -904,7 +918,7 @@ function mul!(A::StridedMatrix, B::LowerTriangular) end A end -function mul!(A::StridedMatrix, B::UnitLowerTriangular) +function mul1!(A::StridedMatrix, B::UnitLowerTriangular) m, n = size(A) if size(B, 1) != n throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(size(B,1))")) @@ -921,7 +935,7 @@ function mul!(A::StridedMatrix, B::UnitLowerTriangular) A end -function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UpperTriangular}) +function mul1!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UpperTriangular}) B = adjB.parent m, n = size(A) if size(B, 1) != n @@ -938,7 +952,8 @@ function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UpperTriangular}) end A end -function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UnitUpperTriangular}) + +function mul1!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UnitUpperTriangular}) B = adjB.parent m, n = size(A) if size(B, 1) != n @@ -956,7 +971,7 @@ function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UnitUpperTriangular}) A end -function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:LowerTriangular}) +function mul1!(A::StridedMatrix, adjB::Adjoint{<:Any,<:LowerTriangular}) B = adjB.parent m, n = size(A) if size(B, 1) != n @@ -973,7 +988,8 @@ function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:LowerTriangular}) end A end -function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UnitLowerTriangular}) + +function mul1!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UnitLowerTriangular}) B = adjB.parent m, n = size(A) if size(B, 1) != n @@ -991,7 +1007,7 @@ function mul!(A::StridedMatrix, adjB::Adjoint{<:Any,<:UnitLowerTriangular}) A end -function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:UpperTriangular}) +function mul1!(A::StridedMatrix, transB::Transpose{<:Any,<:UpperTriangular}) B = transB.parent m, n = size(A) if size(B, 1) != n @@ -999,16 +1015,16 @@ function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:UpperTriangular}) end for i = 1:m for j = 1:n - Aij = A[i,j] * Transpose(B.data[j,j]) + Aij = A[i,j] * transpose(B.data[j,j]) for k = j + 1:n - Aij += A[i,k] * Transpose(B.data[j,k]) + Aij += A[i,k] * transpose(B.data[j,k]) end A[i,j] = Aij end end A end -function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitUpperTriangular}) +function mul1!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitUpperTriangular}) B = transB.parent m, n = size(A) if size(B, 1) != n @@ -1018,7 +1034,7 @@ function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitUpperTriangular}) for j = 1:n Aij = A[i,j] for k = j + 1:n - Aij += A[i,k] * Transpose(B.data[j,k]) + Aij += A[i,k] * transpose(B.data[j,k]) end A[i,j] = Aij end @@ -1026,7 +1042,7 @@ function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitUpperTriangular}) A end -function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:LowerTriangular}) +function mul1!(A::StridedMatrix, transB::Transpose{<:Any,<:LowerTriangular}) B = transB.parent m, n = size(A) if size(B, 1) != n @@ -1034,16 +1050,17 @@ function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:LowerTriangular}) end for i = 1:m for j = n:-1:1 - Aij = A[i,j] * Transpose(B.data[j,j]) + Aij = A[i,j] * transpose(B.data[j,j]) for k = 1:j - 1 - Aij += A[i,k] * Transpose(B.data[j,k]) + Aij += A[i,k] * transpose(B.data[j,k]) end A[i,j] = Aij end end A end -function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitLowerTriangular}) + +function mul1!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitLowerTriangular}) B = transB.parent m, n = size(A) if size(B, 1) != n @@ -1053,7 +1070,7 @@ function mul!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitLowerTriangular}) for j = n:-1:1 Aij = A[i,j] for k = 1:j - 1 - Aij += A[i,k] * Transpose(B.data[j,k]) + Aij += A[i,k] * transpose(B.data[j,k]) end A[i,j] = Aij end @@ -1125,7 +1142,7 @@ function naivesub!(A::UnitLowerTriangular, b::AbstractVector, x::AbstractVector end # in the following transpose and conjugate transpose naive substitution variants, # accumulating in z rather than b[j] significantly improves performance as of Dec 2015 -function ldiv!(transA::Transpose{<:Any,<:LowerTriangular}, b::AbstractVector, x::AbstractVector = b) +function ldiv!(transA::Transpose{<:Any,<:LowerTriangular}, b::AbstractVector, x::AbstractVector) A = transA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1141,7 +1158,9 @@ function ldiv!(transA::Transpose{<:Any,<:LowerTriangular}, b::AbstractVector, x: end x end -function ldiv!(transA::Transpose{<:Any,<:UnitLowerTriangular}, b::AbstractVector, x::AbstractVector = b) +ldiv!(transA::Transpose{<:Any,<:LowerTriangular}, b::AbstractVector) = ldiv!(transA, b, b) + +function ldiv!(transA::Transpose{<:Any,<:UnitLowerTriangular}, b::AbstractVector, x::AbstractVector) A = transA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1156,7 +1175,9 @@ function ldiv!(transA::Transpose{<:Any,<:UnitLowerTriangular}, b::AbstractVector end x end -function ldiv!(transA::Transpose{<:Any,<:UpperTriangular}, b::AbstractVector, x::AbstractVector = b) +ldiv!(transA::Transpose{<:Any,<:UnitLowerTriangular}, b::AbstractVector) = ldiv!(transA, b, b) + +function ldiv!(transA::Transpose{<:Any,<:UpperTriangular}, b::AbstractVector, x::AbstractVector) A = transA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1172,7 +1193,9 @@ function ldiv!(transA::Transpose{<:Any,<:UpperTriangular}, b::AbstractVector, x: end x end -function ldiv!(transA::Transpose{<:Any,<:UnitUpperTriangular}, b::AbstractVector, x::AbstractVector = b) +ldiv!(transA::Transpose{<:Any,<:UpperTriangular}, b::AbstractVector) = ldiv!(transA, b, b) + +function ldiv!(transA::Transpose{<:Any,<:UnitUpperTriangular}, b::AbstractVector, x::AbstractVector) A = transA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1187,7 +1210,9 @@ function ldiv!(transA::Transpose{<:Any,<:UnitUpperTriangular}, b::AbstractVector end x end -function ldiv!(adjA::Adjoint{<:Any,<:LowerTriangular}, b::AbstractVector, x::AbstractVector = b) +ldiv!(transA::Transpose{<:Any,<:UnitUpperTriangular}, b::AbstractVector) = ldiv!(transA, b, b) + +function ldiv!(adjA::Adjoint{<:Any,<:LowerTriangular}, b::AbstractVector, x::AbstractVector) A = adjA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1203,7 +1228,9 @@ function ldiv!(adjA::Adjoint{<:Any,<:LowerTriangular}, b::AbstractVector, x::Abs end x end -function ldiv!(adjA::Adjoint{<:Any,<:UnitLowerTriangular}, b::AbstractVector, x::AbstractVector = b) +ldiv!(adjA::Adjoint{<:Any,<:LowerTriangular}, b::AbstractVector) = ldiv!(adjA, b, b) + +function ldiv!(adjA::Adjoint{<:Any,<:UnitLowerTriangular}, b::AbstractVector, x::AbstractVector) A = adjA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1218,7 +1245,9 @@ function ldiv!(adjA::Adjoint{<:Any,<:UnitLowerTriangular}, b::AbstractVector, x: end x end -function ldiv!(adjA::Adjoint{<:Any,<:UpperTriangular}, b::AbstractVector, x::AbstractVector = b) +ldiv!(adjA::Adjoint{<:Any,<:UnitLowerTriangular}, b::AbstractVector) = ldiv!(adjA, b, b) + +function ldiv!(adjA::Adjoint{<:Any,<:UpperTriangular}, b::AbstractVector, x::AbstractVector) A = adjA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1234,7 +1263,9 @@ function ldiv!(adjA::Adjoint{<:Any,<:UpperTriangular}, b::AbstractVector, x::Abs end x end -function ldiv!(adjA::Adjoint{<:Any,<:UnitUpperTriangular}, b::AbstractVector, x::AbstractVector = b) +ldiv!(adjA::Adjoint{<:Any,<:UpperTriangular}, b::AbstractVector) = ldiv!(adjA, b, b) + +function ldiv!(adjA::Adjoint{<:Any,<:UnitUpperTriangular}, b::AbstractVector, x::AbstractVector) A = adjA.parent n = size(A, 1) if !(n == length(b) == length(x)) @@ -1249,6 +1280,7 @@ function ldiv!(adjA::Adjoint{<:Any,<:UnitUpperTriangular}, b::AbstractVector, x: end x end +ldiv!(adjA::Adjoint{<:Any,<:UnitUpperTriangular}, b::AbstractVector) = ldiv!(adjA, b, b) function rdiv!(A::StridedMatrix, B::UpperTriangular) m, n = size(A) @@ -1396,9 +1428,9 @@ function rdiv!(A::StridedMatrix, transB::Transpose{<:Any,<:UpperTriangular}) for j = n:-1:1 Aij = A[i,j] for k = j + 1:n - Aij -= A[i,k] * Transpose(B.data[j,k]) + Aij -= A[i,k] * transpose(B.data[j,k]) end - A[i,j] = Aij / Transpose(B.data[j,j]) + A[i,j] = Aij / transpose(B.data[j,j]) end end A @@ -1413,7 +1445,7 @@ function rdiv!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitUpperTriangular}) for j = n:-1:1 Aij = A[i,j] for k = j + 1:n - Aij -= A[i,k] * Transpose(B.data[j,k]) + Aij -= A[i,k] * transpose(B.data[j,k]) end A[i,j] = Aij end @@ -1431,9 +1463,9 @@ function rdiv!(A::StridedMatrix, transB::Transpose{<:Any,<:LowerTriangular}) for j = 1:n Aij = A[i,j] for k = 1:j - 1 - Aij -= A[i,k] * Transpose(B.data[j,k]) + Aij -= A[i,k] * transpose(B.data[j,k]) end - A[i,j] = Aij / Transpose(B.data[j,j]) + A[i,j] = Aij / transpose(B.data[j,j]) end end A @@ -1448,7 +1480,7 @@ function rdiv!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitLowerTriangular}) for j = 1:n Aij = A[i,j] for k = 1:j - 1 - Aij -= A[i,k] * Transpose(B.data[j,k]) + Aij -= A[i,k] * transpose(B.data[j,k]) end A[i,j] = Aij end @@ -1456,44 +1488,44 @@ function rdiv!(A::StridedMatrix, transB::Transpose{<:Any,<:UnitLowerTriangular}) A end -mul!(adjA::Adjoint{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}, B::UpperTriangular) = - (A = adjA.parent; UpperTriangular(mul!(Adjoint(A), triu!(B.data)))) -mul!(adjA::Adjoint{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}, B::LowerTriangular) = - (A = adjA.parent; LowerTriangular(mul!(Adjoint(A), tril!(B.data)))) -mul!(transA::Transpose{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}, B::UpperTriangular) = - (A = transA.parent; UpperTriangular(mul!(Transpose(A), triu!(B.data)))) -mul!(transA::Transpose{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}, B::LowerTriangular) = - (A = transA.parent; LowerTriangular(mul!(Transpose(A), tril!(B.data)))) +mul2!(adjA::Adjoint{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}, B::UpperTriangular) = + (A = adjA.parent; UpperTriangular(mul2!(adjoint(A), triu!(B.data)))) +mul2!(adjA::Adjoint{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}, B::LowerTriangular) = + (A = adjA.parent; LowerTriangular(mul2!(adjoint(A), tril!(B.data)))) +mul2!(transA::Transpose{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}, B::UpperTriangular) = + (A = transA.parent; UpperTriangular(mul2!(transpose(A), triu!(B.data)))) +mul2!(transA::Transpose{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}, B::LowerTriangular) = + (A = transA.parent; LowerTriangular(mul2!(transpose(A), tril!(B.data)))) ldiv!(adjA::Adjoint{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}, B::UpperTriangular) = - (A = adjA.parent; UpperTriangular(ldiv!(Adjoint(A), triu!(B.data)))) + (A = adjA.parent; UpperTriangular(ldiv!(adjoint(A), triu!(B.data)))) ldiv!(adjA::Adjoint{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}, B::LowerTriangular) = - (A = adjA.parent; LowerTriangular(ldiv!(Adjoint(A), tril!(B.data)))) + (A = adjA.parent; LowerTriangular(ldiv!(adjoint(A), tril!(B.data)))) ldiv!(transA::Transpose{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}, B::UpperTriangular) = - (A = transA.parent; UpperTriangular(ldiv!(Transpose(A), triu!(B.data)))) + (A = transA.parent; UpperTriangular(ldiv!(transpose(A), triu!(B.data)))) ldiv!(transA::Transpose{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}, B::LowerTriangular) = - (A = transA.parent; LowerTriangular(ldiv!(Transpose(A), tril!(B.data)))) + (A = transA.parent; LowerTriangular(ldiv!(transpose(A), tril!(B.data)))) rdiv!(A::UpperTriangular, B::Union{UpperTriangular,UnitUpperTriangular}) = UpperTriangular(rdiv!(triu!(A.data), B)) rdiv!(A::LowerTriangular, B::Union{LowerTriangular,UnitLowerTriangular}) = LowerTriangular(rdiv!(tril!(A.data), B)) -mul!(A::UpperTriangular, adjB::Adjoint{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}) = - (B = adjB.parent; UpperTriangular(mul!(triu!(A.data), Adjoint(B)))) -mul!(A::LowerTriangular, adjB::Adjoint{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}) = - (B = adjB.parent; LowerTriangular(mul!(tril!(A.data), Adjoint(B)))) -mul!(A::UpperTriangular, transB::Transpose{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}) = - (B = transB.parent; UpperTriangular(mul!(triu!(A.data), Transpose(B)))) -mul!(A::LowerTriangular, transB::Transpose{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}) = - (B = transB.parent; LowerTriangular(mul!(tril!(A.data), Transpose(B)))) +mul1!(A::UpperTriangular, adjB::Adjoint{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}) = + (B = adjB.parent; UpperTriangular(mul1!(triu!(A.data), adjoint(B)))) +mul1!(A::LowerTriangular, adjB::Adjoint{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}) = + (B = adjB.parent; LowerTriangular(mul1!(tril!(A.data), adjoint(B)))) +mul1!(A::UpperTriangular, transB::Transpose{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}) = + (B = transB.parent; UpperTriangular(mul1!(triu!(A.data), transpose(B)))) +mul1!(A::LowerTriangular, transB::Transpose{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}) = + (B = transB.parent; LowerTriangular(mul1!(tril!(A.data), transpose(B)))) rdiv!(A::UpperTriangular, adjB::Adjoint{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}) = - (B = adjB.parent; UpperTriangular(rdiv!(triu!(A.data), Adjoint(B)))) + (B = adjB.parent; UpperTriangular(rdiv!(triu!(A.data), adjoint(B)))) rdiv!(A::LowerTriangular, adjB::Adjoint{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}) = - (B = adjB.parent; LowerTriangular(rdiv!(tril!(A.data), Adjoint(B)))) + (B = adjB.parent; LowerTriangular(rdiv!(tril!(A.data), adjoint(B)))) rdiv!(A::UpperTriangular, transB::Transpose{<:Any,<:Union{LowerTriangular,UnitLowerTriangular}}) = - (B = transB.parent; UpperTriangular(rdiv!(triu!(A.data), Transpose(B)))) + (B = transB.parent; UpperTriangular(rdiv!(triu!(A.data), transpose(B)))) rdiv!(A::LowerTriangular, transB::Transpose{<:Any,<:Union{UpperTriangular,UnitUpperTriangular}}) = - (B = transB.parent; LowerTriangular(rdiv!(tril!(A.data), Transpose(B)))) + (B = transB.parent; LowerTriangular(rdiv!(tril!(A.data), transpose(B)))) # Promotion ## Promotion methods in matmul don't apply to triangular multiplication since @@ -1504,84 +1536,84 @@ rdiv!(A::LowerTriangular, transB::Transpose{<:Any,<:Union{UpperTriangular,UnitUp ## Some Triangular-Triangular cases. We might want to write taylored methods ## for these cases, but I'm not sure it is worth it. -(*)(A::Union{Tridiagonal,SymTridiagonal}, B::AbstractTriangular) = mul!(Matrix(A), B) +(*)(A::Union{Tridiagonal,SymTridiagonal}, B::AbstractTriangular) = mul1!(Matrix(A), B) -for (f1, f2) in ((:*, :mul!), (:\, :ldiv!)) +for (f, f2!) in ((:*, :mul2!), (:\, :ldiv!)) @eval begin - function ($f1)(A::LowerTriangular, B::LowerTriangular) - TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + - ($f1)(zero(eltype(A)), zero(eltype(B)))) + function ($f)(A::LowerTriangular, B::LowerTriangular) + TAB = typeof(($f)(zero(eltype(A)), zero(eltype(B))) + + ($f)(zero(eltype(A)), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) + return LowerTriangular($f2!(convert(AbstractMatrix{TAB}, A), BB)) end - function $(f1)(A::UnitLowerTriangular, B::LowerTriangular) + function $(f)(A::UnitLowerTriangular, B::LowerTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) + return LowerTriangular($f2!(convert(AbstractMatrix{TAB}, A), BB)) end - function ($f1)(A::UpperTriangular, B::UpperTriangular) - TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + - ($f1)(zero(eltype(A)), zero(eltype(B)))) + function ($f)(A::UpperTriangular, B::UpperTriangular) + TAB = typeof(($f)(zero(eltype(A)), zero(eltype(B))) + + ($f)(zero(eltype(A)), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) + return UpperTriangular($f2!(convert(AbstractMatrix{TAB}, A), BB)) end - function ($f1)(A::UnitUpperTriangular, B::UpperTriangular) + function ($f)(A::UnitUpperTriangular, B::UpperTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) + return UpperTriangular($f2!(convert(AbstractMatrix{TAB}, A), BB)) end end end -for (ipop, op, xform) in ( - (:mul!, :*, :Adjoint), - (:mul!, :*, :Transpose), - (:ldiv!, :\, :Adjoint), - (:ldiv!, :\, :Transpose)) +for (ipop, op, xformtype, xformop) in ( + (:mul2!, :*, :Adjoint, :adjoint), + (:mul2!, :*, :Transpose, :transpose), + (:ldiv!, :\, :Adjoint, :adjoint), + (:ldiv!, :\, :Transpose, :transpose)) @eval begin - function ($op)(xformA::($xform){<:Any,<:UpperTriangular}, B::LowerTriangular) + function ($op)(xformA::($xformtype){<:Any,<:UpperTriangular}, B::LowerTriangular) A = xformA.parent - TAB = typeof(($op)($xform(zero(eltype(A))), zero(eltype(B))) + - ($op)($xform(zero(eltype(A))), zero(eltype(B)))) + TAB = typeof(($op)($xformop(zero(eltype(A))), zero(eltype(B))) + + ($op)($xformop(zero(eltype(A))), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return LowerTriangular(($ipop)($xform(convert(AbstractMatrix{TAB}, A)), BB)) + return LowerTriangular(($ipop)($xformop(convert(AbstractMatrix{TAB}, A)), BB)) end - function ($op)(xformA::($xform){<:Any,<:UnitUpperTriangular}, B::LowerTriangular) + function ($op)(xformA::($xformtype){<:Any,<:UnitUpperTriangular}, B::LowerTriangular) A = xformA.parent TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return LowerTriangular($ipop($xform(convert(AbstractMatrix{TAB}, A)), BB)) + return LowerTriangular($ipop($xformop(convert(AbstractMatrix{TAB}, A)), BB)) end - function ($op)(xformA::($xform){<:Any,<:LowerTriangular}, B::UpperTriangular) + function ($op)(xformA::($xformtype){<:Any,<:LowerTriangular}, B::UpperTriangular) A = xformA.parent - TAB = typeof(($op)($xform(zero(eltype(A))), zero(eltype(B))) + - ($op)($xform(zero(eltype(A))), zero(eltype(B)))) + TAB = typeof(($op)($xformop(zero(eltype(A))), zero(eltype(B))) + + ($op)($xformop(zero(eltype(A))), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return UpperTriangular($ipop($xform(convert(AbstractMatrix{TAB}, A)), BB)) + return UpperTriangular($ipop($xformop(convert(AbstractMatrix{TAB}, A)), BB)) end - function ($op)(xformA::($xform){<:Any,<:UnitLowerTriangular}, B::UpperTriangular) + function ($op)(xformA::($xformtype){<:Any,<:UnitLowerTriangular}, B::UpperTriangular) A = xformA.parent TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - return UpperTriangular($ipop($xform(convert(AbstractMatrix{TAB}, A)), BB)) + return UpperTriangular($ipop($xformop(convert(AbstractMatrix{TAB}, A)), BB)) end end end @@ -1615,71 +1647,70 @@ function (/)(A::UpperTriangular, B::UnitUpperTriangular) return UpperTriangular(rdiv!(AA, convert(AbstractMatrix{TAB}, B))) end -for (ipop, op, xform) in ( - (:mul!, :*, :Adjoint), - (:mul!, :*, :Transpose), - (:rdiv!, :/, :Adjoint), - (:rdiv!, :/, :Transpose)) +for (ipop, op, xformtype, xformop) in ( + (:mul1!, :*, :Adjoint, :adjoint), + (:mul1!, :*, :Transpose, :transpose), + (:rdiv!, :/, :Adjoint, :adjoint), + (:rdiv!, :/, :Transpose, :transpose)) @eval begin - function ($op)(A::LowerTriangular, xformB::($xform){<:Any,<:UpperTriangular}) + function ($op)(A::LowerTriangular, xformB::($xformtype){<:Any,<:UpperTriangular}) B = xformB.parent - TAB = typeof(($op)(zero(eltype(A)), $xform(zero(eltype(B)))) + - ($op)(zero(eltype(A)), $xform(zero(eltype(B))))) + TAB = typeof(($op)(zero(eltype(A)), $xformop(zero(eltype(B)))) + + ($op)(zero(eltype(A)), $xformop(zero(eltype(B))))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - return LowerTriangular($ipop(AA, $xform(convert(AbstractMatrix{TAB}, B)))) + return LowerTriangular($ipop(AA, $xformop(convert(AbstractMatrix{TAB}, B)))) end - function ($op)(A::LowerTriangular, xformB::($xform){<:Any,<:UnitUpperTriangular}) + function ($op)(A::LowerTriangular, xformB::($xformtype){<:Any,<:UnitUpperTriangular}) B = xformB.parent TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - return LowerTriangular($ipop(AA, $xform(convert(AbstractMatrix{TAB}, B)))) + return LowerTriangular($ipop(AA, $xformop(convert(AbstractMatrix{TAB}, B)))) end - function ($op)(A::UpperTriangular, xformB::($xform){<:Any,<:LowerTriangular}) + function ($op)(A::UpperTriangular, xformB::($xformtype){<:Any,<:LowerTriangular}) B = xformB.parent - TAB = typeof(($op)(zero(eltype(A)), $xform(zero(eltype(B)))) + - ($op)(zero(eltype(A)), $xform(zero(eltype(B))))) + TAB = typeof(($op)(zero(eltype(A)), $xformop(zero(eltype(B)))) + + ($op)(zero(eltype(A)), $xformop(zero(eltype(B))))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - return UpperTriangular($ipop(AA, $xform(convert(AbstractMatrix{TAB}, B)))) + return UpperTriangular($ipop(AA, $xformop(convert(AbstractMatrix{TAB}, B)))) end - function ($op)(A::UpperTriangular, xformB::($xform){<:Any,<:UnitLowerTriangular}) + function ($op)(A::UpperTriangular, xformB::($xformtype){<:Any,<:UnitLowerTriangular}) B = xformB.parent TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - return UpperTriangular($ipop(AA, $xform(convert(AbstractMatrix{TAB}, B)))) + return UpperTriangular($ipop(AA, $xformop(convert(AbstractMatrix{TAB}, B)))) end end end ## The general promotion methods - function *(A::AbstractTriangular, B::AbstractTriangular) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - mul!(convert(AbstractArray{TAB}, A), BB) + mul2!(convert(AbstractArray{TAB}, A), BB) end function *(adjA::Adjoint{<:Any,<:AbstractTriangular}, B::AbstractTriangular) A = adjA.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - mul!(Adjoint(convert(AbstractArray{TAB}, A)), BB) + mul2!(adjoint(convert(AbstractArray{TAB}, A)), BB) end function *(transA::Transpose{<:Any,<:AbstractTriangular}, B::AbstractTriangular) A = transA.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - mul!(Transpose(convert(AbstractArray{TAB}, A)), BB) + mul2!(transpose(convert(AbstractArray{TAB}, A)), BB) end function *(A::AbstractTriangular, adjB::Adjoint{<:Any,<:AbstractTriangular}) @@ -1687,14 +1718,14 @@ function *(A::AbstractTriangular, adjB::Adjoint{<:Any,<:AbstractTriangular}) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - mul!(AA, Adjoint(convert(AbstractArray{TAB}, B))) + mul1!(AA, adjoint(convert(AbstractArray{TAB}, B))) end function *(A::AbstractTriangular, transB::Transpose{<:Any,<:AbstractTriangular}) B = transB.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - mul!(AA, Transpose(convert(AbstractArray{TAB}, B))) + mul1!(AA, transpose(convert(AbstractArray{TAB}, B))) end for mat in (:AbstractVector, :AbstractMatrix) @@ -1704,21 +1735,21 @@ for mat in (:AbstractVector, :AbstractMatrix) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - mul!(convert(AbstractArray{TAB}, A), BB) + mul2!(convert(AbstractArray{TAB}, A), BB) end function *(adjA::Adjoint{<:Any,<:AbstractTriangular}, B::$mat) A = adjA.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - mul!(Adjoint(convert(AbstractArray{TAB}, A)), BB) + mul2!(adjoint(convert(AbstractArray{TAB}, A)), BB) end function *(transA::Transpose{<:Any,<:AbstractTriangular}, B::$mat) A = transA.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - mul!(Transpose(convert(AbstractArray{TAB}, A)), BB) + mul2!(transpose(convert(AbstractArray{TAB}, A)), BB) end end ### Left division with triangle to the left hence rhs cannot be transposed. No quotients. @@ -1734,14 +1765,14 @@ for mat in (:AbstractVector, :AbstractMatrix) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - ldiv!(Adjoint(convert(AbstractArray{TAB}, A)), BB) + ldiv!(adjoint(convert(AbstractArray{TAB}, A)), BB) end function \(transA::Transpose{<:Any,<:Union{UnitUpperTriangular,UnitLowerTriangular}}, B::$mat) A = transA.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - ldiv!(Transpose(convert(AbstractArray{TAB}, A)), BB) + ldiv!(transpose(convert(AbstractArray{TAB}, A)), BB) end end ### Left division with triangle to the left hence rhs cannot be transposed. Quotients. @@ -1757,14 +1788,14 @@ for mat in (:AbstractVector, :AbstractMatrix) TAB = typeof((zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B)))/one(eltype(A))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - ldiv!(Adjoint(convert(AbstractArray{TAB}, A)), BB) + ldiv!(adjoint(convert(AbstractArray{TAB}, A)), BB) end function \(transA::Transpose{<:Any,<:Union{UpperTriangular,LowerTriangular}}, B::$mat) A = transA.parent TAB = typeof((zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B)))/one(eltype(A))) BB = similar(B, TAB, size(B)) copyto!(BB, B) - ldiv!(Transpose(convert(AbstractArray{TAB}, A)), BB) + ldiv!(transpose(convert(AbstractArray{TAB}, A)), BB) end end ### Right division with triangle to the right hence lhs cannot be transposed. No quotients. @@ -1780,14 +1811,14 @@ for mat in (:AbstractVector, :AbstractMatrix) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - rdiv!(AA, Adjoint(convert(AbstractArray{TAB}, B))) + rdiv!(AA, adjoint(convert(AbstractArray{TAB}, B))) end function /(A::$mat, transB::Transpose{<:Any,<:Union{UnitUpperTriangular, UnitLowerTriangular}}) B = transB.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - rdiv!(AA, Transpose(convert(AbstractArray{TAB}, B))) + rdiv!(AA, transpose(convert(AbstractArray{TAB}, B))) end end ### Right division with triangle to the right hence lhs cannot be transposed. Quotients. @@ -1803,14 +1834,14 @@ for mat in (:AbstractVector, :AbstractMatrix) TAB = typeof((zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B)))/one(eltype(A))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - rdiv!(AA, Adjoint(convert(AbstractArray{TAB}, B))) + rdiv!(AA, adjoint(convert(AbstractArray{TAB}, B))) end function /(A::$mat, transB::Transpose{<:Any,<:Union{UpperTriangular,LowerTriangular}}) B = transB.parent TAB = typeof((zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B)))/one(eltype(A))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - rdiv!(AA, Transpose(convert(AbstractArray{TAB}, B))) + rdiv!(AA, transpose(convert(AbstractArray{TAB}, B))) end end end @@ -1820,27 +1851,27 @@ function *(A::AbstractMatrix, B::AbstractTriangular) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - mul!(AA, convert(AbstractArray{TAB}, B)) + mul1!(AA, convert(AbstractArray{TAB}, B)) end function *(A::AbstractMatrix, adjB::Adjoint{<:Any,<:AbstractTriangular}) B = adjB.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - mul!(AA, Adjoint(convert(AbstractArray{TAB}, B))) + mul1!(AA, adjoint(convert(AbstractArray{TAB}, B))) end function *(A::AbstractMatrix, transB::Transpose{<:Any,<:AbstractTriangular}) B = transB.parent TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copyto!(AA, A) - mul!(AA, Transpose(convert(AbstractArray{TAB}, B))) + mul1!(AA, transpose(convert(AbstractArray{TAB}, B))) end # ambiguity resolution with definitions in linalg/rowvector.jl -*(v::AdjointAbsVec, A::AbstractTriangular) = Adjoint(Adjoint(A) * v.parent) -*(v::TransposeAbsVec, A::AbstractTriangular) = Transpose(Transpose(A) * v.parent) -*(v::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractTriangular}) = Adjoint(A.parent * v.parent) -*(v::TransposeAbsVec, A::Transpose{<:Any,<:AbstractTriangular}) = Transpose(A.parent * v.parent) +*(v::AdjointAbsVec, A::AbstractTriangular) = adjoint(adjoint(A) * v.parent) +*(v::TransposeAbsVec, A::AbstractTriangular) = transpose(transpose(A) * v.parent) +*(v::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractTriangular}) = adjoint(A.parent * v.parent) +*(v::TransposeAbsVec, A::Transpose{<:Any,<:AbstractTriangular}) = transpose(A.parent * v.parent) # If these are not defined, they will fallback to the versions in matmul.jl @@ -1848,16 +1879,16 @@ end # below might compute an unnecessary copy. Eliminating the copy requires adding # all the promotion logic here once again. Since these methods are probably relatively # rare, we chose not to bother for now. -*(adjA::Adjoint{<:Any,<:AbstractMatrix}, B::AbstractTriangular) = (*)(adjoint(adjA.parent), B) -*(transA::Transpose{<:Any,<:AbstractMatrix}, B::AbstractTriangular) = (*)(transpose(transA.parent), B) -*(A::AbstractTriangular, adjB::Adjoint{<:Any,<:AbstractMatrix}) = (*)(A, adjoint(adjB.parent)) -*(A::AbstractTriangular, transB::Transpose{<:Any,<:AbstractMatrix}) = (*)(A, transpose(transB.parent)) -*(adjA::Adjoint{<:Any,<:AbstractTriangular}, adjB::Adjoint{<:Any,<:AbstractTriangular}) = *(adjA, adjoint(adjB.parent)) -*(adjA::Adjoint{<:Any,<:AbstractTriangular}, adjB::Adjoint{<:Any,<:AbstractMatrix}) = *(adjA, adjoint(adjB.parent)) -*(adjA::Adjoint{<:Any,<:AbstractMatrix}, adjB::Adjoint{<:Any,<:AbstractTriangular}) = *(adjoint(adjA.parent), adjB) -*(transA::Transpose{<:Any,<:AbstractTriangular}, transB::Transpose{<:Any,<:AbstractTriangular}) = *(transA, transpose(transB.parent)) -*(transA::Transpose{<:Any,<:AbstractTriangular}, transB::Transpose{<:Any,<:AbstractMatrix}) = *(transA, transpose(transB.parent)) -*(transA::Transpose{<:Any,<:AbstractMatrix}, transB::Transpose{<:Any,<:AbstractTriangular}) = *(transpose(transA.parent), transB) +*(A::Adjoint{<:Any,<:AbstractMatrix}, B::AbstractTriangular) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractMatrix}, B::AbstractTriangular) = copy(A) * B +*(A::AbstractTriangular, B::Adjoint{<:Any,<:AbstractMatrix}) = A * copy(B) +*(A::AbstractTriangular, B::Transpose{<:Any,<:AbstractMatrix}) = A * copy(B) +*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractTriangular}) = A * copy(B) +*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractMatrix}) = A * copy(B) +*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractTriangular}) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractTriangular}) = A * copy(B) +*(A::Transpose{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractMatrix}) = A * copy(B) +*(A::Transpose{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:AbstractTriangular}) = copy(A) * B # Complex matrix power for upper triangular factor, see: # Higham and Lin, "A Schur-Padé algorithm for fractional powers of a Matrix", @@ -1926,7 +1957,7 @@ function powm!(A0::UpperTriangular{<:BlasFloat}, p::Real) scale!(S, normA0^p) return S end -powm(A::LowerTriangular, p::Real) = transpose(powm(transpose(A), p::Real)) +powm(A::LowerTriangular, p::Real) = copy(transpose(powm(copy(transpose(A)), p::Real))) # Complex matrix logarithm for the upper triangular factor, see: # Al-Mohy and Higham, "Improved inverse scaling and squaring algorithms for @@ -2110,7 +2141,7 @@ function log(A0::UpperTriangular{T}) where T<:BlasFloat return UpperTriangular(Y) end -log(A::LowerTriangular) = transpose(log(transpose(A))) +log(A::LowerTriangular) = copy(transpose(log(copy(transpose(A))))) # Auxiliary functions for matrix logarithm and matrix power @@ -2318,8 +2349,8 @@ function sqrt(A::UnitUpperTriangular{T}) where T end return UnitUpperTriangular(R) end -sqrt(A::LowerTriangular) = transpose(sqrt(transpose(A))) -sqrt(A::UnitLowerTriangular) = transpose(sqrt(transpose(A))) +sqrt(A::LowerTriangular) = copy(transpose(sqrt(copy(transpose(A))))) +sqrt(A::UnitLowerTriangular) = copy(transpose(sqrt(copy(transpose(A))))) # Generic eigensystems eigvals(A::AbstractTriangular) = diag(A) @@ -2362,37 +2393,37 @@ end factorize(A::AbstractTriangular) = A # dismabiguation methods: *(AbstractTriangular, Adj/Trans of AbstractVector) -*(A::AbstractTriangular, B::Adjoint{<:Any,<:AbstractVector}) = A * adjoint(B.parent) -*(A::AbstractTriangular, B::Transpose{<:Any,<:AbstractVector}) = A * transpose(B.parent) +*(A::AbstractTriangular, B::Adjoint{<:Any,<:AbstractVector}) = A * copy(B) +*(A::AbstractTriangular, B::Transpose{<:Any,<:AbstractVector}) = A * copy(B) # dismabiguation methods: *(Adj/Trans of AbstractTriangular, Trans/Ajd of AbstractTriangular) -*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractTriangular}) = adjoint(A.parent) * B -*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractTriangular}) = transpose(A.parent) * B +*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractTriangular}) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractTriangular}) = copy(A) * B # dismabiguation methods: *(Adj/Trans of AbstractTriangular, Adj/Trans of AbsVec or AbsMat) -*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVector}) = A * adjoint(B.parent) -*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractMatrix}) = A * transpose(B.parent) -*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVector}) = A * transpose(B.parent) -*(A::Transpose{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVector}) = A * transpose(B.parent) -*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVector}) = A * adjoint(B.parent) -*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractMatrix}) = A * adjoint(B.parent) +*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVector}) = A * copy(B) +*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractMatrix}) = A * copy(B) +*(A::Adjoint{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVector}) = A * copy(B) +*(A::Transpose{<:Any,<:AbstractTriangular}, B::Transpose{<:Any,<:AbstractVector}) = A * copy(B) +*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractVector}) = A * copy(B) +*(A::Transpose{<:Any,<:AbstractTriangular}, B::Adjoint{<:Any,<:AbstractMatrix}) = A * copy(B) # dismabiguation methods: *(Adj/Trans of AbsVec or AbsMat, Adj/Trans of AbstractTriangular) -*(A::Adjoint{<:Any,<:AbstractVector}, B::Transpose{<:Any,<:AbstractTriangular}) = adjoint(A.parent) * B -*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:AbstractTriangular}) = adjoint(A.parent) * B -*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractTriangular}) = transpose(A.parent) * B -*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractTriangular}) = transpose(A.parent) * B +*(A::Adjoint{<:Any,<:AbstractVector}, B::Transpose{<:Any,<:AbstractTriangular}) = copy(A) * B +*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:AbstractTriangular}) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:AbstractTriangular}) = copy(A) * B +*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:AbstractTriangular}) = copy(A) * B # disambiguation methods: /(Adjoint of AbsVec, <:AbstractTriangular) -/(u::AdjointAbsVec, A::Union{LowerTriangular,UpperTriangular}) = Adjoint(Adjoint(A) \ u.parent) -/(u::AdjointAbsVec, A::Union{UnitLowerTriangular,UnitUpperTriangular}) = Adjoint(Adjoint(A) \ u.parent) +/(u::AdjointAbsVec, A::Union{LowerTriangular,UpperTriangular}) = adjoint(adjoint(A) \ u.parent) +/(u::AdjointAbsVec, A::Union{UnitLowerTriangular,UnitUpperTriangular}) = adjoint(adjoint(A) \ u.parent) # disambiguation methods: /(Adjoint of AbsVec, Adj/Trans of <:AbstractTriangular) -/(u::AdjointAbsVec, A::Adjoint{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = Adjoint(A.parent \ u.parent) -/(u::AdjointAbsVec, A::Adjoint{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = Adjoint(A.parent \ u.parent) -/(u::AdjointAbsVec, A::Transpose{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = Adjoint(conj(A.parent) \ u.parent) -/(u::AdjointAbsVec, A::Transpose{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = Adjoint(conj(A.parent) \ u.parent) +/(u::AdjointAbsVec, A::Adjoint{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = adjoint(A.parent \ u.parent) +/(u::AdjointAbsVec, A::Adjoint{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = adjoint(A.parent \ u.parent) +/(u::AdjointAbsVec, A::Transpose{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = adjoint(conj(A.parent) \ u.parent) +/(u::AdjointAbsVec, A::Transpose{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = adjoint(conj(A.parent) \ u.parent) # disambiguation methods: /(Transpose of AbsVec, <:AbstractTriangular) -/(u::TransposeAbsVec, A::Union{LowerTriangular,UpperTriangular}) = Transpose(Transpose(A) \ u.parent) -/(u::TransposeAbsVec, A::Union{UnitLowerTriangular,UnitUpperTriangular}) = Transpose(Transpose(A) \ u.parent) +/(u::TransposeAbsVec, A::Union{LowerTriangular,UpperTriangular}) = transpose(transpose(A) \ u.parent) +/(u::TransposeAbsVec, A::Union{UnitLowerTriangular,UnitUpperTriangular}) = transpose(transpose(A) \ u.parent) # disambiguation methods: /(Transpose of AbsVec, Adj/Trans of <:AbstractTriangular) -/(u::TransposeAbsVec, A::Adjoint{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = Transpose(conj(A.parent) \ u.parent) -/(u::TransposeAbsVec, A::Adjoint{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = Transpose(conj(A.parent) \ u.parent) -/(u::TransposeAbsVec, A::Transpose{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = Transpose(A.parent \ u.parent) -/(u::TransposeAbsVec, A::Transpose{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = Transpose(A.parent \ u.parent) +/(u::TransposeAbsVec, A::Adjoint{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = transpose(conj(A.parent) \ u.parent) +/(u::TransposeAbsVec, A::Adjoint{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = transpose(conj(A.parent) \ u.parent) +/(u::TransposeAbsVec, A::Transpose{<:Any,<:Union{LowerTriangular,UpperTriangular}}) = transpose(A.parent \ u.parent) +/(u::TransposeAbsVec, A::Transpose{<:Any,<:Union{UnitLowerTriangular,UnitUpperTriangular}}) = transpose(A.parent \ u.parent) diff --git a/base/linalg/tridiag.jl b/base/linalg/tridiag.jl index 0bc8448e50c0d..f9d93001b5db3 100644 --- a/base/linalg/tridiag.jl +++ b/base/linalg/tridiag.jl @@ -111,7 +111,8 @@ end # On the other hand, similar(S, [neweltype,] shape...) should yield a sparse matrix. # The first method below effects the former, and the second the latter. similar(S::SymTridiagonal, ::Type{T}) where {T} = SymTridiagonal(similar(S.dv, T), similar(S.ev, T)) -similar(S::SymTridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) +# The method below is moved to SparseArrays for now +# similar(S::SymTridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) #Elementary operations broadcast(::typeof(abs), M::SymTridiagonal) = SymTridiagonal(abs.(M.dv), abs.(M.ev)) @@ -127,8 +128,11 @@ broadcast(::typeof(trunc), ::Type{T}, M::SymTridiagonal) where {T<:Integer} = Sy broadcast(::typeof(floor), ::Type{T}, M::SymTridiagonal) where {T<:Integer} = SymTridiagonal(floor.(T, M.dv), floor.(T, M.ev)) broadcast(::typeof(ceil), ::Type{T}, M::SymTridiagonal) where {T<:Integer} = SymTridiagonal(ceil.(T, M.dv), ceil.(T, M.ev)) -transpose(M::SymTridiagonal) = M #Identity operation -adjoint(M::SymTridiagonal) = conj(M) +transpose(S::SymTridiagonal) = S +adjoint(S::SymTridiagonal{<:Real}) = S +adjoint(S::SymTridiagonal) = Adjoint(S) +Base.copy(S::Adjoint{<:Any,<:SymTridiagonal}) = SymTridiagonal(map(x -> copy.(adjoint.(x)), (S.parent.dv, S.parent.ev))...) +Base.copy(S::Transpose{<:Any,<:SymTridiagonal}) = SymTridiagonal(map(x -> copy.(transpose.(x)), (S.parent.dv, S.parent.ev))...) function diag(M::SymTridiagonal, n::Integer=0) # every branch call similar(..., ::Int) to make sure the @@ -494,7 +498,8 @@ Array(M::Tridiagonal) = Matrix(M) # On the other hand, similar(M, [neweltype,] shape...) should yield a sparse matrix. # The first method below effects the former, and the second the latter. similar(M::Tridiagonal, ::Type{T}) where {T} = Tridiagonal(similar(M.dl, T), similar(M.d, T), similar(M.du, T)) -similar(M::Tridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) +# The method below is moved to SparseArrays for now +# similar(M::Tridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) # Operations on Tridiagonal matrices copyto!(dest::Tridiagonal, src::Tridiagonal) = (copyto!(dest.dl, src.dl); copyto!(dest.d, src.d); copyto!(dest.du, src.du); dest) @@ -519,10 +524,14 @@ broadcast(::typeof(floor), ::Type{T}, M::Tridiagonal) where {T<:Integer} = broadcast(::typeof(ceil), ::Type{T}, M::Tridiagonal) where {T<:Integer} = Tridiagonal(ceil.(T, M.dl), ceil.(T, M.d), ceil.(T, M.du)) -transpose(M::Tridiagonal) = Tridiagonal(M.du, M.d, M.dl) -adjoint(M::Tridiagonal) = conj(transpose(M)) +adjoint(S::Tridiagonal) = Adjoint(S) +transpose(S::Tridiagonal) = Transpose(S) +adjoint(S::Tridiagonal{<:Real}) = Tridiagonal(S.du, S.d, S.dl) +transpose(S::Tridiagonal{<:Number}) = Tridiagonal(S.du, S.d, S.dl) +Base.copy(aS::Adjoint{<:Any,<:Tridiagonal}) = (S = aS.parent; Tridiagonal(map(x -> copy.(adjoint.(x)), (S.du, S.d, S.dl))...)) +Base.copy(tS::Transpose{<:Any,<:Tridiagonal}) = (S = tS.parent; Tridiagonal(map(x -> copy.(transpose.(x)), (S.du, S.d, S.dl))...)) -\(A::Adjoint{<:Any,<:Tridiagonal}, B::Adjoint{<:Any,<:StridedVecOrMat}) = adjoint(A.parent) \ adjoint(B.parent) +\(A::Adjoint{<:Any,<:Tridiagonal}, B::Adjoint{<:Any,<:StridedVecOrMat}) = copy(A) \ copy(B) function diag(M::Tridiagonal{T}, n::Integer=0) where T # every branch call similar(..., ::Int) to make sure the diff --git a/base/logging.jl b/base/logging.jl index 9a8faebf9a797..715b43b5bff73 100644 --- a/base/logging.jl +++ b/base/logging.jl @@ -343,7 +343,7 @@ end # progressively less information. try msg = "Exception while generating log record in module $_module at $filepath:$line" - handle_message(logger, Error, msg, _module, group, id, filepath, line; exception=err) + handle_message(logger, Error, msg, _module, :logevent_error, id, filepath, line; exception=err) catch err2 try # Give up and write to STDERR, in three independent calls to diff --git a/base/markdown/Markdown.jl b/base/markdown/Markdown.jl index 82c14669739a3..7fa7729b00cb5 100644 --- a/base/markdown/Markdown.jl +++ b/base/markdown/Markdown.jl @@ -7,7 +7,6 @@ module Markdown import Base: show, ==, with_output_color import Core: @doc_str -using Base.Unicode: lowercase, ucfirst, isspace include(joinpath("parse", "config.jl")) include(joinpath("parse", "util.jl")) diff --git a/base/markdown/parse/parse.jl b/base/markdown/parse/parse.jl index b9a2f9c1f36c2..a47dcc627f481 100644 --- a/base/markdown/parse/parse.jl +++ b/base/markdown/parse/parse.jl @@ -26,6 +26,7 @@ Base.setindex!(md::MD, args...) = setindex!(md.content, args...) Base.endof(md::MD) = endof(md.content) Base.length(md::MD) = length(md.content) Base.isempty(md::MD) = isempty(md.content) +Base.copy(md::MD) = MD(copy(md.content), copy(md.meta)) ==(a::MD, b::MD) = (html(a) == html(b)) diff --git a/base/markdown/render/terminal/formatting.jl b/base/markdown/render/terminal/formatting.jl index d8b3b61158720..866fd7e625729 100644 --- a/base/markdown/render/terminal/formatting.jl +++ b/base/markdown/render/terminal/formatting.jl @@ -44,16 +44,3 @@ end print_wrapped(f::Function, io::IO, args...; kws...) = print_wrapped(io, f, args...; kws...) -function print_centred(io::IO, s...; columns = 80, width = columns) - lines = wrapped_lines(io, s..., width = width) - for line in lines - print(io, " "^(div(columns-ansi_length(line), 2))) - println(io, line) - end - length(lines), length(pre) + length(lines[end]) -end - -function centred(s, columns) - pad = div(columns - ansi_length(s), 2) - " "^pad * s -end diff --git a/base/methodshow.jl b/base/methodshow.jl index 7afa482d69f8a..8f426b08432d0 100644 --- a/base/methodshow.jl +++ b/base/methodshow.jl @@ -12,7 +12,7 @@ function argtype_decl(env, n, sig::DataType, i::Int, nargs, isva::Bool) # -> (ar end s = string(n) i = findfirst(equalto('#'), s) - if i > 0 + if i !== nothing s = s[1:i-1] end if t === Any && !isempty(s) @@ -84,7 +84,7 @@ function kwarg_decl(m::Method, kwtype::DataType) # ensure the kwarg... is always printed last. The order of the arguments are not # necessarily the same as defined in the function i = findfirst(x -> endswith(string(x), "..."), kws) - i == 0 && return kws + i === nothing && return kws push!(kws, kws[i]) return deleteat!(kws, i) end @@ -304,10 +304,12 @@ show(io::IO, mime::MIME"text/html", mt::MethodTable) = show(io, mime, MethodList # pretty-printing of AbstractVector{Method} for output of methodswith: function show(io::IO, mime::MIME"text/plain", mt::AbstractVector{Method}) resize!(LAST_SHOWN_LINE_INFOS, 0) + first = true for (i, m) in enumerate(mt) + first || println(io) + first = false print(io, "[$(i)] ") show(io, m) - println(io) push!(LAST_SHOWN_LINE_INFOS, (string(m.file), m.line)) end end diff --git a/base/missing.jl b/base/missing.jl index 3b8babdcf126c..8166ade8d2401 100644 --- a/base/missing.jl +++ b/base/missing.jl @@ -164,8 +164,8 @@ skipmissing(itr) = SkipMissing(itr) struct SkipMissing{T} x::T end -iteratorsize(::Type{<:SkipMissing}) = SizeUnknown() -iteratoreltype(::Type{SkipMissing{T}}) where {T} = iteratoreltype(T) +IteratorSize(::Type{<:SkipMissing}) = SizeUnknown() +IteratorEltype(::Type{SkipMissing{T}}) where {T} = IteratorEltype(T) eltype(itr::SkipMissing) = nonmissingtype(eltype(itr.x)) # Fallback implementation for general iterables: we cannot access a value twice, # so after finding the next non-missing element in start() or next(), we have to diff --git a/base/mpfr.jl b/base/mpfr.jl index 2338581d14902..f6f9d53368920 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -132,7 +132,7 @@ BigFloat(x::Union{Float16,Float32}) = BigFloat(Float64(x)) BigFloat(x::Rational) = BigFloat(numerator(x)) / BigFloat(denominator(x)) function tryparse(::Type{BigFloat}, s::AbstractString, base::Int=0) - !isempty(s) && Base.Unicode.isspace(s[end]) && return tryparse(BigFloat, rstrip(s), base) + !isempty(s) && isspace(s[end]) && return tryparse(BigFloat, rstrip(s), base) z = BigFloat() err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ref{BigFloat}, Cstring, Int32, Int32), z, s, base, ROUNDING_MODE[]) err == 0 ? z : nothing diff --git a/base/multidimensional.jl b/base/multidimensional.jl index aa6a3cf5bf74d..d49aa104e21a4 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -4,7 +4,7 @@ module IteratorsMD import Base: eltype, length, size, start, done, next, first, last, in, getindex, setindex!, IndexStyle, min, max, zero, one, isless, eachindex, - ndims, iteratorsize, convert, show + ndims, IteratorSize, convert, show import Base: +, -, * import Base: simd_outer_range, simd_inner_length, simd_index @@ -31,7 +31,7 @@ module IteratorsMD # Examples ```jldoctest - julia> A = reshape(collect(1:16), (2, 2, 2, 2)) + julia> A = reshape(Vector(1:16), (2, 2, 2, 2)) 2×2×2×2 Array{Int64,4}: [:, :, 1, 1] = 1 3 @@ -264,14 +264,14 @@ module IteratorsMD @inline function eachindex(::IndexCartesian, A::AbstractArray, B::AbstractArray...) axsA = axes(A) - all(x->axes(x) == axsA, B) || Base.throw_eachindex_mismatch(IndexCartesian(), A, B...) + Base._all_match_first(axes, axsA, B...) || Base.throw_eachindex_mismatch(IndexCartesian(), A, B...) CartesianIndices(axsA) end eltype(R::CartesianIndices) = eltype(typeof(R)) eltype(::Type{CartesianIndices{N}}) where {N} = CartesianIndex{N} eltype(::Type{CartesianIndices{N,TT}}) where {N,TT} = CartesianIndex{N} - iteratorsize(::Type{<:CartesianIndices}) = Base.HasShape() + IteratorSize(::Type{<:CartesianIndices}) = Base.HasShape() @inline function start(iter::CartesianIndices) iterfirst, iterlast = first(iter), last(iter) @@ -418,6 +418,7 @@ module IteratorsMD # AbstractArray implementation Base.IndexStyle(::Type{LinearIndices{N,R}}) where {N,R} = IndexCartesian() Base.axes(iter::LinearIndices{N,R}) where {N,R} = iter.indices + Base.size(iter::LinearIndices{N,R}) where {N,R} = length.(iter.indices) @inline function Base.getindex(iter::LinearIndices{N,R}, I::Vararg{Int, N}) where {N,R} dims = length.(iter.indices) #without the inbounds, this is slower than Base._sub2ind(iter.indices, I...) @@ -686,51 +687,6 @@ end ## -# small helper function since we cannot use a closure in a generated function -_countnz(x) = x != 0 - -""" - findn(A) - -Return one vector for each dimension containing indices giving the -locations of the non-zeros in `A` (determined by `A[i] != 0`). - -# Examples -```jldoctest -julia> A = [1 2 0; 0 0 3; 0 4 0] -3×3 Array{Int64,2}: - 1 2 0 - 0 0 3 - 0 4 0 - -julia> findn(A) -([1, 1, 3, 2], [1, 2, 2, 3]) - -julia> A = [0 0; 0 0] -2×2 Array{Int64,2}: - 0 0 - 0 0 - -julia> findn(A) -(Int64[], Int64[]) -``` -""" -@generated function findn(A::AbstractArray{T,N}) where {T,N} - quote - nnzA = count(_countnz, A) - @nexprs $N d->(I_d = Vector{Int}(uninitialized, nnzA)) - k = 1 - @nloops $N i A begin - @inbounds if (@nref $N A i) != 0 - @nexprs $N d->(I_d[k] = i_d) - k += 1 - end - end - @ntuple $N I - end -end - - # see discussion in #18364 ... we try not to widen type of the resulting array # from cumsum or cumprod, but in some cases (+, Bool) we may not have a choice. rcum_promote_type(op, ::Type{T}, ::Type{S}) where {T,S<:Number} = promote_op(op, T, S) @@ -780,7 +736,7 @@ end function cumsum!(out, v::AbstractVector, dim::Integer) # we dispatch on the possibility of numerical stability issues - _cumsum!(out, v, dim, TypeArithmetic(eltype(out))) + _cumsum!(out, v, dim, ArithmeticStyle(eltype(out))) end function _cumsum!(out, v, dim, ::ArithmeticRounds) @@ -789,7 +745,7 @@ end function _cumsum!(out, v, dim, ::ArithmeticUnknown) _cumsum!(out, v, dim, ArithmeticRounds()) end -function _cumsum!(out, v, dim, ::TypeArithmetic) +function _cumsum!(out, v, dim, ::ArithmeticStyle) dim == 1 ? accumulate!(+, out, v) : copyto!(out, v) end @@ -1306,7 +1262,7 @@ arrays have overlapping indices, then on the domain of the overlap # Examples ```julia-repl -julia> src = reshape(collect(1:16), (4,4)) +julia> src = reshape(Vector(1:16), (4,4)) 4×4 Array{Int64,2}: 1 5 9 13 2 6 10 14 @@ -1596,25 +1552,6 @@ end end end -## findn - -@generated function findn(B::BitArray{N}) where N - quote - nnzB = count(B) - I = ntuple(x->Vector{Int}(uninitialized, nnzB), Val($N)) - if nnzB > 0 - count = 1 - @nloops $N i B begin - if (@nref $N B i) # TODO: should avoid bounds checking - @nexprs $N d->(I[d][count] = i_d) - count += 1 - end - end - end - return I - end -end - ## isassigned @generated function isassigned(B::BitArray, I_0::Int, I::Int...) @@ -1706,7 +1643,7 @@ Return unique regions of `A` along dimension `dim`. # Examples ```jldoctest -julia> A = map(isodd, reshape(collect(1:8), (2,2,2))) +julia> A = map(isodd, reshape(Vector(1:8), (2,2,2))) 2×2×2 Array{Bool,3}: [:, :, 1] = true true @@ -1816,7 +1753,7 @@ Compute the minimum and maximum elements of an array over the given dimensions. # Examples ```jldoctest -julia> A = reshape(collect(1:2:16), (2,2,2)) +julia> A = reshape(Vector(1:2:16), (2,2,2)) 2×2×2 Array{Int64,3}: [:, :, 1] = 1 5 diff --git a/base/number.jl b/base/number.jl index 71090b80257c0..bc05e0c3619ef 100644 --- a/base/number.jl +++ b/base/number.jl @@ -53,7 +53,7 @@ ndims(x::Number) = 0 ndims(::Type{<:Number}) = 0 length(x::Number) = 1 endof(x::Number) = 1 -iteratorsize(::Type{<:Number}) = HasShape() +IteratorSize(::Type{<:Number}) = HasShape() keys(::Number) = OneTo(1) getindex(x::Number) = x @@ -69,7 +69,7 @@ function getindex(x::Number, I::Integer...) end first(x::Number) = x last(x::Number) = x -copy(x::Number) = x # some code treats numbers as collection-like +copy(x::Number) = x # some code treats numbers as collection-like """ divrem(x, y) @@ -171,6 +171,28 @@ copysign(x::Real, y::Real) = ifelse(signbit(x)!=signbit(y), -x, +x) conj(x::Real) = x transpose(x::Number) = x +""" + adjoint(A) + +Lazy adjoint (conjugate transposition) (also postfix `'`). Note that `adjoint` is applied recursively to +elements. + +This operation is intended for linear algebra usage - for general data manipulation see +[`permutedims`](@ref). + +# Examples +```jldoctest +julia> A = [3+2im 9+2im; 8+7im 4+6im] +2×2 Array{Complex{Int64},2}: + 3+2im 9+2im + 8+7im 4+6im + +julia> adjoint(A) +2×2 Adjoint{Complex{Int64},Array{Complex{Int64},2}}: + 3-2im 8-7im + 9-2im 4-6im +``` +""" adjoint(x::Number) = conj(x) angle(z::Real) = atan2(zero(z), z) diff --git a/base/operators.jl b/base/operators.jl index a54f59fc8b3cc..5786b9cd3f1d0 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -391,16 +391,6 @@ julia> minmax('c','b') """ minmax(x,y) = isless(y, x) ? (y, x) : (x, y) -scalarmax(x,y) = max(x,y) -scalarmax(x::AbstractArray, y::AbstractArray) = throw(ArgumentError("ordering is not well-defined for arrays")) -scalarmax(x , y::AbstractArray) = throw(ArgumentError("ordering is not well-defined for arrays")) -scalarmax(x::AbstractArray, y ) = throw(ArgumentError("ordering is not well-defined for arrays")) - -scalarmin(x,y) = min(x,y) -scalarmin(x::AbstractArray, y::AbstractArray) = throw(ArgumentError("ordering is not well-defined for arrays")) -scalarmin(x , y::AbstractArray) = throw(ArgumentError("ordering is not well-defined for arrays")) -scalarmin(x::AbstractArray, y ) = throw(ArgumentError("ordering is not well-defined for arrays")) - ## definitions providing basic traits of arithmetic operators ## """ @@ -475,7 +465,7 @@ julia> inv(A) * x 4.5 ``` """ -\(x,y) = adjoint(Adjoint(y)/Adjoint(x)) +\(x,y) = adjoint(adjoint(y)/adjoint(x)) # Core <<, >>, and >>> take either Int or UInt as second arg. Signed shift # counts can shift in either direction, and are translated here to unsigned @@ -714,32 +704,6 @@ fldmod1(x::T, y::T) where {T<:Real} = (fld1(x,y), mod1(x,y)) # efficient version for integers fldmod1(x::T, y::T) where {T<:Integer} = (fld1(x,y), mod1(x,y)) -# postfix apostophre -Core.postfixapostrophize(x) = Adjoint(x) - -""" - adjoint(A) - -The conjugate transposition operator (`'`). Note that `adjoint` is applied recursively to -elements. - -This operation is intended for linear algebra usage - for general data manipulation see -[`permutedims`](@ref). - -# Examples -```jldoctest -julia> A = [3+2im 9+2im; 8+7im 4+6im] -2×2 Array{Complex{Int64},2}: - 3+2im 9+2im - 8+7im 4+6im - -julia> adjoint(A) -2×2 Array{Complex{Int64},2}: - 3-2im 8-7im - 9-2im 4-6im -``` -""" -adjoint(x) = conj(transpose(x)) conj(x) = x @@ -789,8 +753,6 @@ entered in the Julia REPL (and most editors, appropriately configured) by typing # Examples ```jldoctest -julia> using Unicode - julia> map(uppercase∘hex, 250:255) 6-element Array{String,1}: "FA" diff --git a/base/parse.jl b/base/parse.jl index e0da3ea303058..58856ce0b4645 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -53,7 +53,7 @@ end function parseint_preamble(signed::Bool, base::Int, s::AbstractString, startpos::Int, endpos::Int) c, i, j = parseint_next(s, startpos, endpos) - while Unicode.isspace(c) + while isspace(c) c, i, j = parseint_next(s,i,endpos) end (j == 0) && (return 0, 0, 0) @@ -66,7 +66,7 @@ function parseint_preamble(signed::Bool, base::Int, s::AbstractString, startpos: end end - while Unicode.isspace(c) + while isspace(c) c, i, j = parseint_next(s,i,endpos) end (j == 0) && (return 0, 0, 0) @@ -124,10 +124,10 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos:: return n end c, i = next(s,i) - Unicode.isspace(c) && break + isspace(c) && break end (T <: Signed) && (n *= sgn) - while !Unicode.isspace(c) + while !isspace(c) d::T = '0' <= c <= '9' ? c-'0' : 'A' <= c <= 'Z' ? c-'A'+10 : 'a' <= c <= 'z' ? c-'a'+a : base @@ -148,7 +148,7 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos:: end while i <= endpos c, i = next(s,i) - if !Unicode.isspace(c) + if !isspace(c) raise && throw(ArgumentError("extra characters after whitespace in $(repr(SubString(s,startpos,endpos)))")) return nothing end @@ -167,10 +167,10 @@ function tryparse_internal(::Type{Bool}, sbuff::Union{String,SubString{String}}, orig_end = endpos # Ignore leading and trailing whitespace - while Unicode.isspace(sbuff[startpos]) && startpos <= endpos + while isspace(sbuff[startpos]) && startpos <= endpos startpos = nextind(sbuff, startpos) end - while Unicode.isspace(sbuff[endpos]) && endpos >= startpos + while isspace(sbuff[endpos]) && endpos >= startpos endpos = prevind(sbuff, endpos) end @@ -185,7 +185,7 @@ function tryparse_internal(::Type{Bool}, sbuff::Union{String,SubString{String}}, if raise substr = SubString(sbuff, orig_start, orig_end) # show input string in the error to avoid confusion - if all(Unicode.isspace, substr) + if all(isspace, substr) throw(ArgumentError("input string only contains whitespace")) else throw(ArgumentError("invalid Bool representation: $(repr(substr))")) @@ -272,7 +272,7 @@ tryparse_internal(::Type{Float16}, s::AbstractString, startpos::Int, endpos::Int function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String}}, i::Int, e::Int, raise::Bool) where {T<:Real} # skip initial whitespace - while i ≤ e && Unicode.isspace(s[i]) + while i ≤ e && isspace(s[i]) i = nextind(s, i) end if i > e @@ -281,16 +281,16 @@ function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String} end # find index of ± separating real/imaginary parts (if any) - i₊ = findnext(occursin(('+','-')), s, i) + i₊ = coalesce(findnext(occursin(('+','-')), s, i), 0) if i₊ == i # leading ± sign - i₊ = findnext(occursin(('+','-')), s, i₊+1) + i₊ = coalesce(findnext(occursin(('+','-')), s, i₊+1), 0) end if i₊ != 0 && s[i₊-1] in ('e','E') # exponent sign - i₊ = findnext(occursin(('+','-')), s, i₊+1) + i₊ = coalesce(findnext(occursin(('+','-')), s, i₊+1), 0) end # find trailing im/i/j - iᵢ = findprev(occursin(('m','i','j')), s, e) + iᵢ = coalesce(findprev(occursin(('m','i','j')), s, e), 0) if iᵢ > 0 && s[iᵢ] == 'm' # im iᵢ -= 1 if s[iᵢ] != 'i' diff --git a/base/path.jl b/base/path.jl index c602e409d7009..d2448a083a315 100644 --- a/base/path.jl +++ b/base/path.jl @@ -380,8 +380,8 @@ function relpath(path::String, startpath::String = ".") break end end - pathpart = join(path_arr[i+1:findlast(x -> !isempty(x), path_arr)], path_separator) - prefix_num = findlast(x -> !isempty(x), start_arr) - i - 1 + pathpart = join(path_arr[i+1:coalesce(findlast(x -> !isempty(x), path_arr), 0)], path_separator) + prefix_num = coalesce(findlast(x -> !isempty(x), start_arr), 0) - i - 1 if prefix_num >= 0 prefix = pardir * path_separator relpath_ = isempty(pathpart) ? diff --git a/base/permuteddimsarray.jl b/base/permuteddimsarray.jl index bf7c73f25071d..3c06450edbcc5 100644 --- a/base/permuteddimsarray.jl +++ b/base/permuteddimsarray.jl @@ -87,7 +87,7 @@ See also: [`PermutedDimsArray`](@ref). # Examples ```jldoctest -julia> A = reshape(collect(1:8), (2,2,2)) +julia> A = reshape(Vector(1:8), (2,2,2)) 2×2×2 Array{Int64,3}: [:, :, 1] = 1 3 @@ -214,7 +214,7 @@ function _copy!(P::PermutedDimsArray{T,N,perm}, src) where {T,N,perm} copyto!(parent(P), src) # it's not permuted else R1 = CartesianIndices(axes(src)[1:d]) - d1 = findfirst(equalto(d+1), perm) # first permuted dim of dest + d1 = findfirst(equalto(d+1), perm)::Int # first permuted dim of dest R2 = CartesianIndices(axes(src)[d+2:d1-1]) R3 = CartesianIndices(axes(src)[d1+1:end]) _permutedims!(P, src, R1, R2, R3, d+1, d1) diff --git a/base/pkg/entry.jl b/base/pkg/entry.jl index fb6c808eb161c..f52f7674f4851 100644 --- a/base/pkg/entry.jl +++ b/base/pkg/entry.jl @@ -92,7 +92,7 @@ function available() for (pkg, vers) in all_avail any(x->Types.satisfies("julia", VERSION, x[2].requires), vers) && push!(avail, pkg) end - sort!(avail, by=Base.Unicode.lowercase) + sort!(avail, by=lowercase) end function available(pkg::AbstractString) @@ -633,19 +633,13 @@ function build!(pkgs::Vector, seen::Set, errfile::AbstractString) end function build!(pkgs::Vector, errs::Dict, seen::Set=Set()) - errfile = tempname() - touch(errfile) # create empty file - try + mktemp() do errfile, f build!(pkgs, seen, errfile) - open(errfile, "r") do f - while !eof(f) - pkg = deserialize(f) - err = deserialize(f) - errs[pkg] = err - end + while !eof(f) + pkg = deserialize(f) + err = deserialize(f) + errs[pkg] = err end - finally - isfile(errfile) && Base.rm(errfile) end end diff --git a/base/pkg/query.jl b/base/pkg/query.jl index a4ca902dd7ea4..bf51e3e8b0726 100644 --- a/base/pkg/query.jl +++ b/base/pkg/query.jl @@ -406,7 +406,7 @@ function prune_versions(reqs::Requires, deps::Dict{String,Dict{VersionNumber,Ava end for (vn,a) in fdepsp vmind = findfirst(equalto(a.requires), uniqdepssets) - @assert vmind > 0 + @assert vmind !== nothing vm = vmaskp[vn] vm[vmind] = true end @@ -435,7 +435,7 @@ function prune_versions(reqs::Requires, deps::Dict{String,Dict{VersionNumber,Ava nc = length(vmask0_uniq) classes = [VersionNumber[] for c0 = 1:nc] for (vn,vm) in vmaskp - c0 = findfirst(equalto(vm), vmask0_uniq) + c0 = findfirst(equalto(vm), vmask0_uniq)::Int push!(classes[c0], vn) end map(sort!, classes) diff --git a/base/pkg/reqs.jl b/base/pkg/reqs.jl index 7bc9db969bbef..3c15fd918e80b 100644 --- a/base/pkg/reqs.jl +++ b/base/pkg/reqs.jl @@ -78,7 +78,7 @@ function write(io::IO, lines::Vector{Line}) end end function write(io::IO, reqs::Requires) - for pkg in sort!(collect(keys(reqs)), by=Unicode.lowercase) + for pkg in sort!(collect(keys(reqs)), by=lowercase) println(io, Requirement(pkg, reqs[pkg]).content) end end diff --git a/base/pkg/resolve/maxsum.jl b/base/pkg/resolve/maxsum.jl index cc22a8abe3555..c35bdc5aa9b58 100644 --- a/base/pkg/resolve/maxsum.jl +++ b/base/pkg/resolve/maxsum.jl @@ -122,7 +122,7 @@ mutable struct Graph adjdict[p0][p1] = j1 bm = trues(spp[p1], spp[p0]) - bmt = adjoint(bm) + bmt = trues(spp[p0], spp[p1]) push!(gmsk[p0], bm) push!(gmsk[p1], bmt) diff --git a/base/pkg/types.jl b/base/pkg/types.jl index 0e5df375892d3..9918a1aa8f153 100644 --- a/base/pkg/types.jl +++ b/base/pkg/types.jl @@ -102,7 +102,7 @@ function union!(A::VersionSet, B::VersionSet) for intB in B.intervals lB, uB = intB.lower, intB.upper k0 = findfirst(i->(i.upper > lB), ivals) - if k0 == 0 + if k0 === nothing push!(ivals, intB) continue end diff --git a/base/pointer.jl b/base/pointer.jl index ffbe54f83214a..63ffd8b4be3d8 100644 --- a/base/pointer.jl +++ b/base/pointer.jl @@ -76,7 +76,7 @@ element type. `dims` is either an integer (for a 1d array) or a tuple of the arr `own` optionally specifies whether Julia should take ownership of the memory, calling `free` on the pointer when the array is no longer referenced. -This function is labelled "unsafe" because it will crash if `pointer` is not +This function is labeled "unsafe" because it will crash if `pointer` is not a valid memory address to data of the requested length. """ function unsafe_wrap(::Union{Type{Array},Type{Array{T}},Type{Array{T,N}}}, diff --git a/base/precompile.jl b/base/precompile.jl index 51acceafbed74..8f38d86a315a4 100644 --- a/base/precompile.jl +++ b/base/precompile.jl @@ -60,14 +60,10 @@ precompile(Tuple{typeof(Base.lstrip), Base.SubString{String}, Array{Char, 1}}) precompile(Tuple{getfield(Base, Symbol("#kw##split")), Array{Any, 1}, typeof(Base.split), String, Char}) precompile(Tuple{getfield(Base, Symbol("#kw##split")), Array{Any, 1}, typeof(Base.split), Base.SubString{String}, Char}) precompile(Tuple{typeof(Base.map!), typeof(Base.strip), Array{Base.SubString{String}, 1}, Array{Base.SubString{String}, 1}}) -precompile(Tuple{typeof(Base.Unicode.isnumeric), Base.SubString{String}}) precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{Core.Inference.Const}, Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}) precompile(Tuple{Type{Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{Core.Inference.Const}}}, Type{Core.Inference.Const}, Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}) precompile(Tuple{typeof(Core.Inference.convert), Type{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}, Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}) precompile(Tuple{typeof(Core.Inference.collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{Core.Inference.Const}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}) @@ -86,7 +82,6 @@ precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Base.DevNullStream, Base.D precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}) precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{QuoteNode}, Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}) precompile(Tuple{Type{Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{QuoteNode}}}, Type{QuoteNode}, Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{QuoteNode}}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{QuoteNode}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{QuoteNode}}}) precompile(Tuple{typeof(Core.Inference.copyto!), Array{Any, 1}, Core.Inference.Generator{Tuple{Tuple{Base.DevNullStream, Base.DevNullStream, Base.DevNullStream}}, Type{QuoteNode}}}) @@ -109,9 +104,6 @@ precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{Core precompile(Tuple{Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{Core.Inference.Const}}}, Type{Core.Inference.Const}, Tuple{Tuple{}, Tuple{}, Int64}}) precompile(Tuple{typeof(Core.Inference.convert), Type{Tuple{Tuple{}, Tuple{}, Int64}}, Tuple{Tuple{}, Tuple{}, Int64}}) precompile(Tuple{typeof(Core.Inference.collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{Tuple{}, Tuple{}, Int64}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{Core.Inference.Const}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{Tuple{}, Tuple{}, Int64}}) @@ -126,7 +118,6 @@ precompile(Tuple{typeof(Core.Inference.getindex), Tuple{Tuple{}, Tuple{}, Int64} precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Tuple{}, Tuple{}, Int64}}) precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{QuoteNode}, Tuple{Tuple{}, Tuple{}, Int64}}) precompile(Tuple{Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{QuoteNode}}}, Type{QuoteNode}, Tuple{Tuple{}, Tuple{}, Int64}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{QuoteNode}}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{QuoteNode}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{QuoteNode}}}) precompile(Tuple{typeof(Core.Inference.copyto!), Array{Any, 1}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}, Int64}, Type{QuoteNode}}}) @@ -137,9 +128,6 @@ precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{Core precompile(Tuple{Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{Core.Inference.Const}}}, Type{Core.Inference.Const}, Tuple{Tuple{}, Tuple{}}}) precompile(Tuple{typeof(Core.Inference.convert), Type{Tuple{Tuple{}, Tuple{}}}, Tuple{Tuple{}, Tuple{}}}) precompile(Tuple{typeof(Core.Inference.collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{Tuple{}, Tuple{}}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{Core.Inference.Const}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{Tuple{}, Tuple{}}}) @@ -153,7 +141,6 @@ precompile(Tuple{typeof(Core.Inference.next), Tuple{Tuple{}, Tuple{}}, Int64}) precompile(Tuple{typeof(Core.Inference.getindex), Tuple{Tuple{}, Tuple{}}, Int64}) precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{QuoteNode}, Tuple{Tuple{}, Tuple{}}}) precompile(Tuple{Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{QuoteNode}}}, Type{QuoteNode}, Tuple{Tuple{}, Tuple{}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{QuoteNode}}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{QuoteNode}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{QuoteNode}}}) precompile(Tuple{typeof(Core.Inference.copyto!), Array{Any, 1}, Core.Inference.Generator{Tuple{Tuple{}, Tuple{}}, Type{QuoteNode}}}) @@ -203,9 +190,6 @@ precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{Core precompile(Tuple{Type{Core.Inference.Generator{Tuple{Nothing}, Type{Core.Inference.Const}}}, Type{Core.Inference.Const}, Tuple{Nothing}}) precompile(Tuple{typeof(Core.Inference.convert), Type{Tuple{Nothing}}, Tuple{Nothing}}) precompile(Tuple{typeof(Core.Inference.collect), Type{Any}, Core.Inference.Generator{Tuple{Nothing}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{Nothing}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Nothing}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{Nothing}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Nothing}, Type{Core.Inference.Const}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Nothing}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{Nothing}}) @@ -222,9 +206,6 @@ precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{Core precompile(Tuple{Type{Core.Inference.Generator{Tuple{String, typeof(Base.info)}, Type{Core.Inference.Const}}}, Type{Core.Inference.Const}, Tuple{String, typeof(Base.info)}}) precompile(Tuple{typeof(Core.Inference.convert), Type{Tuple{String, typeof(Base.info)}}, Tuple{String, typeof(Base.info)}}) precompile(Tuple{typeof(Core.Inference.collect), Type{Any}, Core.Inference.Generator{Tuple{String, typeof(Base.info)}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{String, typeof(Base.info)}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{String, typeof(Base.info)}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{String, typeof(Base.info)}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{String, typeof(Base.info)}, Type{Core.Inference.Const}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{String, typeof(Base.info)}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{String, typeof(Base.info)}}) @@ -635,8 +616,6 @@ precompile(Tuple{typeof(Base.LineEdit.common_prefix), Array{String, 1}}) precompile(Tuple{typeof(Base.LineEdit.show_completions), Base.LineEdit.PromptState, Array{String, 1}}) precompile(Tuple{typeof(Base.collect_to!), Array{Int64, 1}, Base.Generator{Array{String, 1}, typeof(Base.length)}, Int64, Int64}) precompile(Tuple{typeof(Base._collect), Array{String, 1}, Base.Generator{Array{String, 1}, typeof(Base.length)}, Base.EltypeUnknown, Base.HasShape}) -precompile(Tuple{typeof(Base.mapreduce_impl), typeof(Base.identity), typeof(Base.scalarmax), Array{Int64, 1}, Int64, Int64}) -precompile(Tuple{typeof(Base._mapreduce), typeof(Base.identity), typeof(Base.scalarmax), Base.IndexLinear, Array{Int64, 1}}) precompile(Tuple{typeof(Base.Terminals.cmove_down), Base.Terminals.TTYTerminal, Int64}) precompile(Tuple{typeof(Base.Terminals.cmove_col), Base.Terminals.TTYTerminal, Int64}) precompile(Tuple{typeof(Base.Terminals.cmove_right), Base.Terminals.TTYTerminal, Int64}) @@ -729,8 +708,6 @@ precompile(Tuple{typeof(Base.Docs.avgdistance), Array{Int64, 1}}) precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Array{String, 1}}}) precompile(Tuple{typeof(Base.Docs.accessible), Module}) precompile(Tuple{Type{Base.Generator{I, F} where F where I}, typeof(Base.names), Array{Any, 1}}) -precompile(Tuple{typeof(Base.iteratoreltype), Type{Base.Generator{Array{Any, 1}, typeof(Base.names)}}}) -precompile(Tuple{typeof(Base.iteratorsize), Type{Base.Generator{Array{Any, 1}, typeof(Base.names)}}}) precompile(Tuple{typeof(Base._collect), Array{Any, 1}, Base.Generator{Array{Any, 1}, typeof(Base.names)}, Base.EltypeUnknown, Base.HasShape}) precompile(Tuple{typeof(Base.collect_to!), Array{Array{Symbol, 1}, 1}, Base.Generator{Array{Any, 1}, typeof(Base.names)}, Int64, Int64}) precompile(Tuple{typeof(Base.names), Module}) @@ -764,12 +741,9 @@ precompile(Tuple{typeof(Base.copyto!), Base.IndexLinear, Array{Any, 1}, Base.Ind precompile(Tuple{typeof(Base.:(==)), String, Symbol}) precompile(Tuple{typeof(Base.unique_from), Array{Any, 1}, Array{Any, 1}, Base.Set{Any}, Int64}) precompile(Tuple{Type{Base.Generator{I, F} where F where I}, typeof(Base.string), Array{Any, 1}}) -precompile(Tuple{typeof(Base.iteratoreltype), Type{Base.Generator{Array{Any, 1}, typeof(Base.string)}}}) -precompile(Tuple{typeof(Base.iteratorsize), Type{Base.Generator{Array{Any, 1}, typeof(Base.string)}}}) precompile(Tuple{typeof(Base._collect), Array{Any, 1}, Base.Generator{Array{Any, 1}, typeof(Base.string)}, Base.EltypeUnknown, Base.HasShape}) precompile(Tuple{typeof(Base.similar), Array{Any, 1}, Type{String}, Tuple{Base.OneTo{Int64}}}) precompile(Tuple{typeof(Base.collect_to!), Array{String, 1}, Base.Generator{Array{Any, 1}, typeof(Base.string)}, Int64, Int64}) -precompile(Tuple{typeof(Base.Unicode.isalpha), Char}) precompile(Tuple{getfield(Base.Docs, Symbol("#kw##matchinds")), Array{Any, 1}, typeof(Base.Docs.matchinds), String, String}) precompile(Tuple{typeof(Base.Docs.bestmatch), String, String}) precompile(Tuple{typeof(Base.length), Tuple{DataType, DataType}}) @@ -932,7 +906,6 @@ precompile(Tuple{typeof(Base.lstrip), String, Char}) precompile(Tuple{typeof(Base.Markdown.blockquote), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.Markdown.MD}) precompile(Tuple{getfield(Base.Markdown, Symbol("#kw##parse")), Array{Any, 1}, typeof(Base.Markdown.parse), String}) precompile(Tuple{typeof(Base.Markdown.admonition), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.Markdown.MD}) -precompile(Tuple{typeof(Base.Unicode.isupper), Char}) precompile(Tuple{getfield(Base.Markdown, Symbol("#kw##linecontains")), Array{Any, 1}, typeof(Base.Markdown.linecontains), Base.GenericIOBuffer{Array{UInt8, 1}}, String}) precompile(Tuple{typeof(Base.ucfirst), Base.SubString{String}}) precompile(Tuple{typeof(Base.Markdown.blocktex), Base.GenericIOBuffer{Array{UInt8, 1}}, Base.Markdown.MD}) @@ -1556,9 +1529,6 @@ precompile(Tuple{typeof(Core.Inference.done), Core.Inference.Generator{Tuple{Sym precompile(Tuple{typeof(Core.Inference.done), Tuple{Symbol, Expr}, Int64}) precompile(Tuple{typeof(Core.Inference.getindex), Tuple{Symbol, Expr}, Int64}) precompile(Tuple{typeof(Core.Inference.isbits), Array{Module, 1}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{Symbol, Expr}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Symbol, Expr}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{Symbol, Expr}}}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Symbol, Expr}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{Symbol, Expr}}) precompile(Tuple{typeof(Core.Inference.next), Core.Inference.Generator{Tuple{Symbol, Expr}, Type{Core.Inference.Const}}, Int64}) diff --git a/base/printf.jl b/base/printf.jl index a1373592f4fc7..d2f1f00ecc025 100644 --- a/base/printf.jl +++ b/base/printf.jl @@ -3,7 +3,6 @@ module Printf using Base.Grisu using Base.GMP -using Base.Unicode: lowercase, textwidth, isupper ### printf formatter generation ### const SmallFloatingPoint = Union{Float64,Float32,Float16} @@ -641,6 +640,7 @@ function gen_s(flags::String, width::Int, precision::Int, c::Char) # # flags: # (-): left justify + # (#): use `show`/`repr` instead of `print`/`string` # @gensym x blk = Expr(:block) @@ -684,6 +684,9 @@ function gen_p(flags::String, width::Int, precision::Int, c::Char) # print pointer: # [p]: the only option # + # flags: + # (-): left justify + # @gensym x blk = Expr(:block) ptrwidth = Sys.WORD_SIZE>>2 @@ -860,7 +863,7 @@ function decode_dec(d::Integer) return Int32(pt), Int32(pt), neg end -function decode_hex(d::Integer, symbols::Array{UInt8,1}) +function decode_hex(d::Integer, symbols::AbstractArray{UInt8,1}) neg, x = handlenegative(d) @handle_zero x pt = i = (sizeof(x)<<1)-(leading_zeros(x)>>2) @@ -1034,10 +1037,10 @@ ini_HEX(x::Real, n::Int) = ini_hex(x,n,HEX_symbols) ini_hex(x::Real) = ini_hex(x,hex_symbols) ini_HEX(x::Real) = ini_hex(x,HEX_symbols) -ini_hex(x::Real, n::Int, symbols::Array{UInt8,1}) = ini_hex(float(x), n, symbols) -ini_hex(x::Real, symbols::Array{UInt8,1}) = ini_hex(float(x), symbols) +ini_hex(x::Real, n::Int, symbols::AbstractArray{UInt8,1}) = ini_hex(float(x), n, symbols) +ini_hex(x::Real, symbols::AbstractArray{UInt8,1}) = ini_hex(float(x), symbols) -function ini_hex(x::SmallFloatingPoint, n::Int, symbols::Array{UInt8,1}) +function ini_hex(x::SmallFloatingPoint, n::Int, symbols::AbstractArray{UInt8,1}) x = Float64(x) if x == 0.0 ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), DIGITS, '0', n) @@ -1062,7 +1065,7 @@ function ini_hex(x::SmallFloatingPoint, n::Int, symbols::Array{UInt8,1}) end end -function ini_hex(x::SmallFloatingPoint, symbols::Array{UInt8,1}) +function ini_hex(x::SmallFloatingPoint, symbols::AbstractArray{UInt8,1}) x = Float64(x) if x == 0.0 ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), DIGITS, '0', 1) @@ -1183,7 +1186,7 @@ function _printf(macroname, io, fmt, args) quote G = $(esc(x)) if length(G) != $(length(sym_args)) - throw(ArgumentError($macroname,": wrong number of arguments (",length(G),") should be (",$(length(sym_args)),")")) + throw(ArgumentError(string($macroname,": wrong number of arguments (",length(G),") should be (",$(length(sym_args)),")"))) end end ) diff --git a/base/process.jl b/base/process.jl index aec5045839af4..ca2ebb9ca5c3d 100644 --- a/base/process.jl +++ b/base/process.jl @@ -138,7 +138,7 @@ struct FileRedirect filename::AbstractString append::Bool function FileRedirect(filename, append) - if Unicode.lowercase(filename) == (@static Sys.iswindows() ? "nul" : "/dev/null") + if lowercase(filename) == (@static Sys.iswindows() ? "nul" : "/dev/null") @warn "For portability use DevNull instead of a file redirect" maxlog=1 end new(filename, append) diff --git a/base/range.jl b/base/range.jl index 2219e56033853..bea793d5761b9 100644 --- a/base/range.jl +++ b/base/range.jl @@ -26,12 +26,12 @@ julia> colon(1, 2, 5) ``` """ colon(start::T, step::T, stop::T) where {T<:AbstractFloat} = - _colon(TypeOrder(T), TypeArithmetic(T), start, step, stop) + _colon(OrderStyle(T), ArithmeticStyle(T), start, step, stop) colon(start::T, step::T, stop::T) where {T<:Real} = - _colon(TypeOrder(T), TypeArithmetic(T), start, step, stop) -_colon(::HasOrder, ::Any, start::T, step, stop::T) where {T} = StepRange(start, step, stop) + _colon(OrderStyle(T), ArithmeticStyle(T), start, step, stop) +_colon(::Ordered, ::Any, start::T, step, stop::T) where {T} = StepRange(start, step, stop) # for T<:Union{Float16,Float32,Float64} see twiceprecision.jl -_colon(::HasOrder, ::ArithmeticRounds, start::T, step, stop::T) where {T} = +_colon(::Ordered, ::ArithmeticRounds, start::T, step, stop::T) where {T} = StepRangeLen(start, step, floor(Int, (stop-start)/step)+1) _colon(::Any, ::Any, start::T, step, stop::T) where {T} = StepRangeLen(start, step, floor(Int, (stop-start)/step)+1) @@ -57,8 +57,8 @@ end Construct a range by length, given a starting value and optional step (defaults to 1). """ -range(a::T, step, len::Integer) where {T} = _range(TypeOrder(T), TypeArithmetic(T), a, step, len) -_range(::HasOrder, ::ArithmeticOverflows, a::T, step::S, len::Integer) where {T,S} = +range(a::T, step, len::Integer) where {T} = _range(OrderStyle(T), ArithmeticStyle(T), a, step, len) +_range(::Ordered, ::ArithmeticWraps, a::T, step::S, len::Integer) where {T,S} = StepRange{T,S}(a, step, convert(T, a+step*(len-1))) _range(::Any, ::Any, a::T, step::S, len::Integer) where {T,S} = StepRangeLen{typeof(a+0*step),T,S}(a, step, len) @@ -79,8 +79,8 @@ range(a::AbstractFloat, st::Real, len::Integer) = range(a, float(st), len) abstract type AbstractRange{T} <: AbstractArray{T,1} end -TypeRangeStep(::Type{<:AbstractRange}) = RangeStepIrregular() -TypeRangeStep(::Type{<:AbstractRange{<:Integer}}) = RangeStepRegular() +RangeStepStyle(::Type{<:AbstractRange}) = RangeStepIrregular() +RangeStepStyle(::Type{<:AbstractRange{<:Integer}}) = RangeStepRegular() ## ordinal ranges diff --git a/base/reduce.jl b/base/reduce.jl index 3cacc9e837de0..811798e6651e6 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -69,7 +69,7 @@ In general, this cannot be used with empty collections (see [`reduce(op, itr)`]( function mapfoldl(f, op, itr) i = start(itr) if done(itr, i) - return Base.mapreduce_empty_iter(f, op, itr, iteratoreltype(itr)) + return Base.mapreduce_empty_iter(f, op, itr, IteratorEltype(itr)) end (x, i) = next(itr, i) v0 = mapreduce_first(f, op, x) @@ -139,7 +139,7 @@ In general, this cannot be used with empty collections (see [`reduce(op, itr)`]( function mapfoldr(f, op, itr) i = endof(itr) if isempty(itr) - return Base.mapreduce_empty_iter(f, op, itr, iteratoreltype(itr)) + return Base.mapreduce_empty_iter(f, op, itr, IteratorEltype(itr)) end return mapfoldr_impl(f, op, mapreduce_first(f, op, itr[i]), itr, i-1) end @@ -284,8 +284,8 @@ mapreduce_empty(::typeof(identity), op, T) = reduce_empty(op, T) mapreduce_empty(::typeof(abs), op, T) = abs(reduce_empty(op, T)) mapreduce_empty(::typeof(abs2), op, T) = abs2(reduce_empty(op, T)) -mapreduce_empty(f::typeof(abs), ::Union{typeof(scalarmax), typeof(max)}, T) = abs(zero(T)) -mapreduce_empty(f::typeof(abs2), ::Union{typeof(scalarmax), typeof(max)}, T) = abs2(zero(T)) +mapreduce_empty(f::typeof(abs), ::typeof(max), T) = abs(zero(T)) +mapreduce_empty(f::typeof(abs2), ::typeof(max), T) = abs2(zero(T)) mapreduce_empty_iter(f, op, itr, ::HasEltype) = mapreduce_empty(f, op, eltype(itr)) mapreduce_empty_iter(f, op::typeof(&), itr, ::EltypeUnknown) = true @@ -488,10 +488,7 @@ prod(a) = mapreduce(identity, mul_prod, a) ## maximum & minimum -function mapreduce_impl(f, op::Union{typeof(scalarmax), - typeof(scalarmin), - typeof(max), - typeof(min)}, +function mapreduce_impl(f, op::Union{typeof(max), typeof(min)}, A::AbstractArray, first::Int, last::Int) # locate the first non NaN number @inbounds a1 = A[first] @@ -505,8 +502,8 @@ function mapreduce_impl(f, op::Union{typeof(scalarmax), v end -maximum(f::Callable, a) = mapreduce(f, scalarmax, a) -minimum(f::Callable, a) = mapreduce(f, scalarmin, a) +maximum(f::Callable, a) = mapreduce(f, max, a) +minimum(f::Callable, a) = mapreduce(f, min, a) """ maximum(itr) @@ -521,7 +518,7 @@ julia> maximum([1,2,3]) 3 ``` """ -maximum(a) = mapreduce(identity, scalarmax, a) +maximum(a) = mapreduce(identity, max, a) """ minimum(itr) @@ -536,7 +533,7 @@ julia> minimum([1,2,3]) 1 ``` """ -minimum(a) = mapreduce(identity, scalarmin, a) +minimum(a) = mapreduce(identity, min, a) ## extrema diff --git a/base/reducedim.jl b/base/reducedim.jl index 27ff8ecbe0ee5..1ca8ff3d1168b 100644 --- a/base/reducedim.jl +++ b/base/reducedim.jl @@ -67,7 +67,7 @@ for (Op, initfun) in ((:(typeof(add_sum)), :zero), (:(typeof(mul_prod)), :one)) @eval initarray!(a::AbstractArray{T}, ::$(Op), init::Bool, src::AbstractArray) where {T} = (init && fill!(a, $(initfun)(T)); a) end -for Op in (:(typeof(scalarmax)), :(typeof(scalarmin)), :(typeof(max)), :(typeof(min))) +for Op in (:(typeof(max)), :(typeof(min))) @eval initarray!(a::AbstractArray{T}, ::$(Op), init::Bool, src::AbstractArray) where {T} = (init && copyfirst!(a, src); a) end @@ -124,13 +124,9 @@ function _reducedim_init(f, op, fv, fop, A, region) return reducedim_initarray(A, region, z, Tr) end -reducedim_init(f, op::typeof(max), A::AbstractArray, region) = reducedim_init(f, scalarmax, A, region) -reducedim_init(f, op::typeof(min), A::AbstractArray, region) = reducedim_init(f, scalarmin, A, region) -reducedim_init(f::Union{typeof(abs),typeof(abs2)}, op::typeof(max), A::AbstractArray, region) = reducedim_init(f, scalarmax, A, region) - -reducedim_init(f, op::typeof(scalarmax), A::AbstractArray{T}, region) where {T} = reducedim_initarray0(A, region, f, maximum) -reducedim_init(f, op::typeof(scalarmin), A::AbstractArray{T}, region) where {T} = reducedim_initarray0(A, region, f, minimum) -reducedim_init(f::Union{typeof(abs),typeof(abs2)}, op::typeof(scalarmax), A::AbstractArray{T}, region) where {T} = +reducedim_init(f, op::typeof(max), A::AbstractArray{T}, region) where {T} = reducedim_initarray0(A, region, f, maximum) +reducedim_init(f, op::typeof(min), A::AbstractArray{T}, region) where {T} = reducedim_initarray0(A, region, f, minimum) +reducedim_init(f::Union{typeof(abs),typeof(abs2)}, op::typeof(max), A::AbstractArray{T}, region) where {T} = reducedim_initarray(A, region, zero(f(zero(T)))) reducedim_init(f, op::typeof(&), A::AbstractArray, region) = reducedim_initarray(A, region, true) @@ -255,7 +251,7 @@ faster because the intermediate array is avoided. # Examples ```jldoctest -julia> a = reshape(collect(1:16), (4,4)) +julia> a = reshape(Vector(1:16), (4,4)) 4×4 Array{Int64,2}: 1 5 9 13 2 6 10 14 @@ -289,7 +285,7 @@ associativity, e.g. left-to-right, you should write your own loop. See documenta # Examples ```jldoctest -julia> a = reshape(collect(1:16), (4,4)) +julia> a = reshape(Vector(1:16), (4,4)) 4×4 Array{Int64,2}: 1 5 9 13 2 6 10 14 @@ -605,7 +601,7 @@ julia> any!([1 1], A) any!(r, A) for (fname, op) in [(:sum, :add_sum), (:prod, :mul_prod), - (:maximum, :scalarmax), (:minimum, :scalarmin), + (:maximum, :max), (:minimum, :min), (:all, :&), (:any, :|)] fname! = Symbol(fname, '!') @eval begin diff --git a/base/reflection.jl b/base/reflection.jl index 25494cb2bf3e2..b9d18ac1fb2fd 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -62,23 +62,9 @@ function fullname(m::Module) end mp = module_parent(m) if mp === m - if mn !== :Main - return (mn,) - end - # top-level module, not Main, called :Main => prior Main module - n = (:Main,) - this = Main - while this !== m - if isdefined(this, :LastMain) - n = tuple(n..., :LastMain) - this = this.LastMain - else - error("no reference to module ", mn) - end - end - return n + return (mn,) end - return tuple(fullname(mp)..., mn) + return (fullname(mp)..., mn) end """ diff --git a/base/regex.jl b/base/regex.jl index 565e93844c999..716f5a379001e 100644 --- a/base/regex.jl +++ b/base/regex.jl @@ -323,11 +323,11 @@ function _replace(io, repl_s::SubstitutionString, str, r, re) if repl[next_i] == SUB_CHAR write(io, SUB_CHAR) i = nextind(repl, next_i) - elseif Unicode.isdigit(repl[next_i]) + elseif isdigit(repl[next_i]) group = parse(Int, repl[next_i]) i = nextind(repl, next_i) while i <= e - if Unicode.isdigit(repl[i]) + if isdigit(repl[i]) group = 10group + parse(Int, repl[i]) i = nextind(repl, i) else @@ -349,7 +349,7 @@ function _replace(io, repl_s::SubstitutionString, str, r, re) end # TODO: avoid this allocation groupname = SubString(repl, groupstart, prevind(repl, i)) - if all(Unicode.isdigit, groupname) + if all(isdigit, groupname) _write_capture(io, re, parse(Int, groupname)) else group = PCRE.substring_number_from_name(re.regex, groupname) @@ -380,7 +380,7 @@ compile(itr::RegexMatchIterator) = (compile(itr.regex); itr) eltype(::Type{RegexMatchIterator}) = RegexMatch start(itr::RegexMatchIterator) = match(itr.regex, itr.string, 1, UInt32(0)) done(itr::RegexMatchIterator, prev_match) = (prev_match === nothing) -iteratorsize(::Type{RegexMatchIterator}) = SizeUnknown() +IteratorSize(::Type{RegexMatchIterator}) = SizeUnknown() # Assumes prev_match is not nothing function next(itr::RegexMatchIterator, prev_match) diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl index 7f92d6d047b4d..b747b0800dbfe 100644 --- a/base/repl/LineEdit.jl +++ b/base/repl/LineEdit.jl @@ -8,8 +8,7 @@ import ..Terminals: raw!, width, height, cmove, getX, getY, clear_line, beep import Base: ensureroom, peek, show, AnyDict, position - -using Base.Unicode: lowercase, uppercase, ucfirst, textwidth, isspace +using Base: coalesce abstract type TextInterface end abstract type ModeState end @@ -581,10 +580,10 @@ end function edit_move_up(buf::IOBuffer) npos = findprev(equalto(UInt8('\n')), buf.data, position(buf)) - npos == 0 && return false # we're in the first line + npos === nothing && return false # we're in the first line # We're interested in character count, not byte count offset = length(content(buf, npos => position(buf))) - npos2 = findprev(equalto(UInt8('\n')), buf.data, npos-1) + npos2 = coalesce(findprev(equalto(UInt8('\n')), buf.data, npos-1), 0) seek(buf, npos2) for _ = 1:offset pos = position(buf) @@ -603,11 +602,11 @@ function edit_move_up(s) end function edit_move_down(buf::IOBuffer) - npos = findprev(equalto(UInt8('\n')), buf.data[1:buf.size], position(buf)) + npos = coalesce(findprev(equalto(UInt8('\n')), buf.data[1:buf.size], position(buf)), 0) # We're interested in character count, not byte count offset = length(String(buf.data[(npos+1):(position(buf))])) npos2 = findnext(equalto(UInt8('\n')), buf.data[1:buf.size], position(buf)+1) - if npos2 == 0 #we're in the last line + if npos2 === nothing #we're in the last line return false end seek(buf, npos2) @@ -700,7 +699,7 @@ function edit_insert_newline(s::PromptState, align=-1) buf = buffer(s) if align < 0 beg = beginofline(buf) - align = min(findnext(_notspace, buf.data[beg+1:buf.size], 1) - 1, + align = min(coalesce(findnext(_notspace, buf.data[beg+1:buf.size], 1), 0) - 1, position(buf) - beg) # indentation must not increase align < 0 && (align = buf.size-beg) end @@ -727,11 +726,11 @@ const _space = UInt8(' ') _notspace(c) = c != _space -beginofline(buf, pos=position(buf)) = findprev(equalto(_newline), buf.data, pos) +beginofline(buf, pos=position(buf)) = coalesce(findprev(equalto(_newline), buf.data, pos), 0) function endofline(buf, pos=position(buf)) eol = findnext(equalto(_newline), buf.data[pos+1:buf.size], 1) - eol == 0 ? buf.size : pos + eol - 1 + eol === nothing ? buf.size : pos + eol - 1 end function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=false) @@ -745,12 +744,12 @@ function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=false) if align && c == ' ' # maybe delete multiple spaces beg = beginofline(buf, newpos) align = textwidth(String(buf.data[1+beg:newpos])) % 4 - nonspace = findprev(_notspace, buf.data, newpos) + nonspace = coalesce(findprev(_notspace, buf.data, newpos), 0) if newpos - align >= nonspace newpos -= align seek(buf, newpos) if adjust - spaces = findnext(_notspace, buf.data[newpos+2:buf.size], 1) + spaces = coalesce(findnext(_notspace, buf.data[newpos+2:buf.size], 1), 0) oldpos = spaces == 0 ? buf.size : buf.data[newpos+1+spaces] == _newline ? newpos+spaces : newpos + min(spaces, 4) @@ -1107,7 +1106,7 @@ end # compute the number of spaces from b till the next non-space on the right # (which can also be "end of line" or "end of buffer") function leadingspaces(buf::IOBuffer, b::Int)::Int - ls = findnext(_notspace, buf.data, b+1)-1 + ls = coalesce(findnext(_notspace, buf.data, b+1), 0)-1 ls == -1 && (ls = buf.size) ls -= b ls @@ -1849,7 +1848,7 @@ function move_line_start(s::MIState) if s.key_repeats > 0 move_input_start(s) else - seek(buf, findprev(equalto(UInt8('\n')), buf.data, curpos)) + seek(buf, coalesce(findprev(equalto(UInt8('\n')), buf.data, curpos), 0)) end end @@ -1863,7 +1862,7 @@ end function move_line_end(buf::IOBuffer) eof(buf) && return pos = findnext(equalto(UInt8('\n')), buf.data, position(buf)+1) - if pos == 0 + if pos === nothing move_input_end(buf) return end @@ -1922,7 +1921,7 @@ end function edit_insert_tab(buf::IOBuffer, jump_spaces=false, delete_trailing=jump_spaces) i = position(buf) if jump_spaces && i < buf.size && buf.data[i+1] == _space - spaces = findnext(_notspace, buf.data[i+1:buf.size], 1) + spaces = coalesce(findnext(_notspace, buf.data[i+1:buf.size], 1), 0) if delete_trailing && (spaces == 0 || buf.data[i+spaces] == _newline) edit_splice!(buf, i => (spaces == 0 ? buf.size : i+spaces-1)) else diff --git a/base/repl/REPL.jl b/base/repl/REPL.jl index 033398e5ecb83..3c78df19baff5 100644 --- a/base/repl/REPL.jl +++ b/base/repl/REPL.jl @@ -803,7 +803,7 @@ function setup_interface( repl = repl, complete = replc, # When we're done transform the entered line into a call to help("$line") - on_done = respond(Docs.helpmode, repl, julia_prompt)) + on_done = respond(Docs.helpmode, repl, julia_prompt, pass_empty=true)) # Set up shell mode shell_mode = Prompt("shell> "; @@ -888,7 +888,7 @@ function setup_interface( sbuffer = LineEdit.buffer(s) curspos = position(sbuffer) seek(sbuffer, 0) - shouldeval = (nb_available(sbuffer) == curspos && findfirst(equalto(UInt8('\n')), sbuffer) == 0) + shouldeval = (nb_available(sbuffer) == curspos && findfirst(equalto(UInt8('\n')), sbuffer) === nothing) seek(sbuffer, curspos) if curspos == 0 # if pasting at the beginning, strip leading whitespace @@ -1051,7 +1051,7 @@ input_color(r::StreamREPL) = r.input_color # at the end of the expression was intended for suppressing output function ends_with_semicolon(line::AbstractString) match = findlast(equalto(';'), line) - if match != 0 + if match !== nothing # state for comment parser, assuming that the `;` isn't in a string or comment # so input like ";#" will still thwart this to give the wrong (anti-conservative) answer comment = false @@ -1090,7 +1090,7 @@ function ends_with_semicolon(line::AbstractString) else # outside of a comment, encountering anything but whitespace # means the semi-colon was internal to the expression - Base.Unicode.isspace(c) || return false + isspace(c) || return false end end return true diff --git a/base/repl/REPLCompletions.jl b/base/repl/REPLCompletions.jl index 4c88d236fee6f..f76116768dc59 100644 --- a/base/repl/REPLCompletions.jl +++ b/base/repl/REPLCompletions.jl @@ -5,6 +5,7 @@ module REPLCompletions export completions, shell_completions, bslash_completions using Base.Meta +using Base: coalesce function completes_global(x, name) return startswith(x, name) && !('#' in x) @@ -40,7 +41,7 @@ function complete_symbol(sym, ffunc) lookup_module = true t = Union{} - if findlast(occursin(non_identifier_chars), sym) < findlast(equalto('.'), sym) + if coalesce(findlast(occursin(non_identifier_chars), sym), 0) < coalesce(findlast(equalto('.'), sym), 0) # Find module lookup_name, name = rsplit(sym, ".", limit=2) @@ -258,7 +259,7 @@ function find_start_brace(s::AbstractString; c_start='(', c_end=')') end braces != 1 && return 0:-1, -1 method_name_end = reverseind(s, i) - startind = nextind(s, findprev(occursin(non_identifier_chars), s, method_name_end)) + startind = nextind(s, coalesce(findprev(occursin(non_identifier_chars), s, method_name_end), 0)) return (startind:endof(s), method_name_end) end @@ -413,8 +414,8 @@ function afterusing(string::String, startpos::Int) end function bslash_completions(string, pos) - slashpos = findprev(equalto('\\'), string, pos) - if (findprev(occursin(bslash_separators), string, pos) < slashpos && + slashpos = coalesce(findprev(equalto('\\'), string, pos), 0) + if (coalesce(findprev(occursin(bslash_separators), string, pos), 0) < slashpos && !(1 < slashpos && (string[prevind(string, slashpos)]=='\\'))) # latex / emoji symbol substitution s = string[slashpos:pos] @@ -495,7 +496,7 @@ function completions(string, pos) # otherwise... if inc_tag in [:cmd, :string] - m = match(r"[\t\n\r\"><=*?|]| (?!\\)", reverse(partial)) + m = match(r"[\t\n\r\"`><=*?|]| (?!\\)", reverse(partial)) startpos = nextind(partial, reverseind(partial, m.offset)) r = startpos:pos @@ -533,8 +534,8 @@ function completions(string, pos) return String[], 0:-1, false end - dotpos = findprev(equalto('.'), string, pos) - startpos = nextind(string, findprev(occursin(non_identifier_chars), string, pos)) + dotpos = coalesce(findprev(equalto('.'), string, pos), 0) + startpos = nextind(string, coalesce(findprev(occursin(non_identifier_chars), string, pos), 0)) ffunc = (mod,x)->true suggestions = String[] diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index 005be471253b4..e7749b9a97960 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -52,7 +52,7 @@ the specified dimensions is equal to the length of the original array `A`. The total number of elements must not change. ```jldoctest -julia> A = collect(1:16) +julia> A = Vector(1:16) 16-element Array{Int64,1}: 1 2 @@ -142,7 +142,7 @@ _reshape(parent::Array, dims::Dims) = reshape(parent, dims) # When reshaping Vector->Vector, don't wrap with a ReshapedArray function _reshape(v::AbstractVector, dims::Dims{1}) len = dims[1] - len == length(v) || _throw_dmrs(n, "length", len) + len == length(v) || _throw_dmrs(_length(v), "length", len) v end # General reshape diff --git a/base/serialize.jl b/base/serialize.jl index 6ef393c4157bf..fedb64fc5d6c2 100644 --- a/base/serialize.jl +++ b/base/serialize.jl @@ -1195,14 +1195,4 @@ function deserialize(s::AbstractSerializer, t::Type{Regex}) Regex(pattern, compile_options, match_options) end -if !Sys.iswindows() - function serialize(s::AbstractSerializer, rd::RandomDevice) - serialize_type(s, typeof(rd)) - serialize(s, rd.unlimited) - end - function deserialize(s::AbstractSerializer, t::Type{RandomDevice}) - unlimited = deserialize(s) - return RandomDevice(unlimited) - end -end end diff --git a/base/set.jl b/base/set.jl index 808f640d6f145..e58647df0f632 100644 --- a/base/set.jl +++ b/base/set.jl @@ -261,9 +261,11 @@ function symdiff!(s::AbstractSet, itr) s end -==(l::Set, r::Set) = (length(l) == length(r)) && (l <= r) -<( l::Set, r::Set) = (length(l) < length(r)) && (l <= r) -<=(l::Set, r::Set) = issubset(l, r) +==(l::AbstractSet, r::AbstractSet) = length(l) == length(r) && l ⊆ r +# convenience functions for AbstractSet +# (if needed, only their synonyms ⊊ and ⊆ must be specialized) +<( l::AbstractSet, r::AbstractSet) = l ⊊ r +<=(l::AbstractSet, r::AbstractSet) = l ⊆ r """ issubset(a, b) @@ -290,21 +292,35 @@ function issubset(l, r) end return true end - # use the implementation below when it becoms as efficient # issubset(l, r) = all(_in(r), l) const ⊆ = issubset -⊊(l::Set, r::Set) = <(l, r) -⊈(l::Set, r::Set) = !⊆(l, r) -⊇(l, r) = issubset(r, l) -⊉(l::Set, r::Set) = !⊇(l, r) -⊋(l::Set, r::Set) = <(r, l) -⊊(l::T, r::T) where {T<:AbstractSet} = <(l, r) -⊈(l::T, r::T) where {T<:AbstractSet} = !⊆(l, r) -⊉(l::T, r::T) where {T<:AbstractSet} = !⊇(l, r) -⊋(l::T, r::T) where {T<:AbstractSet} = <(r, l) +""" + issetequal(a, b) + +Determine whether `a` and `b` have the same elements. Equivalent +to `a ⊆ b && b ⊆ a`. + +# Examples +```jldoctest +julia> issetequal([1, 2], [1, 2, 3]) +false + +julia> issetequal([1, 2], [2, 1]) +true +``` +""" +issetequal(l, r) = length(l) == length(r) && l ⊆ r +issetequal(l::AbstractSet, r::AbstractSet) = l == r + +⊊(l, r) = length(l) < length(r) && l ⊆ r +⊈(l, r) = !⊆(l, r) + +⊇(l, r) = r ⊆ l +⊉(l, r) = r ⊈ l +⊋(l, r) = r ⊊ l """ unique(itr) @@ -337,7 +353,7 @@ function unique(itr) return out end x, i = next(itr, i) - if !_isleaftype(T) && iteratoreltype(itr) == EltypeUnknown() + if !_isleaftype(T) && IteratorEltype(itr) == EltypeUnknown() S = typeof(x) return _unique_from(itr, S[x], Set{S}((x,)), i) end @@ -534,7 +550,7 @@ function mapfilter(pred, f, itr, res) end const hashs_seed = UInt === UInt64 ? 0x852ada37cfe8e0ce : 0xcfe8e0ce -function hash(s::Set, h::UInt) +function hash(s::AbstractSet, h::UInt) hv = hashs_seed for x in s hv ⊻= hash(x) @@ -548,6 +564,10 @@ convert(::Type{T}, s::AbstractSet) where {T<:AbstractSet} = T(s) ## replace/replace! ## +# to make replace/replace! work for a new container type Cont, only +# replace!(prednew::Callable, A::Cont; count::Integer=typemax(Int)) +# has to be implemented + """ replace!(A, old_new::Pair...; [count::Integer]) @@ -641,12 +661,12 @@ julia> replace!(x->2x, Set([3, 6])) Set([6, 12]) ``` """ -replace!(prednew::Callable, A; count::Integer=typemax(Int)) = - replace!(prednew, A, count=clamp(count, typemin(Int), typemax(Int)) % Int) - - -replace!(prednew::Callable, A; count::Int=typemax(Int)) = - throw(MethodError(replace!, (prednew, A))) +function replace!(prednew::Callable, A::Union{AbstractArray,AbstractDict,AbstractSet}; + count::Integer=typemax(Int)) + count < 0 && throw(DomainError(count, "`count` must not be negative")) + count != 0 && _replace!(prednew, A, min(count, typemax(Int)) % Int) + A +end """ replace(A, old_new::Pair...; [count::Integer]) @@ -746,9 +766,7 @@ end _replace_update_dict!(repl::Vector{<:Pair}, x, ::Nothing) = false _replace_update_dict!(repl::Vector{<:Pair}, x, y) = _replace_update_dict!(repl, x, Some(y)) -function replace!(prednew::Callable, A::Union{AbstractDict,AbstractSet}; count::Int=typemax(Int)) - count < 0 && throw(DomainError(count, "`count` must not be negative")) - count == 0 && return A +function _replace!(prednew::Callable, A::Union{AbstractDict,AbstractSet}, count::Int) repl = Pair{eltype(A),eltype(A)}[] c = 0 for x in A @@ -761,7 +779,6 @@ function replace!(prednew::Callable, A::Union{AbstractDict,AbstractSet}; count:: for oldnew in repl push!(A, last(oldnew)) end - A end ### AbstractArray @@ -774,13 +791,10 @@ end _replace_update!(A::AbstractArray, i::Integer, ::Nothing) = false _replace_update!(A::AbstractArray, i::Integer, y) = _replace_update!(A, i, Some(y)) -function replace!(prednew::Callable, A::AbstractArray; count::Int=typemax(Int)) - count < 0 && throw(DomainError(count, "`count` must not be negative")) - count == 0 && return A +function _replace!(prednew::Callable, A::AbstractArray, count::Int) c = 0 for i in eachindex(A) c += _replace_update!(A, i, prednew(A[i])) c == count && break end - A end diff --git a/base/shell.jl b/base/shell.jl index bd362bcb40a93..f172263a1fbea 100644 --- a/base/shell.jl +++ b/base/shell.jl @@ -54,13 +54,13 @@ function shell_parse(str::AbstractString, interpolate::Bool=true; while !done(s,j) c, k = next(s,j) - if !in_single_quotes && !in_double_quotes && Unicode.isspace(c) + if !in_single_quotes && !in_double_quotes && isspace(c) update_arg(s[i:prevind(s, j)]) append_arg() j = k while !done(s,j) c, k = next(s,j) - if !Unicode.isspace(c) + if !isspace(c) i = j break end @@ -71,7 +71,7 @@ function shell_parse(str::AbstractString, interpolate::Bool=true; if done(s,k) error("\$ right before end of command") end - if Unicode.isspace(s[k]) + if isspace(s[k]) error("space not allowed right after \$") end stpos = j @@ -140,7 +140,7 @@ function print_shell_word(io::IO, word::AbstractString, special::AbstractString has_single = false has_special = false for c in word - if Unicode.isspace(c) || c=='\\' || c=='\'' || c=='"' || c=='$' || c in special + if isspace(c) || c=='\\' || c=='\'' || c=='"' || c=='$' || c in special has_special = true if c == '\'' has_single = true diff --git a/base/show.jl b/base/show.jl index 244faae9261ac..233ecfdacdc37 100644 --- a/base/show.jl +++ b/base/show.jl @@ -73,6 +73,28 @@ The following properties are in common use: `--color` command-line flag when `julia` was launched. # Examples + +```jldoctest +julia> io = IOBuffer(); + +julia> print_with_color(:red, IOContext(io, :color => true), "string") + +julia> String(take!(io)) +"\e[31mstring\e[39m" + +julia> print_with_color(:red, io, "string") + +julia> String(take!(io)) +"string" +``` + +```jldoctest +julia> print(IOContext(STDOUT, :compact => false), 1.12341234) +1.12341234 +julia> print(IOContext(STDOUT, :compact => true), 1.12341234) +1.12341 +``` + ```jldoctest julia> function f(io::IO) if get(io, :short, false) @@ -724,7 +746,7 @@ end emphasize(io, str::AbstractString) = get(io, :color, false) ? print_with_color(Base.error_color(), io, str; bold = true) : - print(io, Unicode.uppercase(str)) + print(io, uppercase(str)) show_linenumber(io::IO, line) = print(io, "#= line ", line, " =#") show_linenumber(io::IO, line, file) = print(io, "#= ", file, ":", line, " =#") diff --git a/base/stacktraces.jl b/base/stacktraces.jl index 0a3c5bcd5becb..7707aa31af903 100644 --- a/base/stacktraces.jl +++ b/base/stacktraces.jl @@ -9,6 +9,7 @@ module StackTraces import Base: hash, ==, show import Base.Serializer: serialize, deserialize using Base.Printf: @printf +using Base: coalesce export StackTrace, StackFrame, stacktrace, catch_stacktrace @@ -277,12 +278,12 @@ all frames above the specified function). Primarily used to remove `StackTraces` from the `StackTrace` prior to returning it. """ function remove_frames!(stack::StackTrace, name::Symbol) - splice!(stack, 1:findlast(frame -> frame.func == name, stack)) + splice!(stack, 1:coalesce(findlast(frame -> frame.func == name, stack), 0)) return stack end function remove_frames!(stack::StackTrace, names::Vector{Symbol}) - splice!(stack, 1:findlast(frame -> frame.func in names, stack)) + splice!(stack, 1:coalesce(findlast(frame -> frame.func in names, stack), 0)) return stack end diff --git a/base/statistics.jl b/base/statistics.jl index c8f24c7ac39d5..80dff1d94e93d 100644 --- a/base/statistics.jl +++ b/base/statistics.jl @@ -330,11 +330,11 @@ unscaled_covzm(x::AbstractMatrix, vardim::Int) = (vardim == 1 ? _conj(x'x) : x * unscaled_covzm(x::AbstractVector, y::AbstractVector) = dot(y, x) unscaled_covzm(x::AbstractVector, y::AbstractMatrix, vardim::Int) = - (vardim == 1 ? *(Transpose(x), _conj(y)) : *(Transpose(x), Transpose(_conj(y)))) + (vardim == 1 ? *(transpose(x), _conj(y)) : *(transpose(x), transpose(_conj(y)))) unscaled_covzm(x::AbstractMatrix, y::AbstractVector, vardim::Int) = - (c = vardim == 1 ? *(Transpose(x), _conj(y)) : x * _conj(y); reshape(c, length(c), 1)) + (c = vardim == 1 ? *(transpose(x), _conj(y)) : x * _conj(y); reshape(c, length(c), 1)) unscaled_covzm(x::AbstractMatrix, y::AbstractMatrix, vardim::Int) = - (vardim == 1 ? *(Transpose(x), _conj(y)) : *(x, Adjoint(y))) + (vardim == 1 ? *(transpose(x), _conj(y)) : *(x, adjoint(y))) # covzm (with centered data) diff --git a/base/stream.jl b/base/stream.jl index 58bf399afb26b..cb800a0728dc2 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -271,13 +271,13 @@ end function wait_readbyte(x::LibuvStream, c::UInt8) if isopen(x) # fast path - findfirst(equalto(c), x.buffer) > 0 && return + findfirst(equalto(c), x.buffer) !== nothing && return else return end preserve_handle(x) try - while isopen(x) && findfirst(equalto(c), x.buffer) <= 0 + while isopen(x) && coalesce(findfirst(equalto(c), x.buffer), 0) <= 0 start_reading(x) # ensure we are reading wait(x.readnotify) end @@ -1073,7 +1073,7 @@ for (x, writable, unix_fd, c_symbol) in ((:STDIN, false, 0, :jl_uv_stdin), (:STDOUT, true, 1, :jl_uv_stdout), (:STDERR, true, 2, :jl_uv_stderr)) - f = Symbol("redirect_",Unicode.lowercase(string(x))) + f = Symbol("redirect_",lowercase(string(x))) _f = Symbol("_",f) @eval begin function ($_f)(stream) @@ -1237,7 +1237,7 @@ end show(io::IO, s::BufferStream) = print(io,"BufferStream() bytes waiting:",nb_available(s.buffer),", isopen:", s.is_open) function wait_readbyte(s::BufferStream, c::UInt8) - while isopen(s) && findfirst(equalto(c), s.buffer) <= 0 + while isopen(s) && findfirst(equalto(c), s.buffer) === nothing wait(s.r_c) end end diff --git a/base/strings/basic.jl b/base/strings/basic.jl index 0fba9536b194e..5b9f00874a5a3 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -82,7 +82,7 @@ I.e. the value returned by `codeunit(s, i)` is of the type returned by See also: [`ncodeunits`](@ref), [`checkbounds`](@ref) """ @propagate_inbounds codeunit(s::AbstractString, i::Integer) = typeof(i) === Int ? - throw(MethodError(codeunit, Tuple{typeof(s),Int})) : codeunit(s, Int(i)) + throw(MethodError(codeunit, (s, i))) : codeunit(s, Int(i)) """ isvalid(s::AbstractString, i::Integer) -> Bool @@ -119,7 +119,7 @@ Stacktrace: ``` """ @propagate_inbounds isvalid(s::AbstractString, i::Integer) = typeof(i) === Int ? - throw(MethodError(isvalid, Tuple{typeof(s),Int})) : isvalid(s, Int(i)) + throw(MethodError(isvalid, (s, i))) : isvalid(s, Int(i)) """ next(s::AbstractString, i::Integer) -> Tuple{Char, Int} @@ -134,7 +134,7 @@ See also: [`getindex`](@ref), [`start`](@ref), [`done`](@ref), [`checkbounds`](@ref) """ @propagate_inbounds next(s::AbstractString, i::Integer) = typeof(i) === Int ? - throw(MethodError(next, Tuple{typeof(s),Int})) : next(s, Int(i)) + throw(MethodError(next, (s, i))) : next(s, Int(i)) ## basic generic definitions ## @@ -223,11 +223,11 @@ one(::Union{T,Type{T}}) where {T<:AbstractString} = convert(T, "") """ cmp(a::AbstractString, b::AbstractString) -> Int -Compare two strings for equality. Return `0` if both strings have the same -length and the character at each index is the same in both strings. Return `-1` -if `a` is a substring of `b`, or if `a` comes before `b` in alphabetical order. -Return `1` if `b` is a substring of `a`, or if `b` comes before `a` in -alphabetical order (technically, lexicographical order by Unicode code points). +Compare two strings. Return `0` if both strings have the same length and the character +at each index is the same in both strings. Return `-1` if `a` is a prefix of `b`, or if +`a` comes before `b` in alphabetical order. Return `1` if `b` is a prefix of `a`, or if +`b` comes before `a` in alphabetical order (technically, lexicographical order by Unicode +code points). # Examples ```jldoctest @@ -512,7 +512,7 @@ isascii(s::AbstractString) = all(isascii, s) ## string map, filter, has ## function map(f, s::AbstractString) - out = IOBuffer(StringVector(endof(s)), true, true) + out = IOBuffer(StringVector(sizeof(s)), true, true) truncate(out, 0) for c in s c′ = f(c) @@ -525,7 +525,7 @@ function map(f, s::AbstractString) end function filter(f, s::AbstractString) - out = IOBuffer(StringVector(endof(s)), true, true) + out = IOBuffer(StringVector(sizeof(s)), true, true) truncate(out, 0) for c in s f(c) && write(out, c) diff --git a/base/strings/io.jl b/base/strings/io.jl index ca008fc61506f..f97dec3b61de2 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -245,7 +245,7 @@ join(strings, delim, last) = sprint(join, strings, delim, last) ## string escaping & unescaping ## -need_full_hex(s::AbstractString, i::Int) = !done(s,i) && Unicode.isxdigit(next(s,i)[1]) +need_full_hex(s::AbstractString, i::Int) = !done(s,i) && isxdigit(next(s,i)[1]) escape_nul(s::AbstractString, i::Int) = !done(s,i) && '0' <= next(s,i)[1] <= '7' ? "\\x00" : "\\0" @@ -271,16 +271,16 @@ function escape_string(io, s::AbstractString, esc::AbstractString="") c, j = next(s,i) if c in esc print(io, '\\', c) - elseif Unicode.isascii(c) + elseif isascii(c) c == '\0' ? print(io, escape_nul(s,j)) : c == '\e' ? print(io, "\\e") : c == '\\' ? print(io, "\\\\") : c in esc ? print(io, '\\', c) : '\a' <= c <= '\r' ? print(io, '\\', "abtnvfr"[Int(c)-6]) : - Unicode.isprint(c) ? print(io, c) : + isprint(c) ? print(io, c) : print(io, "\\x", hex(c, 2)) elseif !isoverlong(c) && !ismalformed(c) - Unicode.isprint(c) ? print(io, c) : + isprint(c) ? print(io, c) : c <= '\x7f' ? print(io, "\\x", hex(c, 2)) : c <= '\uffff' ? print(io, "\\u", hex(c, need_full_hex(s, j) ? 4 : 2)) : print(io, "\\U", hex(c, need_full_hex(s, j) ? 8 : 4)) @@ -374,7 +374,7 @@ function unescape_string(io, s::AbstractString) end macro b_str(s) - v = Vector{UInt8}(codeunits(unescape_string(s))) + v = codeunits(unescape_string(s)) QuoteNode(v) end diff --git a/base/strings/search.jl b/base/strings/search.jl index 8002e9fdd59e1..82434b40689e1 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -1,24 +1,27 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +nothing_sentinel(i) = i == 0 ? nothing : i + function findnext(pred::EqualTo{Char}, s::String, i::Integer) if i < 1 || i > sizeof(s) - i == sizeof(s) + 1 && return 0 + i == sizeof(s) + 1 && return nothing throw(BoundsError(s, i)) end @inbounds isvalid(s, i) || string_index_err(s, i) c = pred.x - c ≤ '\x7f' && return _search(s, c % UInt8, i) + c ≤ '\x7f' && return nothing_sentinel(_search(s, c % UInt8, i)) while true i = _search(s, first_utf8_byte(c), i) - (i == 0 || s[i] == c) && return i + i == 0 && return nothing + s[i] == c && return i i = next(s, i)[2] end end -findfirst(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = _search(a, pred.x) +findfirst(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = nothing_sentinel(_search(a, pred.x)) findnext(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray, i::Integer) = - _search(a, pred.x, i) + nothing_sentinel(_search(a, pred.x, i)) function _search(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = 1) if i < 1 @@ -43,19 +46,20 @@ end function findprev(pred::EqualTo{Char}, s::String, i::Integer) c = pred.x - c ≤ '\x7f' && return _rsearch(s, c % UInt8, i) + c ≤ '\x7f' && return nothing_sentinel(_rsearch(s, c % UInt8, i)) b = first_utf8_byte(c) while true i = _rsearch(s, b, i) - (i == 0 || s[i] == c) && return i + i == 0 && return nothing + s[i] == c && return i i = prevind(s, i) end end -findlast(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = _rsearch(a, pred.x) +findlast(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = nothing_sentinel(_rsearch(a, pred.x)) findprev(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray, i::Integer) = - _rsearch(a, pred.x, i) + nothing_sentinel(_rsearch(a, pred.x, i)) function _rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = sizeof(a)) if i < 1 @@ -109,10 +113,10 @@ function findnext(testf::Function, s::AbstractString, i::Integer) end i = j end - return 0 + return nothing end -in(c::Char, s::AbstractString) = (findfirst(equalto(c),s)!=0) +in(c::Char, s::AbstractString) = (findfirst(equalto(c),s)!==nothing) function _searchindex(s::Union{AbstractString,ByteArray}, t::Union{AbstractString,Char,Int8,UInt8}, @@ -124,7 +128,7 @@ function _searchindex(s::Union{AbstractString,ByteArray}, t1, j2 = next(t,start(t)) while true i = findnext(equalto(t1),s,i) - if i == 0 return 0 end + if i === nothing return 0 end c, ii = next(s,i) j = j2; k = ii matched = true @@ -147,7 +151,7 @@ function _searchindex(s::Union{AbstractString,ByteArray}, end end -_searchindex(s::AbstractString, t::Char, i::Integer) = findnext(equalto(t), s, i) +_searchindex(s::AbstractString, t::Char, i::Integer) = coalesce(findnext(equalto(t), s, i), 0) function _search_bloom_mask(c) UInt64(1) << (c & 63) @@ -158,7 +162,7 @@ _nthbyte(a::Union{AbstractVector{UInt8},AbstractVector{Int8}}, i) = a[i] function _searchindex(s::String, t::String, i::Integer) # Check for fast case of a single byte - endof(t) == 1 && return findnext(equalto(t[1]), s, i) + endof(t) == 1 && return coalesce(findnext(equalto(t[1]), s, i), 0) _searchindex(unsafe_wrap(Vector{UInt8},s), unsafe_wrap(Vector{UInt8},t), i) end @@ -171,7 +175,7 @@ function _searchindex(s::ByteArray, t::ByteArray, i::Integer) elseif m == 0 return 0 elseif n == 1 - return findnext(equalto(_nthbyte(t,1)), s, i) + return coalesce(findnext(equalto(_nthbyte(t,1)), s, i), 0) end w = m - n @@ -284,17 +288,17 @@ findlast(pattern::AbstractString, string::AbstractString) = # AbstractString implementation of the generic findprev interface function findprev(testf::Function, s::AbstractString, i::Integer) if i < 1 - return i == 0 ? 0 : throw(BoundsError(s, i)) + return i == 0 ? nothing : throw(BoundsError(s, i)) end n = ncodeunits(s) if i > n - return i == n+1 ? 0 : throw(BoundsError(s, i)) + return i == n+1 ? nothing : throw(BoundsError(s, i)) end # r[reverseind(r,i)] == reverse(r)[i] == s[i] # s[reverseind(s,j)] == reverse(s)[j] == r[j] r = reverse(s) j = findnext(testf, r, reverseind(r, i)) - j == 0 ? 0 : reverseind(s, j) + j === nothing ? nothing : reverseind(s, j) end function _rsearchindex(s::AbstractString, @@ -310,7 +314,7 @@ function _rsearchindex(s::AbstractString, t1, j2 = next(t, start(t)) while true i = findprev(equalto(t1), s, i) - i == 0 && return 0 + i === nothing && return 0 c, ii = next(rs, reverseind(rs, i)) j = j2; k = ii matched = true @@ -334,7 +338,7 @@ end function _rsearchindex(s::String, t::String, i::Integer) # Check for fast case of a single byte if endof(t) == 1 - return findprev(equalto(t[1]), s, i) + return coalesce(findprev(equalto(t[1]), s, i), 0) elseif endof(t) != 0 j = i ≤ ncodeunits(s) ? nextind(s, i)-1 : i return _rsearchindex(unsafe_wrap(Vector{UInt8}, s), unsafe_wrap(Vector{UInt8}, t), j) @@ -356,7 +360,7 @@ function _rsearchindex(s::ByteArray, t::ByteArray, k::Integer) elseif m == 0 return 0 elseif n == 1 - return findprev(equalto(_nthbyte(t,1)), s, k) + return coalesce(findprev(equalto(_nthbyte(t,1)), s, k), 0) end w = m - n diff --git a/base/strings/string.jl b/base/strings/string.jl index 498e2256896bd..498558f3a65c5 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -37,7 +37,7 @@ Copy a string from the address of a C-style (NUL-terminated) string encoded as U (The pointer can be safely freed afterwards.) If `length` is specified (the length of the data in bytes), the string does not have to be NUL-terminated. -This function is labelled "unsafe" because it will crash if `p` is not +This function is labeled "unsafe" because it will crash if `p` is not a valid memory address to data of the requested length. """ function unsafe_string(p::Union{Ptr{UInt8},Ptr{Int8}}, len::Integer) @@ -64,6 +64,8 @@ unsafe_wrap(::Type{Vector{UInt8}}, s::String) = ccall(:jl_string_to_array, Ref{V (::Type{Vector{UInt8}})(s::CodeUnits{UInt8,String}) = copyto!(Vector{UInt8}(uninitialized, length(s)), s) +String(a::AbstractVector{UInt8}) = String(copyto!(StringVector(length(a)), a)) + String(s::CodeUnits{UInt8,String}) = s.s ## low-level functions ## diff --git a/base/strings/strings.jl b/base/strings/strings.jl index 0edc0c4e4bba6..326fd0f2e2a2a 100644 --- a/base/strings/strings.jl +++ b/base/strings/strings.jl @@ -3,5 +3,9 @@ include("strings/substring.jl") include("strings/search.jl") include("strings/unicode.jl") + +import .Unicode: textwidth, islower, isupper, isalpha, isdigit, isnumeric, iscntrl, ispunct, + isspace, isprint, isxdigit, lowercase, uppercase, titlecase, lcfirst, ucfirst + include("strings/util.jl") include("strings/io.jl") diff --git a/base/strings/unicode.jl b/base/strings/unicode.jl index 96eaa0d65342d..7a70516f42471 100644 --- a/base/strings/unicode.jl +++ b/base/strings/unicode.jl @@ -259,8 +259,6 @@ Give the number of columns needed to print a character. # Examples ```jldoctest -julia> using Unicode - julia> textwidth('α') 1 @@ -280,8 +278,6 @@ Give the number of columns needed to print a string. # Examples ```jldoctest -julia> using Unicode - julia> textwidth("March") 5 ``` @@ -329,7 +325,7 @@ julia> isassigned('\\x01') true ``` """ -isassigned(c) = category_code(c) != UTF8PROC_CATEGORY_CN +isassigned(c) = UTF8PROC_CATEGORY_CN < category_code(c) <= UTF8PROC_CATEGORY_CO ## libc character class predicates ## @@ -342,8 +338,6 @@ Letter: Lowercase. # Examples ```jldoctest -julia> using Unicode - julia> islower('α') true @@ -367,8 +361,6 @@ Letter: Uppercase, or Lt, Letter: Titlecase. # Examples ```jldoctest -julia> using Unicode - julia> isupper('γ') false @@ -384,6 +376,19 @@ function isupper(c::Char) cat == UTF8PROC_CATEGORY_LU || cat == UTF8PROC_CATEGORY_LT end +""" + iscased(c::Char) -> Bool + +Tests whether a character is cased, i.e. is lower-, upper- or title-cased. +""" +function iscased(c::Char) + cat = category_code(c) + return cat == UTF8PROC_CATEGORY_LU || + cat == UTF8PROC_CATEGORY_LT || + cat == UTF8PROC_CATEGORY_LL +end + + """ isdigit(c::Char) -> Bool @@ -391,8 +396,6 @@ Tests whether a character is a decimal digit (0-9). # Examples ```jldoctest -julia> using Unicode - julia> isdigit('❤') false @@ -414,8 +417,6 @@ category Letter, i.e. a character whose category code begins with 'L'. # Examples ```jldoctest -julia> using Unicode - julia> isalpha('❤') false @@ -440,8 +441,6 @@ Use [`isdigit`](@ref) to check whether a character a decimal digit between 0 and # Examples ```jldoctest -julia> using Unicode - julia> isnumeric('௰') true @@ -457,33 +456,6 @@ false """ isnumeric(c::Char) = UTF8PROC_CATEGORY_ND <= category_code(c) <= UTF8PROC_CATEGORY_NO -""" - isalnum(c::Char) -> Bool - -Tests whether a character is alphanumeric. -A character is classified as alphabetic if it belongs to the Unicode general -category Letter or Number, i.e. a character whose category code begins with 'L' or 'N'. - -# Examples -```jldoctest -julia> using Unicode - -julia> isalnum('❤') -false - -julia> isalnum('9') -true - -julia> isalnum('α') -true -``` -""" -function isalnum(c::Char) - cat = category_code(c) - UTF8PROC_CATEGORY_LU <= cat <= UTF8PROC_CATEGORY_LO || - UTF8PROC_CATEGORY_ND <= cat <= UTF8PROC_CATEGORY_NO -end - # following C++ only control characters from the Latin-1 subset return true """ @@ -494,8 +466,6 @@ Control characters are the non-printing characters of the Latin-1 subset of Unic # Examples ```jldoctest -julia> using Unicode - julia> iscntrl('\\x01') true @@ -513,8 +483,6 @@ character whose category code begins with 'P'. # Examples ```jldoctest -julia> using Unicode - julia> ispunct('α') false @@ -538,8 +506,6 @@ category Zs. # Examples ```jldoctest -julia> using Unicode - julia> isspace('\\n') true @@ -564,8 +530,6 @@ Tests whether a character is printable, including spaces, but not a control char # Examples ```jldoctest -julia> using Unicode - julia> isprint('\\x01') false @@ -577,26 +541,6 @@ isprint(c::Char) = UTF8PROC_CATEGORY_LU <= category_code(c) <= UTF8PROC_CATEGORY # true in principal if a printer would use ink -""" - isgraph(c::Char) -> Bool - -Tests whether a character is printable, and not a space. -Any character that would cause a printer to use ink should be -classified with `isgraph(c)==true`. - -# Examples -```jldoctest -julia> using Unicode - -julia> isgraph('\\x01') -false - -julia> isgraph('A') -true -``` -""" -isgraph(c::Char) = UTF8PROC_CATEGORY_LU <= category_code(c) <= UTF8PROC_CATEGORY_SO - """ isxdigit(c::Char) -> Bool @@ -605,8 +549,6 @@ include `x` (as in the standard `0x` prefix). # Examples ```jldoctest -julia> using Unicode - julia> isxdigit('a') true @@ -625,8 +567,6 @@ Return `s` with all characters converted to uppercase. # Examples ```jldoctest -julia> using Unicode - julia> uppercase("Julia") "JULIA" ``` @@ -640,8 +580,6 @@ Return `s` with all characters converted to lowercase. # Examples ```jldoctest -julia> using Unicode - julia> lowercase("STRINGS AND THINGS") "strings and things" ``` @@ -649,27 +587,38 @@ julia> lowercase("STRINGS AND THINGS") lowercase(s::AbstractString) = map(lowercase, s) """ - titlecase(s::AbstractString) -> String + titlecase(s::AbstractString; [wordsep::Function], strict::Bool=true) -> String -Capitalize the first character of each word in `s`. +Capitalize the first character of each word in `s`; +if `strict` is true, every other character is +converted to lowercase, otherwise they are left unchanged. +By default, all non-letters are considered as word separators; +a predicate can be passed as the `wordsep` keyword to determine +which characters should be considered as word separators. See also [`ucfirst`](@ref) to capitalize only the first character in `s`. # Examples ```jldoctest -julia> titlecase("the Julia programming language") +julia> titlecase("the JULIA programming language") "The Julia Programming Language" + +julia> titlecase("ISS - international space station", strict=false) +"ISS - International Space Station" + +julia> titlecase("a-a b-b", wordsep = c->c==' ') +"A-a B-b" ``` """ -function titlecase(s::AbstractString) +function titlecase(s::AbstractString; wordsep::Function = !iscased, strict::Bool=true) startword = true b = IOBuffer() for c in s - if isspace(c) + if wordsep(c) print(b, c) startword = true else - print(b, startword ? titlecase(c) : c) + print(b, startword ? titlecase(c) : strict ? lowercase(c) : c) startword = false end end diff --git a/base/strings/util.jl b/base/strings/util.jl index 80788e9b07e13..e477bfd42788a 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -177,15 +177,14 @@ julia> rstrip(a) ``` """ function rstrip(s::AbstractString, chars::Chars=_default_delims) - a = start(s) i = endof(s) - while a ≤ i + while 1 ≤ i c = s[i] j = prevind(s, i) c in chars || return SubString(s, 1:i) i = j end - SubString(s, a, a-1) + SubString(s, 1, 0) end """ @@ -299,7 +298,7 @@ split(str::T, splitter::Char; function _split(str::AbstractString, splitter, limit::Integer, keep_empty::Bool, strs::Array) i = start(str) n = endof(str) - r = findfirst(splitter,str) + r = coalesce(findfirst(splitter,str), 0) if r != 0:-1 j, k = first(r), nextind(str,last(r)) while 0 < j <= n && length(strs) != limit-1 @@ -310,7 +309,7 @@ function _split(str::AbstractString, splitter, limit::Integer, keep_empty::Bool, i = k end (k <= j) && (k = nextind(str,j)) - r = findnext(splitter,str,k) + r = coalesce(findnext(splitter,str,k), 0) r == 0:-1 && break j, k = first(r), nextind(str,last(r)) end @@ -366,7 +365,7 @@ rsplit(str::T, splitter::Char; function _rsplit(str::AbstractString, splitter, limit::Integer, keep_empty::Bool, strs::Array) i = start(str) n = endof(str) - r = findlast(splitter, str) + r = coalesce(findlast(splitter, str), 0) j = first(r)-1 k = last(r) while((0 <= j < n) && (length(strs) != limit-1)) @@ -375,7 +374,7 @@ function _rsplit(str::AbstractString, splitter, limit::Integer, keep_empty::Bool n = j end (k <= j) && (j = prevind(str,j)) - r = findprev(splitter,str,j) + r = coalesce(findprev(splitter,str,j), 0) j = first(r)-1 k = last(r) end @@ -400,7 +399,7 @@ function replace(str::String, pat_repl::Pair; count::Integer=typemax(Int)) n = 1 e = endof(str) i = a = start(str) - r = findnext(pattern,str,i) + r = coalesce(findnext(pattern,str,i), 0) j, k = first(r), last(r) out = IOBuffer(StringVector(floor(Int, 1.2sizeof(str))), true, true) out.size = 0 @@ -417,7 +416,7 @@ function replace(str::String, pat_repl::Pair; count::Integer=typemax(Int)) else i = k = nextind(str, k) end - r = findnext(pattern,str,k) + r = coalesce(findnext(pattern,str,k), 0) r == 0:-1 || n == count && break j, k = first(r), last(r) n += 1 diff --git a/base/sysimg.jl b/base/sysimg.jl index ab6906a7bd905..066457c4a0052 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -294,8 +294,13 @@ include("version.jl") include("sysinfo.jl") include("libc.jl") using .Libc: getpid, gethostname, time -include("libdl.jl") -using .Libdl: DL_LOAD_PATH + +const DL_LOAD_PATH = String[] +if Sys.isapple() + push!(DL_LOAD_PATH, "@loader_path/julia") + push!(DL_LOAD_PATH, "@loader_path") +end + include("env.jl") # Scheduling @@ -306,6 +311,31 @@ include("lock.jl") include("threads.jl") include("weakkeydict.jl") +# To limit dependency on rand functionality (implemented in the Random +# module), Crand is used in file.jl, and could be used in error.jl +# (but it breaks a test) +""" + Crand([T::Type]) + +Interface to the C `rand()` function. If `T` is provided, generate a value of type `T` +by composing two calls to `Crand()`. `T` can be `UInt32` or `Float64`. +""" +Crand() = ccall(:rand, Cuint, ()) +# RAND_MAX at least 2^15-1 in theory, but we assume 2^16-1 (in practice, it's 2^31-1) +Crand(::Type{UInt32}) = ((Crand() % UInt32) << 16) ⊻ (Crand() % UInt32) +Crand(::Type{Float64}) = Crand(UInt32) / 2^32 + +""" + Csrand([seed]) + +Interface the the C `srand(seed)` function. +""" +Csrand(seed=floor(time())) = ccall(:srand, Cvoid, (Cuint,), seed) + +# functions defined in Random +function rand end +function randn end + # I/O include("stream.jl") include("socket.jl") @@ -368,12 +398,6 @@ include("irrationals.jl") include("mathconstants.jl") using .MathConstants: ℯ, π, pi -# random number generation -include("random/dSFMT.jl") -include("random/random.jl") -using .Random -import .Random: rand, rand! - # (s)printf macros include("printf.jl") # import .Printf @@ -409,12 +433,6 @@ include("client.jl") # misc useful functions & macros include("util.jl") -# dense linear algebra -include("linalg/linalg.jl") -using .LinAlg -const ⋅ = dot -const × = cross - # statistics include("statistics.jl") @@ -427,12 +445,6 @@ include("libgit2/libgit2.jl") # package manager include("pkg/pkg.jl") -# sparse matrices, vectors, and sparse linear algebra -include("sparse/sparse.jl") -using .SparseArrays - -include("asyncmap.jl") - # worker threads include("threadcall.jl") @@ -448,6 +460,14 @@ import Base64 INCLUDE_STATE = 2 +# dense linear algebra +include("linalg/linalg.jl") +using .LinAlg +const ⋅ = dot +const × = cross + +include("asyncmap.jl") + include("multimedia.jl") using .Multimedia @@ -470,9 +490,11 @@ using .Docs, .Markdown isdefined(Core, :Inference) && Docs.loaddocs(Core.Inference.CoreDocs.DOCS) function __init__() + # for the few uses of Crand in Base: + Csrand() # Base library init reinit_stdio() - global_logger(SimpleLogger(STDERR)) + global_logger(root_module(:Logging).ConsoleLogger(STDERR)) Multimedia.reinit_displays() # since Multimedia.displays uses STDOUT as fallback early_init() init_load_path() @@ -493,18 +515,21 @@ Base.require(:Base64) Base.require(:CRC32c) Base.require(:Dates) Base.require(:DelimitedFiles) +Base.require(:Distributed) Base.require(:FileWatching) -Base.require(:Logging) +Base.require(:Future) Base.require(:IterativeEigensolvers) +Base.require(:Libdl) +Base.require(:Logging) Base.require(:Mmap) +Base.require(:Printf) Base.require(:Profile) +Base.require(:Random) Base.require(:SharedArrays) +Base.require(:SparseArrays) Base.require(:SuiteSparse) Base.require(:Test) Base.require(:Unicode) -Base.require(:Distributed) -Base.require(:Printf) -Base.require(:Future) @eval Base begin @deprecate_binding Test root_module(:Test) true ", run `using Test` instead" @@ -512,6 +537,20 @@ Base.require(:Future) @deprecate_binding Profile root_module(:Profile) true ", run `using Profile` instead" @deprecate_binding Dates root_module(:Dates) true ", run `using Dates` instead" @deprecate_binding Distributed root_module(:Distributed) true ", run `using Distributed` instead" + @deprecate_binding Random root_module(:Random) true ", run `using Random` instead" + + # PR #25249 + @deprecate_binding SparseArrays root_module(:SparseArrays) true ", run `using SparseArrays` instead" + @deprecate_binding(AbstractSparseArray, root_module(:SparseArrays).AbstractSparseArray, true, + ", run `using SparseArrays` to load sparse array functionality") + @deprecate_binding(AbstractSparseMatrix, root_module(:SparseArrays).AbstractSparseMatrix, true, + ", run `using SparseArrays` to load sparse array functionality") + @deprecate_binding(AbstractSparseVector, root_module(:SparseArrays).AbstractSparseVector, true, + ", run `using SparseArrays` to load sparse array functionality") + @deprecate_binding(SparseMatrixCSC, root_module(:SparseArrays).SparseMatrixCSC, true, + ", run `using SparseArrays` to load sparse array functionality") + @deprecate_binding(SparseVector, root_module(:SparseArrays).SparseVector, true, + ", run `using SparseArrays` to load sparse array functionality") end empty!(LOAD_PATH) diff --git a/base/task.jl b/base/task.jl index 26569252e7a87..5c7ca4c7ba919 100644 --- a/base/task.jl +++ b/base/task.jl @@ -204,9 +204,6 @@ function task_done_hook(t::Task) t.backtrace = catch_backtrace() end - q = t.consumers - t.consumers = nothing - if isa(t.donenotify, Condition) && !isempty(t.donenotify.waitq) handled = true notify(t.donenotify, result, true, err) @@ -219,21 +216,6 @@ function task_done_hook(t::Task) handled = true end - #### un-optimized version - #isa(q,Condition) && notify(q, result, error=err) - if isa(q,Task) - handled = true - nexttask = q - nexttask.state = :runnable - if err - nexttask.exception = result - end - yieldto(nexttask, result) # this terminates the task - elseif isa(q,Condition) && !isempty(q.waitq) - handled = true - notify(q, result, error=err) - end - if err && !handled if isa(result,InterruptException) && isdefined(Base,:active_repl_backend) && active_repl_backend.backend_task.state == :runnable && isempty(Workqueue) && diff --git a/base/threadcall.jl b/base/threadcall.jl index 151e1153ee406..357b9c881477e 100644 --- a/base/threadcall.jl +++ b/base/threadcall.jl @@ -83,7 +83,7 @@ function do_threadcall(wrapper::Function, rettype::Type, argtypes::Vector, argva # wait for a worker thread to be available acquire(threadcall_restrictor) - idx = findfirst(equalto(nothing), thread_notifiers) + idx = findfirst(equalto(nothing), thread_notifiers)::Int thread_notifiers[idx] = Condition() # queue up the work to be done diff --git a/base/traits.jl b/base/traits.jl index 7bd470a1bdea8..3c6a8019483b7 100644 --- a/base/traits.jl +++ b/base/traits.jl @@ -2,29 +2,29 @@ ## numeric/object traits # trait for objects that have an ordering -abstract type TypeOrder end -struct HasOrder <: TypeOrder end -struct Unordered <: TypeOrder end +abstract type OrderStyle end +struct Ordered <: OrderStyle end +struct Unordered <: OrderStyle end -TypeOrder(instance) = TypeOrder(typeof(instance)) -TypeOrder(::Type{<:Real}) = HasOrder() -TypeOrder(::Type{<:Any}) = Unordered() +OrderStyle(instance) = OrderStyle(typeof(instance)) +OrderStyle(::Type{<:Real}) = Ordered() +OrderStyle(::Type{<:Any}) = Unordered() # trait for objects that support arithmetic -abstract type TypeArithmetic end -struct ArithmeticRounds <: TypeArithmetic end # least significant bits can be lost -struct ArithmeticOverflows <: TypeArithmetic end # most significant bits can be lost -struct ArithmeticUnknown <: TypeArithmetic end +abstract type ArithmeticStyle end +struct ArithmeticRounds <: ArithmeticStyle end # least significant bits can be lost +struct ArithmeticWraps <: ArithmeticStyle end # most significant bits can be lost +struct ArithmeticUnknown <: ArithmeticStyle end -TypeArithmetic(instance) = TypeArithmetic(typeof(instance)) -TypeArithmetic(::Type{<:AbstractFloat}) = ArithmeticRounds() -TypeArithmetic(::Type{<:Integer}) = ArithmeticOverflows() -TypeArithmetic(::Type{<:Any}) = ArithmeticUnknown() +ArithmeticStyle(instance) = ArithmeticStyle(typeof(instance)) +ArithmeticStyle(::Type{<:AbstractFloat}) = ArithmeticRounds() +ArithmeticStyle(::Type{<:Integer}) = ArithmeticWraps() +ArithmeticStyle(::Type{<:Any}) = ArithmeticUnknown() # trait for objects that support ranges with regular step """ - TypeRangeStep(instance) - TypeRangeStep(T::Type) + RangeStepStyle(instance) + RangeStepStyle(T::Type) Indicate whether an instance or a type supports constructing a range with a perfectly regular step or not. A regular step means that @@ -37,7 +37,7 @@ all(diff(r) .== step(r)) When a type `T` always leads to ranges with regular steps, it should define the following method: ```julia -Base.TypeRangeStep(::Type{<:AbstractRange{<:T}}) = Base.RangeStepRegular() +Base.RangeStepStyle(::Type{<:AbstractRange{<:T}}) = Base.RangeStepRegular() ``` This will allow [`hash`](@ref) to use an O(1) algorithm for `AbstractRange{T}` objects instead of the default O(N) algorithm (with N the length of the range). @@ -46,14 +46,14 @@ In some cases, whether the step will be regular depends not only on the element type `T`, but also on the type of the step `S`. In that case, more specific methods should be defined: ```julia -Base.TypeRangeStep(::Type{<:OrdinalRange{<:T, <:S}}) = Base.RangeStepRegular() +Base.RangeStepStyle(::Type{<:OrdinalRange{<:T, <:S}}) = Base.RangeStepRegular() ``` By default, all range types are assumed to be `RangeStepIrregular`, except ranges with an element type which is a subtype of `Integer`. """ -abstract type TypeRangeStep end -struct RangeStepRegular <: TypeRangeStep end # range with regular step -struct RangeStepIrregular <: TypeRangeStep end # range with rounding error +abstract type RangeStepStyle end +struct RangeStepRegular <: RangeStepStyle end # range with regular step +struct RangeStepIrregular <: RangeStepStyle end # range with rounding error -TypeRangeStep(instance) = TypeRangeStep(typeof(instance)) +RangeStepStyle(instance) = RangeStepStyle(typeof(instance)) diff --git a/base/util.jl b/base/util.jl index a9ee3754f751d..e2a32a511795a 100644 --- a/base/util.jl +++ b/base/util.jl @@ -320,13 +320,26 @@ end function with_output_color(f::Function, color::Union{Int, Symbol}, io::IO, args...; bold::Bool = false) buf = IOBuffer() iscolor = get(io, :color, false) - iscolor && bold && print(buf, text_colors[:bold]) - iscolor && print(buf, get(text_colors, color, color_normal)) try f(IOContext(buf, io), args...) finally - iscolor && color != :nothing && print(buf, get(disable_text_style, color, text_colors[:default])) - iscolor && (bold || color == :bold) && print(buf, disable_text_style[:bold]) - print(io, String(take!(buf))) + str = String(take!(buf)) + if !iscolor + print(io, str) + else + bold && color == :bold && (color = :nothing) + enable_ansi = get(text_colors, color, text_colors[:default]) * + (bold ? text_colors[:bold] : "") + disable_ansi = (bold ? disable_text_style[:bold] : "") * + get(disable_text_style, color, text_colors[:default]) + first = true + for line in split(str, '\n') + first || print(buf, '\n') + first = false + isempty(line) && continue + print(buf, enable_ansi, line, disable_ansi) + end + print(io, String(take!(buf))) + end end end @@ -410,7 +423,7 @@ function getpass(prompt::AbstractString) ccall(:_getch, UInt8, ()) # ignore function/arrow keys elseif c == UInt8('\b') && plen > 0 plen -= 1 # delete last character on backspace - elseif !Unicode.iscntrl(Char(c)) && plen < 128 + elseif !iscntrl(Char(c)) && plen < 128 p[plen += 1] = c end end diff --git a/contrib/julia-config.jl b/contrib/julia-config.jl index 77e288962ef64..1ccdd3b2fa720 100755 --- a/contrib/julia-config.jl +++ b/contrib/julia-config.jl @@ -1,6 +1,8 @@ #!/usr/bin/env julia # This file is a part of Julia. License is MIT: https://julialang.org/license +import Libdl + const options = [ "--cflags", "--ldflags", diff --git a/contrib/mac/app/Makefile b/contrib/mac/app/Makefile index 5d860e105db68..3a03d129d4a22 100644 --- a/contrib/mac/app/Makefile +++ b/contrib/mac/app/Makefile @@ -23,7 +23,7 @@ APP_COPYRIGHT:=© 2016 The Julia Project all: clean $(DMG_NAME) $(DMG_NAME): dmg/$(APP_NAME) dmg/.VolumeIcon.icns dmg/Applications - hdiutil create $@ -size 500m -ov -volname "$(VOL_NAME)" -imagekey zlib-level=9 -srcfolder dmg + hdiutil create $@ -size 1t -ov -volname "$(VOL_NAME)" -imagekey zlib-level=9 -srcfolder dmg dmg/.VolumeIcon.icns: julia.icns -mkdir -p dmg diff --git a/doc/.gitignore b/doc/.gitignore index a1479f3343723..4e9962dc08c2b 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,4 +1,6 @@ deps/ _build/ UnicodeData.txt +src/stdlib/ +src/NEWS.md diff --git a/doc/Makefile b/doc/Makefile index 743804d8b6968..86ab60191cb47 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -32,17 +32,17 @@ cleanall: clean html: deps @echo "Building HTML documentation." ifneq ($(OS),WINNT) - $(JULIA_EXECUTABLE) $(call cygpath_w,$(SRCDIR)/make.jl) + $(JULIA_EXECUTABLE) --color=yes $(call cygpath_w,$(SRCDIR)/make.jl) else # work around issue #11727, windows output redirection breaking on buildbot - $(JULIA_EXECUTABLE) $(call cygpath_w,$(SRCDIR)/make.jl) > docbuild.log 2>&1 + $(JULIA_EXECUTABLE) --color=yes $(call cygpath_w,$(SRCDIR)/make.jl) > docbuild.log 2>&1 @cat docbuild.log endif @echo "Build finished. The HTML pages are in _build/html." pdf: deps @echo "Building PDF documentation." - $(JULIA_EXECUTABLE) $(call cygpath_w,$(SRCDIR)/make.jl) -- pdf + $(JULIA_EXECUTABLE) --color=yes $(call cygpath_w,$(SRCDIR)/make.jl) -- pdf @echo "Build finished." linkcheck: deps @@ -63,5 +63,5 @@ check: deps # The deploy target should only be called in Travis builds deploy: deps @echo "Deploying HTML documentation." - $(JULIA_EXECUTABLE) $(call cygpath_w,$(SRCDIR)/make.jl) -- deploy + $(JULIA_EXECUTABLE) --color=yes $(call cygpath_w,$(SRCDIR)/make.jl) -- deploy @echo "Build & deploy of docs finished." diff --git a/doc/make.jl b/doc/make.jl index e67f63e768003..5c6c812ea2200 100644 --- a/doc/make.jl +++ b/doc/make.jl @@ -19,39 +19,35 @@ end symlink_q(tgt, link) = isfile(link) || symlink(tgt, link) cp_q(src, dest) = isfile(dest) || cp(src, dest) -# make links for stdlib package docs -if Sys.iswindows() - cp_q("../stdlib/DelimitedFiles/docs/src/index.md", "src/stdlib/delimitedfiles.md") - cp_q("../stdlib/Test/docs/src/index.md", "src/stdlib/test.md") - cp_q("../stdlib/Mmap/docs/src/index.md", "src/stdlib/mmap.md") - cp_q("../stdlib/SharedArrays/docs/src/index.md", "src/stdlib/sharedarrays.md") - cp_q("../stdlib/Profile/docs/src/index.md", "src/stdlib/profile.md") - cp_q("../stdlib/Base64/docs/src/index.md", "src/stdlib/base64.md") - cp_q("../stdlib/FileWatching/docs/src/index.md", "src/stdlib/filewatching.md") - cp_q("../stdlib/CRC32c/docs/src/index.md", "src/stdlib/crc32c.md") - cp_q("../stdlib/Dates/docs/src/index.md", "src/stdlib/dates.md") - cp_q("../stdlib/IterativeEigensolvers/docs/src/index.md", "src/stdlib/iterativeeigensolvers.md") - cp_q("../stdlib/Unicode/docs/src/index.md", "src/stdlib/unicode.md") - cp_q("../stdlib/Distributed/docs/src/index.md", "src/stdlib/distributed.md") - cp_q("../stdlib/Printf/docs/src/index.md", "src/stdlib/printf.md") -else - symlink_q("../../../stdlib/DelimitedFiles/docs/src/index.md", "src/stdlib/delimitedfiles.md") - symlink_q("../../../stdlib/Test/docs/src/index.md", "src/stdlib/test.md") - symlink_q("../../../stdlib/Mmap/docs/src/index.md", "src/stdlib/mmap.md") - symlink_q("../../../stdlib/SharedArrays/docs/src/index.md", "src/stdlib/sharedarrays.md") - symlink_q("../../../stdlib/Profile/docs/src/index.md", "src/stdlib/profile.md") - symlink_q("../../../stdlib/Base64/docs/src/index.md", "src/stdlib/base64.md") - symlink_q("../../../stdlib/FileWatching/docs/src/index.md", "src/stdlib/filewatching.md") - symlink_q("../../../stdlib/CRC32c/docs/src/index.md", "src/stdlib/crc32c.md") - symlink_q("../../../stdlib/Dates/docs/src/index.md", "src/stdlib/dates.md") - symlink_q("../../../stdlib/IterativeEigensolvers/docs/src/index.md", "src/stdlib/iterativeeigensolvers.md") - symlink_q("../../../stdlib/Unicode/docs/src/index.md", "src/stdlib/unicode.md") - symlink_q("../../../stdlib/Distributed/docs/src/index.md", "src/stdlib/distributed.md") - symlink_q("../../../stdlib/Printf/docs/src/index.md", "src/stdlib/printf.md") +# make links for stdlib package docs, this is needed until #522 in Documenter.jl is finished +const STDLIB_DOCS = [] +const STDLIB_DIR = joinpath(@__DIR__, "..", "stdlib") +for dir in readdir(STDLIB_DIR) + sourcefile = joinpath(STDLIB_DIR, dir, "docs", "src", "index.md") + if isfile(sourcefile) + cd(joinpath(@__DIR__, "src")) do + isdir("stdlib") || mkdir("stdlib") + targetfile = joinpath("stdlib", dir * ".md") + push!(STDLIB_DOCS, (stdlib = Symbol(dir), targetfile = targetfile)) + if Sys.iswindows() + cp_q(sourcefile, targetfile) + else + symlink_q(sourcefile, targetfile) + end + end + end end +# Generate a suitable markdown file from NEWS.md and put it in src +str = read(joinpath(@__DIR__, "..", "NEWS.md"), String) +splitted = split(str, "") +@assert length(splitted) == 2 +replaced_links = replace(splitted[1], r"\[\#([0-9]*?)\]" => s"[#\g<1>](https://github.com/JuliaLang/julia/issues/\g<1>)") +write(joinpath(@__DIR__, "src", "NEWS.md"), replaced_links) + const PAGES = [ "Home" => "index.md", + hide("NEWS.md"), "Manual" => [ "manual/introduction.md", "manual/getting-started.md", @@ -93,42 +89,30 @@ const PAGES = [ "manual/noteworthy-differences.md", "manual/unicode-input.md", ], - "Standard Library" => [ - "stdlib/base.md", - "stdlib/collections.md", - "stdlib/math.md", - "stdlib/numbers.md", - "stdlib/strings.md", - "stdlib/arrays.md", - "stdlib/parallel.md", - "stdlib/distributed.md", - "stdlib/multi-threading.md", - "stdlib/linalg.md", - "stdlib/constants.md", - "stdlib/file.md", - "stdlib/delimitedfiles.md", - "stdlib/io-network.md", - "stdlib/punctuation.md", - "stdlib/sort.md", - "stdlib/pkg.md", - "stdlib/dates.md", - "stdlib/iterators.md", - "stdlib/test.md", - "stdlib/c.md", - "stdlib/libc.md", - "stdlib/libdl.md", - "stdlib/profile.md", - "stdlib/stacktraces.md", - "stdlib/simd-types.md", - "stdlib/base64.md", - "stdlib/mmap.md", - "stdlib/sharedarrays.md", - "stdlib/filewatching.md", - "stdlib/crc32c.md", - "stdlib/iterativeeigensolvers.md", - "stdlib/unicode.md", - "stdlib/printf.md", + "Base" => [ + "base/base.md", + "base/collections.md", + "base/math.md", + "base/numbers.md", + "base/strings.md", + "base/arrays.md", + "base/parallel.md", + "base/multi-threading.md", + "base/linalg.md", + "base/constants.md", + "base/file.md", + "base/io-network.md", + "base/punctuation.md", + "base/sort.md", + "base/pkg.md", + "base/iterators.md", + "base/c.md", + "base/libc.md", + "base/stacktraces.md", + "base/simd-types.md", ], + "Standard Library" => + [stdlib.targetfile for stdlib in STDLIB_DOCS], "Developer Documentation" => [ "devdocs/reflection.md", "Documentation of Julia's Internals" => [ @@ -162,13 +146,13 @@ const PAGES = [ ], ] -using DelimitedFiles, Test, Mmap, SharedArrays, Profile, Base64, FileWatching, CRC32c, - Dates, IterativeEigensolvers, Unicode, Distributed, Printf +for stdlib in STDLIB_DOCS + @eval using $(stdlib.stdlib) +end makedocs( build = joinpath(pwd(), "_build/html/en"), - modules = [Base, Core, BuildSysImg, DelimitedFiles, Test, Mmap, SharedArrays, Profile, - Base64, FileWatching, Dates, IterativeEigensolvers, Unicode, Distributed, Printf], + modules = [Base, Core, BuildSysImg, [Base.root_module(stdlib.stdlib) for stdlib in STDLIB_DOCS]...], clean = false, doctest = "doctest" in ARGS, linkcheck = "linkcheck" in ARGS, diff --git a/doc/src/stdlib/arrays.md b/doc/src/base/arrays.md similarity index 75% rename from doc/src/stdlib/arrays.md rename to doc/src/base/arrays.md index c3f1efca5d5ea..894e36c735cd1 100644 --- a/doc/src/stdlib/arrays.md +++ b/doc/src/base/arrays.md @@ -34,8 +34,6 @@ Base.similar(::AbstractArray) Base.similar(::Any, ::Tuple) Base.linspace Base.logspace -Base.Random.randsubseq -Base.Random.randsubseq! ``` ## Basic functions @@ -126,7 +124,6 @@ Base.circshift! Base.circcopy! Base.find(::Any) Base.find(::Function, ::Any) -Base.findn Base.findnz Base.findfirst(::Any) Base.findfirst(::Function, ::Any) @@ -164,16 +161,10 @@ Base.mapslices ## Combinatorics ```@docs -Base.Random.randperm -Base.Random.randperm! Base.invperm Base.isperm Base.permute!(::Any, ::AbstractVector) Base.invpermute! -Base.Random.randcycle -Base.Random.randcycle! -Base.Random.shuffle -Base.Random.shuffle! Base.reverse Base.reverseind Base.reverse! @@ -188,30 +179,3 @@ and can be converted to/from the latter via `Array(bitarray)` and `BitArray(arra ```@docs Base.flipbits! ``` - -## [Sparse Vectors and Matrices](@id stdlib-sparse-arrays) - -Sparse vectors and matrices largely support the same set of operations as their dense counterparts. -The following functions are specific to sparse arrays. - -```@docs -Base.SparseArrays.SparseVector -Base.SparseArrays.SparseMatrixCSC -Base.SparseArrays.sparse -Base.SparseArrays.sparsevec -Base.SparseArrays.issparse -Base.SparseArrays.nnz -Base.SparseArrays.spzeros -Base.SparseArrays.spdiagm -Base.SparseArrays.sprand -Base.SparseArrays.sprandn -Base.SparseArrays.nonzeros -Base.SparseArrays.rowvals -Base.SparseArrays.nzrange -Base.SparseArrays.dropzeros!(::SparseMatrixCSC, ::Bool) -Base.SparseArrays.dropzeros(::SparseMatrixCSC, ::Bool) -Base.SparseArrays.dropzeros!(::SparseVector, ::Bool) -Base.SparseArrays.dropzeros(::SparseVector, ::Bool) -Base.SparseArrays.permute -Base.permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) -``` diff --git a/doc/src/stdlib/base.md b/doc/src/base/base.md similarity index 97% rename from doc/src/stdlib/base.md rename to doc/src/base/base.md index d0ea63d72b38f..6d60c33900e94 100644 --- a/doc/src/stdlib/base.md +++ b/doc/src/base/base.md @@ -2,7 +2,7 @@ ## Introduction -The Julia standard library contains a range of functions and macros appropriate for performing +Julia Base contains a range of functions and macros appropriate for performing scientific and numerical computing, but is also as broad as those of many general purpose programming languages. Additional functionality is available from a growing collection of available packages. Functions are grouped by topic below. @@ -92,13 +92,11 @@ Base.Iterators Base.LAPACK Base.LibGit2 Base.Libc -Base.Libdl Base.LinAlg Base.Markdown Base.Meta Base.Pkg Base.Serializer -Base.SparseArrays Base.StackTraces Base.Sys Base.Threads diff --git a/doc/src/stdlib/c.md b/doc/src/base/c.md similarity index 100% rename from doc/src/stdlib/c.md rename to doc/src/base/c.md diff --git a/doc/src/stdlib/collections.md b/doc/src/base/collections.md similarity index 99% rename from doc/src/stdlib/collections.md rename to doc/src/base/collections.md index 6c9c33d3a5236..1f6d9d16b6ec5 100644 --- a/doc/src/stdlib/collections.md +++ b/doc/src/base/collections.md @@ -29,8 +29,8 @@ iterable type. Base.start Base.done Base.next -Base.iteratorsize -Base.iteratoreltype +Base.IteratorSize +Base.IteratorEltype ``` Fully implemented by: diff --git a/doc/src/base/constants.md b/doc/src/base/constants.md new file mode 100644 index 0000000000000..0f4c321d69067 --- /dev/null +++ b/doc/src/base/constants.md @@ -0,0 +1,27 @@ +# [Constants](@id lib-constants) + +```@docs +Core.nothing +Base.PROGRAM_FILE +Base.ARGS +Base.C_NULL +Base.VERSION +Base.LOAD_PATH +Base.Sys.BINDIR +Base.Sys.CPU_CORES +Base.Sys.WORD_SIZE +Base.Sys.KERNEL +Base.Sys.ARCH +Base.Sys.MACHINE +``` + +See also: + + * [`STDIN`](@ref) + * [`STDOUT`](@ref) + * [`STDERR`](@ref) + * [`ENV`](@ref) + * [`ENDIAN_BOM`](@ref) + * `Libc.MS_ASYNC` + * `Libc.MS_INVALIDATE` + * `Libc.MS_SYNC` diff --git a/doc/src/stdlib/file.md b/doc/src/base/file.md similarity index 100% rename from doc/src/stdlib/file.md rename to doc/src/base/file.md diff --git a/doc/src/stdlib/index.md b/doc/src/base/index.md similarity index 95% rename from doc/src/stdlib/index.md rename to doc/src/base/index.md index 5356aaf26ffa0..7e19cb5213295 100644 --- a/doc/src/stdlib/index.md +++ b/doc/src/base/index.md @@ -31,5 +31,7 @@ * [Memory-mapped I/O](@ref) * [Base64](@ref) * [File Events](@ref lib-filewatching) + * [Sparse Arrays](@ref) * [Iterative Eigensolvers](@ref lib-itereigen) * [Printf](@ref) + * [Random Numbers](@ref) diff --git a/doc/src/stdlib/io-network.md b/doc/src/base/io-network.md similarity index 100% rename from doc/src/stdlib/io-network.md rename to doc/src/base/io-network.md diff --git a/doc/src/stdlib/iterators.md b/doc/src/base/iterators.md similarity index 100% rename from doc/src/stdlib/iterators.md rename to doc/src/base/iterators.md diff --git a/doc/src/stdlib/libc.md b/doc/src/base/libc.md similarity index 100% rename from doc/src/stdlib/libc.md rename to doc/src/base/libc.md diff --git a/doc/src/stdlib/linalg.md b/doc/src/base/linalg.md similarity index 99% rename from doc/src/stdlib/linalg.md rename to doc/src/base/linalg.md index a1b3ae0e292d5..e6d500201aba2 100644 --- a/doc/src/stdlib/linalg.md +++ b/doc/src/base/linalg.md @@ -91,7 +91,6 @@ Base.LinAlg.pinv Base.LinAlg.nullspace Base.repmat Base.kron -Base.SparseArrays.blkdiag Base.LinAlg.linreg Base.LinAlg.exp(::StridedMatrix{<:Base.LinAlg.BlasFloat}) Base.LinAlg.log(::StridedMatrix) diff --git a/doc/src/stdlib/math.md b/doc/src/base/math.md similarity index 100% rename from doc/src/stdlib/math.md rename to doc/src/base/math.md diff --git a/doc/src/stdlib/multi-threading.md b/doc/src/base/multi-threading.md similarity index 100% rename from doc/src/stdlib/multi-threading.md rename to doc/src/base/multi-threading.md diff --git a/doc/src/stdlib/numbers.md b/doc/src/base/numbers.md similarity index 56% rename from doc/src/stdlib/numbers.md rename to doc/src/base/numbers.md index 9ed0821042869..4be2570374488 100644 --- a/doc/src/stdlib/numbers.md +++ b/doc/src/base/numbers.md @@ -130,38 +130,3 @@ BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) Base.MPFR.BigFloat(x::String) ``` - -## Random Numbers - -Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) -via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types -can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple -streams of random numbers. Besides `MersenneTwister`, Julia also provides the `RandomDevice` RNG -type, which is a wrapper over the OS provided entropy. - -Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Morever, some of them accept optionally -dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random -values. - -A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the following types: -[`Float16`](@ref), [`Float32`](@ref), [`Float64`](@ref), [`BigFloat`](@ref), [`Bool`](@ref), -[`Int8`](@ref), [`UInt8`](@ref), [`Int16`](@ref), [`UInt16`](@ref), [`Int32`](@ref), -[`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), -[`BigInt`](@ref) (or complex numbers of those types). -Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents -unbounded integers, the interval must be specified (e.g. `rand(big(1:6))`). - -```@docs -Base.Random.srand -Base.Random.MersenneTwister -Base.Random.RandomDevice -Base.Random.rand -Base.Random.rand! -Base.Random.bitrand -Base.Random.randn -Base.Random.randn! -Base.Random.randexp -Base.Random.randexp! -Base.Random.randjump -``` diff --git a/doc/src/stdlib/parallel.md b/doc/src/base/parallel.md similarity index 100% rename from doc/src/stdlib/parallel.md rename to doc/src/base/parallel.md diff --git a/doc/src/stdlib/pkg.md b/doc/src/base/pkg.md similarity index 100% rename from doc/src/stdlib/pkg.md rename to doc/src/base/pkg.md diff --git a/doc/src/stdlib/punctuation.md b/doc/src/base/punctuation.md similarity index 100% rename from doc/src/stdlib/punctuation.md rename to doc/src/base/punctuation.md diff --git a/doc/src/stdlib/simd-types.md b/doc/src/base/simd-types.md similarity index 100% rename from doc/src/stdlib/simd-types.md rename to doc/src/base/simd-types.md diff --git a/doc/src/stdlib/sort.md b/doc/src/base/sort.md similarity index 100% rename from doc/src/stdlib/sort.md rename to doc/src/base/sort.md diff --git a/doc/src/stdlib/stacktraces.md b/doc/src/base/stacktraces.md similarity index 100% rename from doc/src/stdlib/stacktraces.md rename to doc/src/base/stacktraces.md diff --git a/doc/src/stdlib/strings.md b/doc/src/base/strings.md similarity index 86% rename from doc/src/stdlib/strings.md rename to doc/src/base/strings.md index 1175c11e3268d..011cf245dfb5a 100644 --- a/doc/src/stdlib/strings.md +++ b/doc/src/base/strings.md @@ -48,13 +48,29 @@ Base.startswith Base.endswith Base.first(::AbstractString, ::Integer) Base.last(::AbstractString, ::Integer) +Base.uppercase +Base.lowercase +Base.titlecase +Base.ucfirst +Base.lcfirst Base.join Base.chop Base.chomp Base.thisind Base.nextind Base.prevind -Base.Random.randstring +Base.textwidth +Base.isalpha +Base.isascii +Base.iscntrl +Base.isdigit +Base.islower +Base.isnumeric +Base.isprint +Base.ispunct +Base.isspace +Base.isupper +Base.isxdigit Core.Symbol Base.escape_string Base.unescape_string diff --git a/doc/src/index.md b/doc/src/index.md index ce23e41a10256..7e2882ee8a624 100644 --- a/doc/src/index.md +++ b/doc/src/index.md @@ -1,4 +1,13 @@ -# Julia Documentation +# Julia 0.7 Documentation + +Welcome to the documentation for Julia 0.7. + +Please read the [release notes](NEWS.md) to see what has changed since the last release. + +* [Manual](#Manual-1) +* [Base](#Base-1) +* [Standard Library](#Standard-Library-1) +* [Developer Documentation](#Developer-Documentation-1) ## Manual @@ -42,7 +51,7 @@ * [Noteworthy Differences from other Languages](@ref) * [Unicode Input](@ref) -## Standard Library +## Base * [Essentials](@ref) * [Collections and Data Structures](@ref) @@ -57,26 +66,34 @@ * [Linear Algebra](@ref) * [Constants](@ref lib-constants) * [Filesystem](@ref) - * [Delimited Files](@ref) * [I/O and Network](@ref) * [Punctuation](@ref) * [Sorting and Related Functions](@ref) * [Package Manager Functions](@ref) - * [Dates and Time](@ref stdlib-dates) * [Iteration utilities](@ref) - * [Unit Testing](@ref) * [C Interface](@ref) * [C Standard Library](@ref) * [Dynamic Linker](@ref) * [StackTraces](@ref) * [SIMD Support](@ref) - * [Profiling](@ref lib-profiling) - * [Memory-mapped I/O](@ref) + +## Standard Library + * [Base64](@ref) + * [CRC32c](@ref) + * [Dates and Time](@ref stdlib-dates) + * [Delimited Files](@ref) + * [Distributed Computing](@ref) * [File Events](@ref lib-filewatching) * [Iterative Eigensolvers](@ref lib-itereigen) - * [Unicode](@ref) + * [Memory-mapped I/O](@ref) * [Printf](@ref) + * [Profiling](@ref lib-profiling) + * [Random Numbers](@ref) + * [Shared Arrays](@ref) + * [Sparse Arrays](@ref) + * [Unicode](@ref) + * [Unit Testing](@ref) ## Developer Documentation diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index 9b4099cea7346..b90ebe6e2f315 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -694,15 +694,18 @@ functions may be unexpectedly slow. Concrete types should also typically provide method, which is used to allocate a similar array for [`copy`](@ref) and other out-of-place operations. No matter how an `AbstractArray{T,N}` is represented internally, `T` is the type of object returned by *integer* indexing (`A[1, ..., 1]`, when `A` is not empty) and `N` should be -the length of the tuple returned by [`size`](@ref). +the length of the tuple returned by [`size`](@ref). For more details on defining custom +`AbstractArray` implementations, see the [array interface guide in the interfaces chapter](@ref man-interface-array). `DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays that are laid out at regular offsets in memory, and which can therefore be passed to external C and Fortran -functions expecting this memory layout. Subtypes should provide a method [`stride(A,k)`](@ref) -that returns the "stride" of dimension `k`: increasing the index of dimension `k` by `1` should +functions expecting this memory layout. Subtypes should provide a [`strides(A)`](@ref) method +that returns a tuple of "strides" for each dimension; a provided [`stride(A,k)`](@ref) method accesses +the `k`th element within this tuple. Increasing the index of dimension `k` by `1` should increase the index `i` of [`getindex(A,i)`](@ref) by [`stride(A,k)`](@ref). If a pointer conversion method [`Base.unsafe_convert(Ptr{T}, A)`](@ref) is provided, the memory layout should correspond -in the same way to these strides. +in the same way to these strides. More concrete examples can be found within the [interface guide +for strided arrays](@ref man-interface-strided-arrays). The [`Array`](@ref) type is a specific instance of `DenseArray` where elements are stored in column-major order (see additional notes in [Performance Tips](@ref man-performance-tips)). [`Vector`](@ref) and [`Matrix`](@ref) are aliases for @@ -762,195 +765,3 @@ julia> r -1.58553 -0.921517 0.0 0.866567 ``` - -## Sparse Vectors and Matrices - -Julia has built-in support for sparse vectors and -[sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix). Sparse arrays are arrays -that contain enough zeros that storing them in a special data structure leads to savings -in space and execution time, compared to dense arrays. - -### [Compressed Sparse Column (CSC) Sparse Matrix Storage](@id man-csc) - -In Julia, sparse matrices are stored in the [Compressed Sparse Column (CSC) format](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29). -Julia sparse matrices have the type [`SparseMatrixCSC{Tv,Ti}`](@ref), where `Tv` is the -type of the stored values, and `Ti` is the integer type for storing column pointers and -row indices. The internal representation of `SparseMatrixCSC` is as follows: - -```julia -struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti} - m::Int # Number of rows - n::Int # Number of columns - colptr::Vector{Ti} # Column i is in colptr[i]:(colptr[i+1]-1) - rowval::Vector{Ti} # Row indices of stored values - nzval::Vector{Tv} # Stored values, typically nonzeros -end -``` - -The compressed sparse column storage makes it easy and quick to access the elements in the column -of a sparse matrix, whereas accessing the sparse matrix by rows is considerably slower. Operations -such as insertion of previously unstored entries one at a time in the CSC structure tend to be slow. This is -because all elements of the sparse matrix that are beyond the point of insertion have to be moved -one place over. - -All operations on sparse matrices are carefully implemented to exploit the CSC data structure -for performance, and to avoid expensive operations. - -If you have data in CSC format from a different application or library, and wish to import it -in Julia, make sure that you use 1-based indexing. The row indices in every column need to be -sorted. If your `SparseMatrixCSC` object contains unsorted row indices, one quick way to sort -them is by doing a double transpose. - -In some applications, it is convenient to store explicit zero values in a `SparseMatrixCSC`. These -*are* accepted by functions in `Base` (but there is no guarantee that they will be preserved in -mutating operations). Such explicitly stored zeros are treated as structural nonzeros by many -routines. The [`nnz`](@ref) function returns the number of elements explicitly stored in the -sparse data structure, including structural nonzeros. In order to count the exact number of -numerical nonzeros, use [`count(!iszero, x)`](@ref), which inspects every stored element of a sparse -matrix. [`dropzeros`](@ref), and the in-place [`dropzeros!`](@ref), can be used to -remove stored zeros from the sparse matrix. - -```jldoctest -julia> A = sparse([1, 2, 3], [1, 2, 3], [0, 2, 0]) -3×3 SparseMatrixCSC{Int64,Int64} with 3 stored entries: - [1, 1] = 0 - [2, 2] = 2 - [3, 3] = 0 - -julia> dropzeros(A) -3×3 SparseMatrixCSC{Int64,Int64} with 1 stored entry: - [2, 2] = 2 -``` - -### Sparse Vector Storage - -Sparse vectors are stored in a close analog to compressed sparse column format for sparse -matrices. In Julia, sparse vectors have the type [`SparseVector{Tv,Ti}`](@ref) where `Tv` -is the type of the stored values and `Ti` the integer type for the indices. The internal -representation is as follows: - -```julia -struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti} - n::Int # Length of the sparse vector - nzind::Vector{Ti} # Indices of stored values - nzval::Vector{Tv} # Stored values, typically nonzeros -end -``` - -As for [`SparseMatrixCSC`](@ref), the `SparseVector` type can also contain explicitly -stored zeros. (See [Sparse Matrix Storage](@ref man-csc).). - -### Sparse Vector and Matrix Constructors - -The simplest way to create a sparse array is to use a function equivalent to the [`zeros`](@ref) -function that Julia provides for working with dense arrays. To produce a -sparse array instead, you can use the same name with an `sp` prefix: - -```jldoctest -julia> spzeros(3) -3-element SparseVector{Float64,Int64} with 0 stored entries -``` - -The [`sparse`](@ref) function is often a handy way to construct sparse arrays. For -example, to construct a sparse matrix we can input a vector `I` of row indices, a vector -`J` of column indices, and a vector `V` of stored values (this is also known as the -[COO (coordinate) format](https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29)). -`sparse(I,J,V)` then constructs a sparse matrix such that `S[I[k], J[k]] = V[k]`. The -equivalent sparse vector constructor is [`sparsevec`](@ref), which takes the (row) index -vector `I` and the vector `V` with the stored values and constructs a sparse vector `R` -such that `R[I[k]] = V[k]`. - -```jldoctest sparse_function -julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3]; - -julia> S = sparse(I,J,V) -5×18 SparseMatrixCSC{Int64,Int64} with 4 stored entries: - [1 , 4] = 1 - [4 , 7] = 2 - [5 , 9] = 3 - [3 , 18] = -5 - -julia> R = sparsevec(I,V) -5-element SparseVector{Int64,Int64} with 4 stored entries: - [1] = 1 - [3] = -5 - [4] = 2 - [5] = 3 -``` - -The inverse of the [`sparse`](@ref) and [`sparsevec`](@ref) functions is -[`findnz`](@ref), which retrieves the inputs used to create the sparse array. -There is also a [`findn`](@ref) function which only returns the index vectors. - -```jldoctest sparse_function -julia> findnz(S) -([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5]) - -julia> findn(S) -([1, 4, 5, 3], [4, 7, 9, 18]) - -julia> findnz(R) -([1, 3, 4, 5], [1, -5, 2, 3]) - -julia> find(!iszero, R) -4-element Array{Int64,1}: - 1 - 3 - 4 - 5 -``` - -Another way to create a sparse array is to convert a dense array into a sparse array using -the [`sparse`](@ref) function: - -```jldoctest -julia> sparse(Matrix(1.0I, 5, 5)) -5×5 SparseMatrixCSC{Float64,Int64} with 5 stored entries: - [1, 1] = 1.0 - [2, 2] = 1.0 - [3, 3] = 1.0 - [4, 4] = 1.0 - [5, 5] = 1.0 - -julia> sparse([1.0, 0.0, 1.0]) -3-element SparseVector{Float64,Int64} with 2 stored entries: - [1] = 1.0 - [3] = 1.0 -``` - -You can go in the other direction using the [`Array`](@ref) constructor. The [`issparse`](@ref) -function can be used to query if a matrix is sparse. - -```jldoctest -julia> issparse(spzeros(5)) -true -``` - -### Sparse matrix operations - -Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, -assignment into, and concatenation of sparse matrices work in the same way as dense matrices. -Indexing operations, especially assignment, are expensive, when carried out one element at a time. -In many cases it may be better to convert the sparse matrix into `(I,J,V)` format using [`findnz`](@ref), -manipulate the values or the structure in the dense vectors `(I,J,V)`, and then reconstruct -the sparse matrix. - -### Correspondence of dense and sparse methods - -The following table gives a correspondence between built-in methods on sparse matrices and their -corresponding methods on dense matrix types. In general, methods that generate sparse matrices -differ from their dense counterparts in that the resulting matrix follows the same sparsity pattern -as a given sparse matrix `S`, or that the resulting sparse matrix has density `d`, i.e. each matrix -element has a probability `d` of being non-zero. - -Details can be found in the [Sparse Vectors and Matrices](@ref stdlib-sparse-arrays) -section of the standard library reference. - -| Sparse | Dense | Description | -|:-------------------------- |:---------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`spzeros(m,n)`](@ref) | [`zeros(m,n)`](@ref) | Creates a *m*-by-*n* matrix of zeros. ([`spzeros(m,n)`](@ref) is empty.) | -| [`sparse(I, n, n)`](@ref) | [`Matrix(I,n,n)`](@ref)| Creates a *n*-by-*n* identity matrix. | -| [`Array(S)`](@ref) | [`sparse(A)`](@ref) | Interconverts between dense and sparse formats. | -| [`sprand(m,n,d)`](@ref) | [`rand(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed uniformly on the half-open interval ``[0, 1)``. | -| [`sprandn(m,n,d)`](@ref) | [`randn(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution. | -| [`sprandn(m,n,d,X)`](@ref) | [`randn(m,n,X)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the *X* distribution. (Requires the `Distributions` package.) | diff --git a/doc/src/manual/control-flow.md b/doc/src/manual/control-flow.md index ccfe0ed66072f..18dd9828087cb 100644 --- a/doc/src/manual/control-flow.md +++ b/doc/src/manual/control-flow.md @@ -937,7 +937,7 @@ In addition to [`yieldto`](@ref), a few other basic functions are needed to use ### Tasks and events Most task switches occur as a result of waiting for events such as I/O requests, and are performed -by a scheduler included in the standard library. The scheduler maintains a queue of runnable tasks, +by a scheduler included in Julia Base. The scheduler maintains a queue of runnable tasks, and executes an event loop that restarts tasks based on external events such as message arrival. The basic function for waiting for an event is [`wait`](@ref). Several objects implement [`wait`](@ref); diff --git a/doc/src/manual/conversion-and-promotion.md b/doc/src/manual/conversion-and-promotion.md index 56fe28341b089..b824c97b6b015 100644 --- a/doc/src/manual/conversion-and-promotion.md +++ b/doc/src/manual/conversion-and-promotion.md @@ -119,14 +119,40 @@ its methods are restricted to cases that are considered "safe" or "unsurprising" It is also usually lossless; converting a value to a different type and back again should result in the exact same value. -Notice that some constructors don't implement the concept of "conversion". -For example, `Vector{Int}(5)` constructs a 5-element vector, which is not really a -"conversion" from an integer to a vector. +There are four general kinds of cases where constructors differ from `convert`: -Finally, `convert(T, x)` is expected to return the original `x` if `x` is already of type `T`. +#### Constructors for types unrelated to their arguments + +Some constructors don't implement the concept of "conversion". +For example, `Timer(2)` creates a 2-second timer, which is not really a +"conversion" from an integer to a timer. + +#### Mutable collections + +`convert(T, x)` is expected to return the original `x` if `x` is already of type `T`. In contrast, if `T` is a mutable collection type then `T(x)` should always make a new collection (copying elements from `x`). +#### Wrapper types + +For some types which "wrap" other values, the constructor may wrap its argument inside +a new object even if it is already of the requested type. +For example `Some(x)` wraps `x` to indicate that a value is present (in a context +where the result might be a `Some` or `nothing`). +However, `x` itself might be the object `Some(y)`, in which case the result is +`Some(Some(y))`, with two levels of wrapping. +`convert(Some, x)`, on the other hand, would just return `x` since it is already +a `Some`. + +#### Constructors that don't return instances of their own type + +In *very rare* cases it might make sense for the constructor `T(x)` to return +an object not of type `T`. +This could happen if a wrapper type is its own inverse (e.g. `Flip(Flip(x)) === x`), +or to support an old calling syntax for backwards compatibility when a library is +restructured. +But `convert(T, x)` should always return a value of type `T`. + ### Defining New Conversions When defining a new type, initially all ways of creating it should be defined as @@ -146,11 +172,11 @@ The type of the first argument of this method is a [singleton type](@ref man-sin when the first argument is the type value `MyType`. Notice the syntax used for the first argument: the argument name is omitted prior to the `::` symbol, and only the type is given. This is the syntax in Julia for a function argument whose type is specified but whose value -is never used in the function body. In this example, since the type is a singleton, there -would never be any reason to use its value within the body. +does not need to be referenced by name. In this example, since the type is a singleton, we +already know its value without referring to an argument name. All instances of some abstract types are by default considered "sufficiently similar" -that a universal `convert` definition is provided in the standard library. +that a universal `convert` definition is provided in Julia Base. For example, this definition states that it's valid to `convert` any `Number` type to any other by calling a 1-argument constructor: @@ -231,7 +257,7 @@ try again. That's all there is to it: nowhere else does one ever need to worry a to a common numeric type for arithmetic operations -- it just happens automatically. There are definitions of catch-all promotion methods for a number of other arithmetic and mathematical functions in [`promotion.jl`](https://github.com/JuliaLang/julia/blob/master/base/promotion.jl), but beyond -that, there are hardly any calls to `promote` required in the Julia standard library. The most +that, there are hardly any calls to `promote` required in Julia Base. The most common usages of `promote` occur in outer constructors methods, provided for convenience, to allow constructor calls with mixed types to delegate to an inner type with fields promoted to an appropriate common type. For example, recall that [`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl) @@ -270,7 +296,7 @@ promote_rule(::Type{Float64}, ::Type{Float32}) = Float64 one declares that when 64-bit and 32-bit floating-point values are promoted together, they should be promoted to 64-bit floating-point. The promotion type does not need to be one of the argument -types, however; the following promotion rules both occur in Julia's standard library: +types, however; the following promotion rules both occur in Julia Base: ```julia promote_rule(::Type{UInt8}, ::Type{Int8}) = Int diff --git a/doc/src/manual/interfaces.md b/doc/src/manual/interfaces.md index c61104fbd2e4b..22898dbf4fcda 100644 --- a/doc/src/manual/interfaces.md +++ b/doc/src/manual/interfaces.md @@ -13,20 +13,20 @@ to generically build upon those behaviors. | `next(iter, state)` |   | Returns the current item and the next state | | `done(iter, state)` |   | Tests if there are any items remaining | | **Important optional methods** | **Default definition** | **Brief description** | -| `iteratorsize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | -| `iteratoreltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | +| `IteratorSize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | +| `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | | `eltype(IterType)` | `Any` | The type of the items returned by `next()` | | `length(iter)` | (*undefined*) | The number of items, if known | | `size(iter, [dim...])` | (*undefined*) | The number of items in each dimension, if known | -| Value returned by `iteratorsize(IterType)` | Required Methods | +| Value returned by `IteratorSize(IterType)` | Required Methods | |:------------------------------------------ |:------------------------------------------ | | `HasLength()` | `length(iter)` | | `HasShape()` | `length(iter)` and `size(iter, [dim...])` | | `IsInfinite()` | (*none*) | | `SizeUnknown()` | (*none*) | -| Value returned by `iteratoreltype(IterType)` | Required Methods | +| Value returned by `IteratorEltype(IterType)` | Required Methods | |:-------------------------------------------- |:------------------ | | `HasEltype()` | `eltype(IterType)` | | `EltypeUnknown()` | (*none*) | @@ -131,7 +131,7 @@ julia> sum(Squares(1803)) 1955361914 ``` -This is a very common pattern throughout the Julia standard library: a small set of required methods +This is a very common pattern throughout Julia Base: a small set of required methods define an informal interface that enable many fancier behaviors. In some cases, types will want to additionally specialize those extra behaviors when they know a more efficient algorithm can be used in their specific case. @@ -234,7 +234,7 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref If a type is defined as a subtype of `AbstractArray`, it inherits a very large set of rich behaviors including iteration and multidimensional indexing built on top of single-element access. See -the [arrays manual page](@ref man-multi-dim-arrays) and [standard library section](@ref lib-arrays) for more supported methods. +the [arrays manual page](@ref man-multi-dim-arrays) and the [Julia Base section](@ref lib-arrays) for more supported methods. A key part in defining an `AbstractArray` subtype is [`IndexStyle`](@ref). Since indexing is such an important part of an array and often occurs in hot loops, it's important to make both @@ -373,7 +373,7 @@ julia> copy(A) ``` In addition to all the iterable and indexable methods from above, these types can also interact -with each other and use most of the methods defined in the standard library for `AbstractArrays`: +with each other and use most of the methods defined in Julia Base for `AbstractArrays`: ```jldoctest squarevectype julia> A[SquaresVector(3)] @@ -391,7 +391,7 @@ something other than 1), you should specialize `indices`. You should also specia so that the `dims` argument (ordinarily a `Dims` size-tuple) can accept `AbstractUnitRange` objects, perhaps range-types `Ind` of your own design. For more information, see [Arrays with custom indices](@ref). -## [Strided Arrays] +## [Strided Arrays](@id man-interface-strided-arrays) | Methods to implement |   | Brief description | |:----------------------------------------------- |:-------------------------------------- |:------------------------------------------------------------------------------------- | diff --git a/doc/src/manual/introduction.md b/doc/src/manual/introduction.md index 58ea8faeaf6d7..ec75297c0cf7e 100644 --- a/doc/src/manual/introduction.md +++ b/doc/src/manual/introduction.md @@ -27,7 +27,7 @@ and [Ruby](https://en.wikipedia.org/wiki/Ruby_(programming_language)). The most significant departures of Julia from typical dynamic languages are: - * The core language imposes very little; the standard library is written in Julia itself, including + * The core language imposes very little; Julia Base and the standard library is written in Julia itself, including primitive operations like integer arithmetic * A rich language of types for constructing and describing objects, that can also optionally be used to make type declarations diff --git a/doc/src/manual/linear-algebra.md b/doc/src/manual/linear-algebra.md index e8131776759dc..549fd74507e05 100644 --- a/doc/src/manual/linear-algebra.md +++ b/doc/src/manual/linear-algebra.md @@ -261,7 +261,7 @@ in linear algebra. The following table summarizes the types of matrix factorizations that have been implemented in Julia. Details of their associated methods can be found in the [Linear Algebra](@ref) section -of the standard library documentation. +of the Julia Base documentation. | Type | Description | |:----------------- |:-------------------------------------------------------------------------------------------------------------- | diff --git a/doc/src/manual/metaprogramming.md b/doc/src/manual/metaprogramming.md index e11f111d95e54..16bff6d77d5ab 100644 --- a/doc/src/manual/metaprogramming.md +++ b/doc/src/manual/metaprogramming.md @@ -676,7 +676,7 @@ Notice that it would not be possible to write this as a function, since only the condition is available and it would be impossible to display the expression that computed it in the error message. -The actual definition of `@assert` in the standard library is more complicated. It allows the +The actual definition of `@assert` in Julia Base is more complicated. It allows the user to optionally specify their own error message, instead of just printing the failed expression. Just like in functions with a variable number of arguments, this is specified with an ellipses following the last argument: @@ -776,7 +776,7 @@ end ``` Here, we want `t0`, `t1`, and `val` to be private temporary variables, and we want `time` to refer -to the [`time`](@ref) function in the standard library, not to any `time` variable the user +to the [`time`](@ref) function in Julia Base, not to any `time` variable the user might have (the same applies to `println`). Imagine the problems that could occur if the user expression `ex` also contained assignments to a variable called `t0`, or defined its own `time` variable. We might get errors, or mysteriously incorrect behavior. @@ -787,7 +787,7 @@ to (and not declared global), declared local, or used as a function argument nam it is considered global. Local variables are then renamed to be unique (using the [`gensym`](@ref) function, which generates new symbols), and global variables are resolved within the macro definition environment. Therefore both of the above concerns are handled; the macro's locals will not conflict -with any user variables, and `time` and `println` will refer to the standard library definitions. +with any user variables, and `time` and `println` will refer to the Julia Base definitions. One problem remains however. Consider the following use of this macro: diff --git a/doc/src/manual/methods.md b/doc/src/manual/methods.md index 927282bfec675..2d9a490edfeac 100644 --- a/doc/src/manual/methods.md +++ b/doc/src/manual/methods.md @@ -593,7 +593,7 @@ The subtypes of `AbstractArray` typically implement two methods to achieve this: A method to convert the input array to a subtype of a specific `AbstractArray{T, N}` abstract type; and a method to make a new uninitialized array with a specific element type. -Sample implementations of these can be found in the standard library. +Sample implementations of these can be found in Julia Base. Here is a basic example usage of them, guaranteeing that `input` and `output` are of the same type: diff --git a/doc/src/manual/modules.md b/doc/src/manual/modules.md index 80143d322a4ec..68e8391de5e69 100644 --- a/doc/src/manual/modules.md +++ b/doc/src/manual/modules.md @@ -126,7 +126,7 @@ Core contains all identifiers considered "built in" to the language, i.e. part o and not libraries. Every module implicitly specifies `using Core`, since you can't do anything without those definitions. -Base is the standard library (the contents of base/). All modules implicitly contain `using Base`, +Base is a module that contains basic functionality (the contents of base/). All modules implicitly contain `using Base`, since this is needed in the vast majority of cases. ### Default top-level definitions and bare modules diff --git a/doc/src/manual/networking-and-streams.md b/doc/src/manual/networking-and-streams.md index fb091fcad691c..d43c0d1cbc7c2 100644 --- a/doc/src/manual/networking-and-streams.md +++ b/doc/src/manual/networking-and-streams.md @@ -100,7 +100,7 @@ Note that `a` is written to [`STDOUT`](@ref) by the [`write`](@ref) function and value is `1` (since `0x61` is one byte). For text I/O, use the [`print`](@ref) or [`show`](@ref) methods, depending on your needs (see -the standard library reference for a detailed discussion of the difference between the two): +the Julia Base reference for a detailed discussion of the difference between the two): ```jldoctest julia> print(STDOUT, 0x61) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index d376bb9076902..ec33a6ed6d530 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -666,7 +666,7 @@ of `fill_twos!` for different types of `a`. The second form is also often better style and can lead to more code reuse. -This pattern is used in several places in the standard library. For example, see `hvcat_fill` +This pattern is used in several places in Julia Base. For example, see `hvcat_fill` in [`abstractarray.jl`](https://github.com/JuliaLang/julia/blob/master/base/abstractarray.jl), or the [`fill!`](@ref) function, which we could have used instead of writing our own `fill_twos!`. @@ -804,7 +804,7 @@ statement can be found [on the mailing list](https://groups.google.com/forum/#!m Perhaps even worse than the run-time impact is the compile-time impact: Julia will compile specialized functions for each different `Car{Make, Model}`; if you have hundreds or thousands of such types, then every function that accepts such an object as a parameter (from a custom `get_year` function -you might write yourself, to the generic `push!` function in the standard library) will have hundreds +you might write yourself, to the generic `push!` function in Julia Base) will have hundreds or thousands of variants compiled for it. Each of these increases the size of the cache of compiled code, the length of internal lists of methods, etc. Excess enthusiasm for values-as-parameters can easily waste enormous resources. diff --git a/doc/src/manual/strings.md b/doc/src/manual/strings.md index 97991a0681258..7949d57be095e 100644 --- a/doc/src/manual/strings.md +++ b/doc/src/manual/strings.md @@ -517,7 +517,6 @@ julia> findfirst(equalto('p'), "xylophone") 5 julia> findfirst(equalto('z'), "xylophone") -0 ``` You can start the search for a character at a given offset by using [`findnext`](@ref) @@ -531,7 +530,6 @@ julia> findnext(equalto('o'), "xylophone", 5) 7 julia> findnext(equalto('o'), "xylophone", 8) -0 ``` You can use the [`contains`](@ref) function to check if a substring is contained in a string: diff --git a/doc/src/manual/style-guide.md b/doc/src/manual/style-guide.md index 486aa7fc9a1ac..f2a24be8e45d3 100644 --- a/doc/src/manual/style-guide.md +++ b/doc/src/manual/style-guide.md @@ -110,7 +110,7 @@ function double!(a::AbstractArray{<:Number}) end ``` -The Julia standard library uses this convention throughout and contains examples of functions +Julia Base uses this convention throughout and contains examples of functions with both copying and modifying forms (e.g., [`sort`](@ref) and [`sort!`](@ref)), and others which are just modifying (e.g., [`push!`](@ref), [`pop!`](@ref), [`splice!`](@ref)). It is typical for such functions to also return the modified array for convenience. diff --git a/doc/src/manual/unicode-input.md b/doc/src/manual/unicode-input.md index 57f9894e7423e..0952f6324b831 100644 --- a/doc/src/manual/unicode-input.md +++ b/doc/src/manual/unicode-input.md @@ -37,7 +37,7 @@ function unicode_data() for line in readlines(unidata) id, name, desc = split(line, ";")[[1, 2, 11]] codepoint = parse(UInt32, "0x$id") - names[codepoint] = Base.Unicode.titlecase(Base.Unicode.lowercase( + names[codepoint] = titlecase(lowercase( name == "" ? desc : desc == "" ? name : "$name / $desc")) end end @@ -61,7 +61,7 @@ function table_entries(completions, unicode_dict) for (chars, inputs) in sort!(collect(completions), by = first) code_points, unicode_names, characters = String[], String[], String[] for char in chars - push!(code_points, "U+$(Base.Unicode.uppercase(hex(char, 5)))") + push!(code_points, "U+$(uppercase(hex(char, 5)))") push!(unicode_names, get(unicode_dict, UInt32(char), "(No Unicode name)")) push!(characters, isempty(characters) ? fix_combining_chars(char) : "$char") end diff --git a/doc/src/manual/variables-and-scoping.md b/doc/src/manual/variables-and-scoping.md index ab9f0a92e59ed..4fc5ba1ee0b1f 100644 --- a/doc/src/manual/variables-and-scoping.md +++ b/doc/src/manual/variables-and-scoping.md @@ -25,7 +25,7 @@ constructs introducing scope blocks are: - local scope (don't allow nesting) - + type, immutable, macro + + (mutable) struct, macro * Scope blocks which may nest anywhere (in global or local scope): diff --git a/doc/src/stdlib/.gitignore b/doc/src/stdlib/.gitignore deleted file mode 100644 index e7a76fa8960d0..0000000000000 --- a/doc/src/stdlib/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -delimitedfiles.md -test.md -mmap.md -sharedarrays.md -profile.md -base64.md -filewatching.md -crc32c.md -dates.md -unicode.md -iterativeeigensolvers.md -printf.md -distributed.md diff --git a/doc/src/stdlib/constants.md b/doc/src/stdlib/constants.md deleted file mode 100644 index bb8af72ab3373..0000000000000 --- a/doc/src/stdlib/constants.md +++ /dev/null @@ -1,36 +0,0 @@ -# [Constants](@id lib-constants) - -```@docs -Core.nothing -Base.PROGRAM_FILE -Base.ARGS -Base.C_NULL -Base.VERSION -Base.LOAD_PATH -Base.Sys.BINDIR -Base.Sys.CPU_CORES -Base.Sys.WORD_SIZE -Base.Sys.KERNEL -Base.Sys.ARCH -Base.Sys.MACHINE -``` - -See also: - - * [`STDIN`](@ref) - * [`STDOUT`](@ref) - * [`STDERR`](@ref) - * [`ENV`](@ref) - * [`ENDIAN_BOM`](@ref) - * `Libc.MS_ASYNC` - * `Libc.MS_INVALIDATE` - * `Libc.MS_SYNC` - * [`Libdl.DL_LOAD_PATH`](@ref) - * [`Libdl.RTLD_DEEPBIND`](@ref Base.Libdl.RTLD_NOW) - * [`Libdl.RTLD_LOCAL`](@ref Base.Libdl.RTLD_NOW) - * [`Libdl.RTLD_NOLOAD`](@ref Base.Libdl.RTLD_NOW) - * [`Libdl.RTLD_LAZY`](@ref Base.Libdl.RTLD_NOW) - * [`Libdl.RTLD_NOW`](@ref) - * [`Libdl.RTLD_GLOBAL`](@ref Base.Libdl.RTLD_NOW) - * [`Libdl.RTLD_NODELETE`](@ref Base.Libdl.RTLD_NOW) - * [`Libdl.RTLD_FIRST`](@ref Base.Libdl.RTLD_NOW) diff --git a/doc/src/stdlib/libdl.md b/doc/src/stdlib/libdl.md deleted file mode 100644 index 9956624ad7f95..0000000000000 --- a/doc/src/stdlib/libdl.md +++ /dev/null @@ -1,15 +0,0 @@ -# Dynamic Linker - -The names in `Base.Libdl` are not exported and need to be called e.g. as `Libdl.dlopen`. - -```@docs -Base.Libdl.dlopen -Base.Libdl.dlopen_e -Base.Libdl.RTLD_NOW -Base.Libdl.dlsym -Base.Libdl.dlsym_e -Base.Libdl.dlclose -Base.Libdl.dlext -Base.Libdl.find_library -Base.Libdl.DL_LOAD_PATH -``` diff --git a/src/array.c b/src/array.c index f42b8cc36f517..519e56d75987b 100644 --- a/src/array.c +++ b/src/array.c @@ -531,38 +531,6 @@ JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i) return 1; } -int jl_array_isdefined(jl_value_t **args0, int nargs) -{ - assert(jl_is_array(args0[0])); - jl_depwarn("`isdefined(a::Array, i::Int)` is deprecated, " - "use `isassigned(a, i)` instead", (jl_value_t*)jl_symbol("isdefined")); - - jl_array_t *a = (jl_array_t*)args0[0]; - jl_value_t **args = &args0[1]; - size_t nidxs = nargs-1; - size_t i=0; - size_t k, stride=1; - size_t nd = jl_array_ndims(a); - for(k=0; k < nidxs; k++) { - if (!jl_is_long(args[k])) - jl_type_error("isdefined", (jl_value_t*)jl_long_type, args[k]); - size_t ii = jl_unbox_long(args[k])-1; - i += ii * stride; - size_t d = k>=nd ? 1 : jl_array_dim(a, k); - if (k < nidxs-1 && ii >= d) - return 0; - stride *= d; - } - for(; k < nd; k++) - stride *= jl_array_dim(a, k); - if (i >= stride) - return 0; - - if (a->flags.ptrarray) - return ((jl_value_t**)jl_array_data(a))[i] != NULL; - return 1; -} - JL_DLLEXPORT void jl_arrayset(jl_array_t *a, jl_value_t *rhs, size_t i) { assert(i < jl_array_len(a)); diff --git a/src/builtins.c b/src/builtins.c index d5b980ac24d03..a50ac83bc0530 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -644,9 +644,6 @@ JL_CALLABLE(jl_f_isdefined) jl_module_t *m = NULL; jl_sym_t *s = NULL; JL_NARGSV(isdefined, 1); - if (jl_is_array(args[0])) { - return jl_array_isdefined(args, nargs) ? jl_true : jl_false; - } if (nargs == 1) { JL_TYPECHK(isdefined, symbol, args[0]); s = (jl_sym_t*)args[0]; @@ -906,12 +903,6 @@ JL_CALLABLE(jl_f_apply_type) // generic function reflection ------------------------------------------------ -static void jl_check_type_tuple(jl_value_t *t, jl_sym_t *name, const char *ctx) -{ - if (!jl_is_tuple_type(t)) - jl_type_error_rt(jl_symbol_name(name), ctx, (jl_value_t*)jl_type_type, t); -} - JL_CALLABLE(jl_f_applicable) { JL_NARGSV(applicable, 1); @@ -925,20 +916,12 @@ JL_CALLABLE(jl_f_invoke) JL_NARGSV(invoke, 2); jl_value_t *argtypes = args[1]; JL_GC_PUSH1(&argtypes); - if (jl_is_tuple(args[1])) { - jl_depwarn("`invoke(f, (types...), ...)` is deprecated, " - "use `invoke(f, Tuple{types...}, ...)` instead", - (jl_value_t*)jl_symbol("invoke")); - argtypes = (jl_value_t*)jl_apply_tuple_type_v((jl_value_t**)jl_data_ptr(argtypes), - jl_nfields(argtypes)); - } - else { - jl_check_type_tuple(args[1], jl_gf_name(args[0]), "invoke"); - } + if (!jl_is_tuple_type(jl_unwrap_unionall(args[1]))) + jl_type_error_rt(jl_symbol_name(jl_gf_name(args[0])), "invoke", (jl_value_t*)jl_type_type, args[1]); if (!jl_tuple_isa(&args[2], nargs-2, (jl_datatype_t*)argtypes)) jl_error("invoke: argument type error"); args[1] = args[0]; // move function directly in front of arguments - jl_value_t *res = jl_gf_invoke((jl_tupletype_t*)argtypes, &args[1], nargs-1); + jl_value_t *res = jl_gf_invoke(argtypes, &args[1], nargs-1); JL_GC_POP(); return res; } diff --git a/src/codegen.cpp b/src/codegen.cpp index be03e1de95da9..68d33ee4bf4e2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1748,11 +1748,11 @@ static void show_source_loc(jl_codectx_t &ctx, JL_STREAM *out) jl_printf(out, "in %s at %s", ctx.name, ctx.file.str().c_str()); } -extern "C" void jl_binding_deprecation_warning(jl_binding_t *b); +extern "C" void jl_binding_deprecation_warning(jl_module_t *m, jl_binding_t *b); static void cg_bdw(jl_codectx_t &ctx, jl_binding_t *b) { - jl_binding_deprecation_warning(b); + jl_binding_deprecation_warning(ctx.module, b); if (b->deprecated == 1 && jl_options.depwarn) { show_source_loc(ctx, JL_STDERR); jl_printf(JL_STDERR, "\n"); @@ -4523,7 +4523,7 @@ static Function *jl_cfunction_object(jl_function_t *ff, jl_value_t *declrt, jl_t // check the cache jl_typemap_entry_t *sf = NULL; if (jl_cfunction_list.unknown != jl_nothing) { - sf = jl_typemap_assoc_by_type(jl_cfunction_list, (jl_tupletype_t*)cfunc_sig, NULL, /*subtype*/0, /*offs*/0, /*world*/1, /*max_world_mask*/0); + sf = jl_typemap_assoc_by_type(jl_cfunction_list, cfunc_sig, NULL, /*subtype*/0, /*offs*/0, /*world*/1, /*max_world_mask*/0); if (sf) { jl_value_t *v = sf->func.value; if (v) { diff --git a/src/dump.c b/src/dump.c index 40092a461a432..b7d12860afffc 100644 --- a/src/dump.c +++ b/src/dump.c @@ -2568,7 +2568,7 @@ static jl_method_t *jl_lookup_method_worldset(jl_methtable_t *mt, jl_datatype_t jl_method_t *_new; while (1) { entry = jl_typemap_assoc_by_type( - mt->defs, sig, NULL, /*subtype*/0, /*offs*/0, world, /*max_world_mask*/0); + mt->defs, (jl_value_t*)sig, NULL, /*subtype*/0, /*offs*/0, world, /*max_world_mask*/0); if (!entry) break; _new = (jl_method_t*)entry->func.value; @@ -2581,7 +2581,7 @@ static jl_method_t *jl_lookup_method_worldset(jl_methtable_t *mt, jl_datatype_t // If we failed to find a method (perhaps due to method deletion), // grab anything entry = jl_typemap_assoc_by_type( - mt->defs, sig, NULL, /*subtype*/0, /*offs*/0, /*world*/jl_world_counter, /*max_world_mask*/(~(size_t)0) >> 1); + mt->defs, (jl_value_t*)sig, NULL, /*subtype*/0, /*offs*/0, /*world*/jl_world_counter, /*max_world_mask*/(~(size_t)0) >> 1); assert(entry); assert(entry->max_world != ~(size_t)0); *max_world = entry->max_world; diff --git a/src/gf.c b/src/gf.c index 65473ad03d7e0..ec99041f626fb 100644 --- a/src/gf.c +++ b/src/gf.c @@ -146,7 +146,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m, assert(world >= m->min_world && "typemap lookup is corrupted"); JL_LOCK(&m->writelock); jl_typemap_entry_t *sf = - jl_typemap_assoc_by_type(m->specializations, (jl_tupletype_t*)type, NULL, /*subtype*/0, /*offs*/0, world, /*max_world_mask*/0); + jl_typemap_assoc_by_type(m->specializations, type, NULL, /*subtype*/0, /*offs*/0, world, /*max_world_mask*/0); if (sf && jl_is_method_instance(sf->func.value)) { jl_method_instance_t *linfo = (jl_method_instance_t*)sf->func.value; assert(linfo->min_world <= sf->min_world && linfo->max_world >= sf->max_world); @@ -177,7 +177,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m, return li; } -JL_DLLEXPORT jl_value_t *jl_specializations_lookup(jl_method_t *m, jl_tupletype_t *type, size_t world) +JL_DLLEXPORT jl_value_t *jl_specializations_lookup(jl_method_t *m, jl_value_t *type, size_t world) { jl_typemap_entry_t *sf = jl_typemap_assoc_by_type( m->specializations, type, NULL, /*subtype*/0, /*offs*/0, world, /*max_world_mask*/0); @@ -186,7 +186,7 @@ JL_DLLEXPORT jl_value_t *jl_specializations_lookup(jl_method_t *m, jl_tupletype_ return sf->func.value; } -JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_tupletype_t *type, size_t world) +JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_value_t *type, size_t world) { jl_typemap_entry_t *sf = jl_typemap_assoc_by_type( mt->defs, type, NULL, /*subtype*/0, /*offs*/0, world, /*max_world_mask*/0); @@ -548,7 +548,7 @@ jl_value_t *jl_nth_slot_type(jl_value_t *sig, size_t i) // after intersection, the argument tuple type needs to be corrected to reflect the signature match // that occurred, if the arguments contained a Type but the signature matched on the kind // if sharp_match is returned as false, this tt may have matched only because of bug in subtyping -static jl_tupletype_t *join_tsig(jl_tupletype_t *tt, jl_tupletype_t *sig, int *sharp_match) +static jl_tupletype_t *join_tsig(jl_tupletype_t *tt, jl_value_t *sig, int *sharp_match) { jl_svec_t *newparams = NULL; JL_GC_PUSH1(&newparams); @@ -1070,10 +1070,10 @@ static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_datatype jl_method_instance_t *nf = NULL; JL_GC_PUSH4(&env, &entry, &func, &sig); - entry = jl_typemap_assoc_by_type(mt->defs, tt, &env, /*subtype*/1, /*offs*/0, world, /*max_world_mask*/0); + entry = jl_typemap_assoc_by_type(mt->defs, (jl_value_t*)tt, &env, /*subtype*/1, /*offs*/0, world, /*max_world_mask*/0); if (entry != NULL) { jl_method_t *m = entry->func.method; - if (!jl_has_call_ambiguities(tt, m)) { + if (!jl_has_call_ambiguities((jl_value_t*)tt, m)) { #ifdef TRACE_COMPILE if (!jl_has_free_typevars((jl_value_t*)tt)) { jl_printf(JL_STDERR, "precompile("); @@ -1082,7 +1082,7 @@ static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_datatype } #endif int sharp_match; - sig = join_tsig(tt, (jl_tupletype_t*)m->sig, &sharp_match); + sig = join_tsig(tt, m->sig, &sharp_match); if (!mt_cache) { nf = jl_specializations_get_linfo(m, (jl_value_t*)sig, env, world); } @@ -1167,7 +1167,7 @@ static int check_ambiguous_visitor(jl_typemap_entry_t *oldentry, struct typemap_ // (if type-morespecific made a mistake, this also might end up finding // that isect == type or isect == sig and return the original match) jl_typemap_entry_t *l = jl_typemap_assoc_by_type( - map, (jl_tupletype_t*)isect, NULL, /*subtype*/0, /*offs*/0, + map, isect, NULL, /*subtype*/0, /*offs*/0, closure->newentry->min_world, /*max_world_mask*/0); if (l != NULL) // ok, intersection is covered return 1; @@ -1637,7 +1637,7 @@ jl_tupletype_t *arg_type_tuple(jl_value_t **args, size_t nargs) jl_method_instance_t *jl_method_lookup_by_type(jl_methtable_t *mt, jl_tupletype_t *types, int cache, int allow_exec, size_t world) { - jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(mt->cache, types, NULL, /*subtype*/1, jl_cachearg_offset(mt), world, /*max_world_mask*/0); + jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(mt->cache, (jl_value_t*)types, NULL, /*subtype*/1, jl_cachearg_offset(mt), world, /*max_world_mask*/0); if (entry) { jl_method_instance_t *linfo = (jl_method_instance_t*)entry->func.value; assert(linfo->min_world <= entry->min_world && linfo->max_world >= entry->max_world && @@ -1645,7 +1645,7 @@ jl_method_instance_t *jl_method_lookup_by_type(jl_methtable_t *mt, jl_tupletype_ return linfo; } JL_LOCK(&mt->writelock); - entry = jl_typemap_assoc_by_type(mt->cache, types, NULL, /*subtype*/1, jl_cachearg_offset(mt), world, /*max_world_mask*/0); + entry = jl_typemap_assoc_by_type(mt->cache, (jl_value_t*)types, NULL, /*subtype*/1, jl_cachearg_offset(mt), world, /*max_world_mask*/0); if (entry) { jl_method_instance_t *linfo = (jl_method_instance_t*)entry->func.value; assert(linfo->min_world <= entry->min_world && linfo->max_world >= entry->max_world && @@ -1808,12 +1808,12 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world jl_svec_t *env = (jl_svec_t*)jl_svecref(match, 1); jl_tupletype_t *ti = (jl_tupletype_t*)jl_unwrap_unionall(jl_svecref(match, 0)); jl_method_instance_t *nf = NULL; - if (ti == types && !jl_has_call_ambiguities(types, m)) { + if (ti == types && !jl_has_call_ambiguities((jl_value_t*)types, m)) { jl_datatype_t *dt = jl_first_argument_datatype(jl_unwrap_unionall((jl_value_t*)types)); assert(jl_is_datatype(dt)); jl_methtable_t *mt = dt->name->mt; int sharp_match; - sig = join_tsig(ti, (jl_tupletype_t*)m->sig, &sharp_match); + sig = join_tsig(ti, m->sig, &sharp_match); if (sharp_match) { JL_LOCK(&mt->writelock); nf = cache_method(mt, &mt->cache, (jl_value_t*)mt, sig, ti, m, world, env, /*allow_exec*/1); @@ -1872,7 +1872,7 @@ JL_DLLEXPORT jl_value_t *jl_get_spec_lambda(jl_tupletype_t *types, size_t world) } // see if a call to m with computed from `types` is ambiguous -JL_DLLEXPORT int jl_is_call_ambiguous(jl_tupletype_t *types, jl_method_t *m) +JL_DLLEXPORT int jl_is_call_ambiguous(jl_value_t *types, jl_method_t *m) { if (m->ambig == jl_nothing) return 0; @@ -1886,21 +1886,22 @@ JL_DLLEXPORT int jl_is_call_ambiguous(jl_tupletype_t *types, jl_method_t *m) // see if a call to m with a subtype of `types` might be ambiguous // if types is from a call signature (approximated by isleaftype), this is the same as jl_is_call_ambiguous above -JL_DLLEXPORT int jl_has_call_ambiguities(jl_tupletype_t *types, jl_method_t *m) +JL_DLLEXPORT int jl_has_call_ambiguities(jl_value_t *types, jl_method_t *m) { if (m->ambig == jl_nothing) return 0; for (size_t i = 0; i < jl_array_len(m->ambig); i++) { jl_method_t *mambig = (jl_method_t*)jl_array_ptr_ref(m->ambig, i); - if (!jl_has_empty_intersection((jl_value_t*)mambig->sig, (jl_value_t*)types)) + if (!jl_has_empty_intersection(mambig->sig, types)) return 1; } return 0; } // add type of `f` to front of argument tuple type -jl_tupletype_t *jl_argtype_with_function(jl_function_t *f, jl_tupletype_t *types) +jl_value_t *jl_argtype_with_function(jl_function_t *f, jl_value_t *types0) { + jl_value_t *types = jl_unwrap_unionall(types0); size_t l = jl_nparams(types); jl_value_t *tt = (jl_value_t*)jl_alloc_svec(1+l); size_t i; @@ -1912,8 +1913,9 @@ jl_tupletype_t *jl_argtype_with_function(jl_function_t *f, jl_tupletype_t *types for(i=0; i < l; i++) jl_svecset(tt, i+1, jl_tparam(types,i)); tt = (jl_value_t*)jl_apply_tuple_type((jl_svec_t*)tt); + tt = jl_rewrap_unionall(tt, types0); JL_GC_POP(); - return (jl_tupletype_t*)tt; + return tt; } #ifdef JL_TRACE @@ -2083,9 +2085,9 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs) return verify_type(res); } -JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_datatype_t *types, size_t world) +JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, size_t world) { - jl_methtable_t *mt = ((jl_datatype_t*)jl_tparam0(types))->name->mt; + jl_methtable_t *mt = jl_first_argument_datatype(types)->name->mt; jl_svec_t *env = jl_emptysvec; JL_GC_PUSH1(&env); jl_typemap_entry_t *entry = jl_typemap_assoc_by_type( @@ -2107,21 +2109,21 @@ JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_datatype_t *types, size_t world) // every definition has its own private method table for this purpose. // // NOTE: assumes argument type is a subtype of the lookup type. -jl_value_t *jl_gf_invoke(jl_tupletype_t *types0, jl_value_t **args, size_t nargs) +jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) { size_t world = jl_get_ptls_states()->world_age; jl_svec_t *tpenv = jl_emptysvec; jl_tupletype_t *tt = NULL; - jl_tupletype_t *types = NULL; + jl_value_t *types = NULL; jl_tupletype_t *sig = NULL; JL_GC_PUSH4(&types, &tpenv, &sig, &tt); jl_value_t *gf = args[0]; - types = (jl_datatype_t*)jl_argtype_with_function(gf, (jl_tupletype_t*)types0); + types = jl_argtype_with_function(gf, types0); jl_methtable_t *mt = jl_gf_mtable(gf); jl_typemap_entry_t *entry = (jl_typemap_entry_t*)jl_gf_invoke_lookup(types, world); if ((jl_value_t*)entry == jl_nothing) { - jl_method_error_bare(gf, (jl_value_t*)types0, world); + jl_method_error_bare(gf, types0, world); // unreachable } @@ -2154,7 +2156,7 @@ jl_value_t *jl_gf_invoke(jl_tupletype_t *types0, jl_value_t **args, size_t nargs method->invokes.unknown = jl_nothing; int sharp_match; - sig = join_tsig(tt, (jl_tupletype_t*)method->sig, &sharp_match); + sig = join_tsig(tt, method->sig, &sharp_match); mfunc = cache_method(mt, &method->invokes, entry->func.value, sig, tt, method, world, tpenv, 1); } JL_UNLOCK(&method->writelock); @@ -2197,10 +2199,10 @@ static int tupletype_has_datatype(jl_tupletype_t *tt, tupletype_stack_t *stack) JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, jl_typemap_entry_t *entry, - jl_tupletype_t *tt, + jl_value_t *tt, size_t world) { - if (!jl_is_leaf_type((jl_value_t*)tt) || tupletype_has_datatype(tt, NULL)) + if (!jl_is_leaf_type((jl_value_t*)tt) || tupletype_has_datatype((jl_tupletype_t*)tt, NULL)) return jl_nothing; jl_method_t *method = entry->func.method; @@ -2228,7 +2230,7 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, JL_GC_PUSH2(&tpenv, &sig); if (jl_is_unionall(entry->sig)) { jl_value_t *ti = - jl_type_intersection_env((jl_value_t*)tt, (jl_value_t*)entry->sig, &tpenv); + jl_type_intersection_env(tt, (jl_value_t*)entry->sig, &tpenv); assert(ti != (jl_value_t*)jl_bottom_type); (void)ti; } @@ -2237,9 +2239,9 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, method->invokes.unknown = jl_nothing; int sharp_match; - sig = join_tsig(tt, (jl_tupletype_t*)method->sig, &sharp_match); + sig = join_tsig((jl_tupletype_t*)tt, method->sig, &sharp_match); jl_method_instance_t *mfunc = cache_method(mt, &method->invokes, entry->func.value, - sig, tt, method, world, tpenv, 1); + sig, (jl_tupletype_t*)tt, method, world, tpenv, 1); JL_GC_POP(); JL_UNLOCK(&method->writelock); return (jl_value_t*)mfunc; diff --git a/src/init.c b/src/init.c index fb0993ef99180..80a1cb93ebd37 100644 --- a/src/init.c +++ b/src/init.c @@ -784,7 +784,6 @@ void jl_get_builtin_hooks(void) for (t = 0; t < jl_n_threads; t++) { jl_ptls_t ptls2 = jl_all_tls_states[t]; ptls2->root_task->tls = jl_nothing; - ptls2->root_task->consumers = jl_nothing; ptls2->root_task->donenotify = jl_nothing; ptls2->root_task->exception = jl_nothing; ptls2->root_task->result = jl_nothing; diff --git a/src/jltypes.c b/src/jltypes.c index d8830d34c7589..b0b4b0dc73e9e 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2046,8 +2046,9 @@ void jl_init_types(void) jl_code_info_type = jl_new_datatype(jl_symbol("CodeInfo"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(9, + jl_perm_symsvec(10, "code", + "signature_for_inference_heuristics", "slottypes", "ssavaluetypes", "slotflags", @@ -2056,17 +2057,18 @@ void jl_init_types(void) "inlineable", "propagate_inbounds", "pure"), - jl_svec(9, + jl_svec(10, jl_array_any_type, jl_any_type, jl_any_type, + jl_any_type, jl_array_uint8_type, jl_array_any_type, jl_bool_type, jl_bool_type, jl_bool_type, jl_bool_type), - 0, 1, 9); + 0, 1, 10); jl_method_type = jl_new_datatype(jl_symbol("Method"), core, diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 667854da2bd16..80ab7f33fa933 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -8,7 +8,9 @@ ;; be an operator. (define prec-assignment (append! (add-dots '(= += -= *= /= //= |\\=| ^= ÷= %= <<= >>= >>>= |\|=| &= ⊻=)) - '(:= => ~ $=))) + '(:= ~ $=))) +;; comma - higher than assignment outside parentheses, lower when inside +(define prec-pair '(=>)) (define prec-conditional '(?)) (define prec-arrow (append! '(-- -->) @@ -34,7 +36,7 @@ (define prec-dot '(|.|)) (define prec-names '(prec-assignment - prec-conditional prec-lazy-or prec-lazy-and prec-arrow prec-comparison + prec-pair prec-conditional prec-lazy-or prec-lazy-and prec-arrow prec-comparison prec-pipe< prec-pipe> prec-colon prec-plus prec-bitshift prec-times prec-rational prec-power prec-decl prec-dot)) @@ -714,8 +716,8 @@ (if (or (eqv? nxt #\,) (eqv? nxt #\) ) (eqv? nxt #\}) (eqv? nxt #\])) t (begin (ts:put-back! s t spc) - (parse-assignment s parse-cond))))) - (parse-assignment s parse-cond)))) + (parse-assignment s parse-pair))))) + (parse-assignment s parse-pair)))) (define (eventually-call? ex) (and (pair? ex) @@ -735,14 +737,12 @@ ex (begin (take-token s) - (cond ((eq? t '~) + (cond ((eq? t '~) ;; ~ is the only non-syntactic assignment-precedence operators (if (and space-sensitive (ts:space? s) (not (eqv? (peek-char (ts:port s)) #\ ))) (begin (ts:put-back! s t (ts:space? s)) ex) (list 'call t ex (parse-assignment s down)))) - ((eq? t '=>) ;; ~ and => are the only non-syntactic assignment-precedence operators - (list 'call t ex (parse-assignment s down))) ((eq? t '=) ;; insert line/file for short-form function defs, otherwise leave alone (let ((lno (input-port-line (ts:port s)))) @@ -753,7 +753,7 @@ ; parse-comma is needed for commas outside parens, for example a = b,c (define (parse-comma s) - (let loop ((ex (list (parse-cond s))) + (let loop ((ex (list (parse-pair s))) (first? #t) (t (peek-token s))) (if (not (eqv? t #\,)) @@ -767,7 +767,9 @@ (begin (take-token s) (if (or (eof-object? (peek-token s)) (eq? (peek-token s) '=)) (loop ex #f (peek-token s)) - (loop (cons (parse-cond s) ex) #f (peek-token s))))))) + (loop (cons (parse-pair s) ex) #f (peek-token s))))))) + +(define (parse-pair s) (parse-RtoL s parse-cond is-prec-pair? #f parse-pair)) (define (parse-cond s) (let ((ex (parse-arrow s))) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 28bc5a7bd66cc..2c91d37c76f1d 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -362,7 +362,8 @@ 'nothing (cons 'list (map car sparams))) ,(if (null? loc) 0 (cadr loc)) - (inert ,(if (null? loc) 'none (caddr loc)))))))) + (inert ,(if (null? loc) 'none (caddr loc))) + false))))) (list gf)) '())) (types (llist-types argl)) @@ -2342,35 +2343,38 @@ ,.(apply append rows))) `(call (top typed_vcat) ,t ,@a))))) - '|'| (lambda (e) (expand-forms `(call (core postfixapostrophize) ,(cadr e)))) + '|'| (lambda (e) (expand-forms `(call (top adjoint) ,(cadr e)))) '|.'| (lambda (e) (begin (deprecation-message (string "The syntax `.'` for transposition is deprecated, " "and the special lowering of `.'` in multiplication " "(`*`), left-division (`\\`), and right-division (`/`) " "operations, for example `A.'*B` lowering to `At_mul_B(A, B)`, " "`A\\B.'` lowering to `A_ldiv_Bt(A, B)`, and `A.'/B.'` " "lowering to `At_rdiv_Bt(A, B)`, has been removed " - "in favor of a lazy `Transpose` wrapper type and " + "in favor of lazy transposition via `transpose`, " + "a corresponding lazy `Transpose` wrapper type, and " "dispatch on that type. Two rewrites for `A.'` for " - "matrix `A` exist: eager or materializing `transpose(A)`, " - "which constructs a freshly allocated matrix of `A`'s type " - "and containing the transpose of `A`, and lazy " - "`Transpose(A)`, which wraps `A` in a `Transpose` " - "view type. Which rewrite is appropriate depends on " + "matrix `A` exist: " + "`transpose(A)`, which yields a lazily transposed " + "version of `A` (often by wrapping in the `Transpose` type), " + "and `copy(transpose(A))` which lazily transposes " + "`A` as above and then materializes that lazily " + "transposed `A` into a freshly allocated matrix " + "of `A`'s type. Which rewrite is appropriate depends on " "context: If `A.'` appears in a multiplication, " "left-division, or right-division operation that " "was formerly specially lowered to an `A_mul_B`-like " - "call, then the lazy `Tranpose(A)` is the correct " + "call, then the lazy `transpose(A)` is the correct " "replacement and will result in dispatch to a method " "equivalent to the former `A_mul_B`-like call. For " "example, `A.'*B`, formerly yielding `At_mul_B(A, B)`, " - "should be rewritten `Transpose(A)*B`, which will " + "should be rewritten `transpose(A)*B`, which will " "dispatch to a method equivalent to the former " "`At_mul_B(A, B)` method. If `A.'` appears outside " - "such an operation, then `transpose(A)` is the " - "correct rewrite. For vector `A`, `A.'` already " - "transposed lazily to a `RowVector`, so `Transpose(A)`. " + "such an operation, then `copy(transpose(A))` is the " + "functionally equivalent rewrite. For vector `A`, `A.'` already " + "transposed lazily to a `RowVector`, so `transpose(A)`, " "which now yields a `Transpose`-wrapped vector " - "behaviorally equivalent to the former `RowVector` " + "behaviorally equivalent to the former `RowVector`, " "is always the correct rewrite for vectors. For " "more information, see issue #5332 on Julia's " "issue tracker on GitHub." #\newline) #f) diff --git a/src/julia.h b/src/julia.h index 665f16ca6d90b..3a207c61f8d5d 100644 --- a/src/julia.h +++ b/src/julia.h @@ -229,6 +229,7 @@ typedef struct _jl_llvm_functions_t { // This type describes a single function body typedef struct _jl_code_info_t { jl_array_t *code; // Any array of statements + jl_value_t *signature_for_inference_heuristics; // optional method used during inference jl_value_t *slottypes; // types of variable slots (or `nothing`) jl_value_t *ssavaluetypes; // types of ssa values (or count of them) jl_array_t *slotflags; // local var bit flags @@ -1512,7 +1513,6 @@ typedef struct _jl_task_t { struct _jl_task_t *parent; jl_value_t *tls; jl_sym_t *state; - jl_value_t *consumers; jl_value_t *donenotify; jl_value_t *result; jl_value_t *exception; diff --git a/src/julia_internal.h b/src/julia_internal.h index 56490e34e1c44..741ebf6808951 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -399,7 +399,7 @@ STATIC_INLINE jl_value_t *jl_call_method_internal(jl_method_instance_t *meth, jl return jl_call_fptr_internal(&fptr, meth, args, nargs); } -jl_tupletype_t *jl_argtype_with_function(jl_function_t *f, jl_tupletype_t *types); +jl_value_t *jl_argtype_with_function(jl_function_t *f, jl_value_t *types); JL_DLLEXPORT jl_value_t *jl_apply_2va(jl_value_t *f, jl_value_t **args, uint32_t nargs); @@ -516,7 +516,7 @@ int jl_is_toplevel_only_expr(jl_value_t *e); jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule); jl_method_instance_t *jl_method_lookup(jl_methtable_t *mt, jl_value_t **args, size_t nargs, int cache, size_t world); -jl_value_t *jl_gf_invoke(jl_tupletype_t *types, jl_value_t **args, size_t nargs); +jl_value_t *jl_gf_invoke(jl_value_t *types, jl_value_t **args, size_t nargs); jl_method_instance_t *jl_lookup_generic(jl_value_t **args, uint32_t nargs, uint32_t callsite, size_t world); JL_DLLEXPORT jl_value_t *jl_matching_methods(jl_tupletype_t *types, int lim, int include_ambiguous, size_t world, size_t *min_valid, size_t *max_valid); @@ -638,10 +638,10 @@ JL_DLLEXPORT jl_array_t *jl_idtable_rehash(jl_array_t *a, size_t newsz); JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module); jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world); -JL_DLLEXPORT int jl_has_call_ambiguities(jl_tupletype_t *types, jl_method_t *m); +JL_DLLEXPORT int jl_has_call_ambiguities(jl_value_t *types, jl_method_t *m); jl_method_instance_t *jl_get_specialized(jl_method_t *m, jl_value_t *types, jl_svec_t *sp); int jl_is_rettype_inferred(jl_method_instance_t *li); -JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_tupletype_t *type, size_t world); +JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_value_t *type, size_t world); JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m, jl_value_t *type, jl_svec_t *sparams, size_t world); JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee, jl_method_instance_t *caller); JL_DLLEXPORT void jl_method_table_add_backedge(jl_methtable_t *mt, jl_value_t *typ, jl_value_t *caller); @@ -846,7 +846,6 @@ JL_DLLEXPORT jl_value_t *jl_flipsign_int(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_select_value(jl_value_t *isfalse, jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_arraylen(jl_value_t *a); int jl_array_store_unboxed(jl_value_t *el_type); -int jl_array_isdefined(jl_value_t **args, int nargs); JL_DLLEXPORT jl_value_t *(jl_array_data_owner)(jl_array_t *a); JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i); @@ -927,7 +926,7 @@ jl_typemap_entry_t *jl_typemap_insert(union jl_typemap_t *cache, jl_value_t *par jl_value_t **overwritten); jl_typemap_entry_t *jl_typemap_assoc_by_type( - union jl_typemap_t ml_or_cache, jl_tupletype_t *types, jl_svec_t **penv, + union jl_typemap_t ml_or_cache, jl_value_t *types, jl_svec_t **penv, int8_t subtype, int8_t offs, size_t world, size_t max_world_mask); jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_value_t **args, size_t n, int8_t offs, size_t world); jl_typemap_entry_t *jl_typemap_entry_assoc_exact(jl_typemap_entry_t *mn, jl_value_t **args, size_t n, size_t world); diff --git a/src/method.c b/src/method.c index e956abdc76b55..77f8d497a2621 100644 --- a/src/method.c +++ b/src/method.c @@ -187,6 +187,7 @@ static void jl_code_info_set_ast(jl_code_info_t *li, jl_expr_t *ast) jl_array_del_end(meta, na - ins); } } + li->signature_for_inference_heuristics = jl_nothing; jl_array_t *vinfo = (jl_array_t*)jl_exprarg(ast, 1); jl_array_t *vis = (jl_array_t*)jl_array_ptr_ref(vinfo, 0); size_t nslots = jl_array_len(vis); @@ -255,6 +256,7 @@ JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void) (jl_code_info_t*)jl_gc_alloc(ptls, sizeof(jl_code_info_t), jl_code_info_type); src->code = NULL; + src->signature_for_inference_heuristics = NULL; src->slotnames = NULL; src->slotflags = NULL; src->slottypes = NULL; @@ -442,8 +444,8 @@ static void jl_method_set_source(jl_method_t *m, jl_code_info_t *src) else if (jl_expr_nargs(st) == 2 && jl_exprarg(st, 0) == (jl_value_t*)generated_sym) { m->generator = NULL; jl_value_t *gexpr = jl_exprarg(st, 1); - if (jl_expr_nargs(gexpr) == 6) { - // expects (new (core GeneratedFunctionStub) funcname argnames sp line file) + if (jl_expr_nargs(gexpr) == 7) { + // expects (new (core GeneratedFunctionStub) funcname argnames sp line file expandearly) jl_value_t *funcname = jl_exprarg(gexpr, 1); assert(jl_is_symbol(funcname)); if (jl_get_global(m->module, (jl_sym_t*)funcname) != NULL) { diff --git a/src/module.c b/src/module.c index 7f3cfce998786..5d967bef02081 100644 --- a/src/module.c +++ b/src/module.c @@ -229,7 +229,7 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding(jl_module_t *m, jl_sym_t *var) return jl_get_binding_(m, var, NULL); } -void jl_binding_deprecation_warning(jl_binding_t *b); +void jl_binding_deprecation_warning(jl_module_t *m, jl_binding_t *b); JL_DLLEXPORT jl_binding_t *jl_get_binding_or_error(jl_module_t *m, jl_sym_t *var) { @@ -237,7 +237,7 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding_or_error(jl_module_t *m, jl_sym_t *var if (b == NULL) jl_undefined_var_error(var); if (b->deprecated) - jl_binding_deprecation_warning(b); + jl_binding_deprecation_warning(m, b); return b; } @@ -451,7 +451,7 @@ JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m, jl_sym_t *var) { jl_binding_t *b = jl_get_binding(m, var); if (b == NULL) return NULL; - if (b->deprecated) jl_binding_deprecation_warning(b); + if (b->deprecated) jl_binding_deprecation_warning(m, b); return b->value; } @@ -510,7 +510,7 @@ jl_binding_t *jl_get_dep_message_binding(jl_module_t *m, jl_binding_t *deprecate return jl_get_binding(m, jl_symbol(dep_binding_name)); } -void jl_binding_deprecation_warning(jl_binding_t *b) +void jl_binding_deprecation_warning(jl_module_t *m, jl_binding_t *b) { // Only print a warning for deprecated == 1 (renamed). // For deprecated == 2 (moved to a package) the binding is to a function @@ -559,8 +559,14 @@ void jl_binding_deprecation_warning(jl_binding_t *b) } jl_printf(JL_STDERR, ".\n"); - if (jl_options.depwarn != JL_OPTIONS_DEPWARN_ERROR) - jl_printf(JL_STDERR, " likely near %s:%d\n", jl_filename, jl_lineno); + if (jl_options.depwarn != JL_OPTIONS_DEPWARN_ERROR) { + if (jl_lineno == 0) { + jl_printf(JL_STDERR, " in module %s\n", jl_symbol_name(m->name)); + } + else { + jl_printf(JL_STDERR, " likely near %s:%d\n", jl_filename, jl_lineno); + } + } if (jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) { if (b->owner) diff --git a/src/task.c b/src/task.c index 7643ae3919130..6cd7d8c6727d8 100644 --- a/src/task.c +++ b/src/task.c @@ -604,7 +604,6 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, size_t ssize) t->current_module = NULL; t->parent = ptls->current_task; t->tls = jl_nothing; - t->consumers = jl_nothing; t->state = runnable_sym; t->start = start; t->result = jl_nothing; @@ -676,18 +675,17 @@ void jl_init_tasks(void) NULL, jl_any_type, jl_emptysvec, - jl_perm_symsvec(10, + jl_perm_symsvec(9, "parent", "storage", "state", - "consumers", "donenotify", "result", "exception", "backtrace", "logstate", "code"), - jl_svec(10, + jl_svec(9, jl_any_type, jl_any_type, jl_sym_type, @@ -696,9 +694,8 @@ void jl_init_tasks(void) jl_any_type, jl_any_type, jl_any_type, - jl_any_type, jl_any_type), - 0, 1, 9); + 0, 1, 8); jl_svecset(jl_task_type->types, 0, (jl_value_t*)jl_task_type); done_sym = jl_symbol("done"); @@ -728,7 +725,6 @@ void jl_init_root_task(void *stack, size_t ssize) ptls->current_task->parent = ptls->current_task; ptls->current_task->current_module = ptls->current_module; ptls->current_task->tls = jl_nothing; - ptls->current_task->consumers = jl_nothing; ptls->current_task->state = runnable_sym; ptls->current_task->start = NULL; ptls->current_task->result = jl_nothing; diff --git a/src/toplevel.c b/src/toplevel.c index 78c2e9328332d..7dbf75f93bdf6 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -576,6 +576,7 @@ static jl_code_info_t *expr_to_code_info(jl_value_t *expr) jl_gc_wb(src, src->slotflags); src->ssavaluetypes = jl_box_long(0); jl_gc_wb(src, src->ssavaluetypes); + src->signature_for_inference_heuristics = jl_nothing; JL_GC_POP(); return src; diff --git a/src/typemap.c b/src/typemap.c index 9406b3ec2b96b..74da3a3f750ab 100644 --- a/src/typemap.c +++ b/src/typemap.c @@ -561,22 +561,24 @@ int jl_typemap_intersection_visitor(union jl_typemap_t map, int offs, there tends to be lots of variation there. The type of the 0th argument (the function) is always the same for most functions. */ -static jl_typemap_entry_t *jl_typemap_assoc_by_type_(jl_typemap_entry_t *ml, jl_tupletype_t *types, +static jl_typemap_entry_t *jl_typemap_assoc_by_type_(jl_typemap_entry_t *ml, jl_value_t *types, jl_svec_t **penv, size_t world, size_t max_world_mask) { - size_t n = jl_field_count(types); - int typesisva = n == 0 ? 0 : jl_is_vararg_type(jl_tparam(types, n-1)); + jl_value_t *unw = jl_unwrap_unionall((jl_value_t*)types); + int isua = jl_is_unionall(types); + size_t n = jl_field_count(unw); + int typesisva = n == 0 ? 0 : jl_is_vararg_type(jl_tparam(unw, n-1)); for (; ml != (void*)jl_nothing; ml = ml->next) { if (world < ml->min_world || world > (ml->max_world | max_world_mask)) continue; // ignore replaced methods size_t lensig = jl_field_count(jl_unwrap_unionall((jl_value_t*)ml->sig)); if (lensig == n || (ml->va && lensig <= n+1)) { int resetenv = 0, ismatch = 1; - if (ml->simplesig != (void*)jl_nothing) { + if (ml->simplesig != (void*)jl_nothing && !isua) { size_t lensimplesig = jl_field_count(ml->simplesig); int isva = lensimplesig > 0 && jl_is_vararg_type(jl_tparam(ml->simplesig, lensimplesig - 1)); if (lensig == n || (isva && lensimplesig <= n + 1)) - ismatch = sig_match_by_type_simple(jl_svec_data(types->parameters), n, + ismatch = sig_match_by_type_simple(jl_svec_data(((jl_datatype_t*)types)->parameters), n, ml->simplesig, lensimplesig, isva); else ismatch = 0; @@ -584,14 +586,14 @@ static jl_typemap_entry_t *jl_typemap_assoc_by_type_(jl_typemap_entry_t *ml, jl_ if (ismatch == 0) ; // nothing - else if (ml->isleafsig && !typesisva) - ismatch = sig_match_by_type_leaf(jl_svec_data(types->parameters), + else if (ml->isleafsig && !typesisva && !isua) + ismatch = sig_match_by_type_leaf(jl_svec_data(((jl_datatype_t*)types)->parameters), ml->sig, lensig); - else if (ml->issimplesig && !typesisva) - ismatch = sig_match_by_type_simple(jl_svec_data(types->parameters), n, + else if (ml->issimplesig && !typesisva && !isua) + ismatch = sig_match_by_type_simple(jl_svec_data(((jl_datatype_t*)types)->parameters), n, ml->sig, lensig, ml->va); else { - ismatch = jl_subtype_matching((jl_value_t*)types, (jl_value_t*)ml->sig, penv); + ismatch = jl_subtype_matching(types, (jl_value_t*)ml->sig, penv); if (ismatch && penv) resetenv = 1; } @@ -600,7 +602,7 @@ static jl_typemap_entry_t *jl_typemap_assoc_by_type_(jl_typemap_entry_t *ml, jl_ size_t i, l; for (i = 0, l = jl_svec_len(ml->guardsigs); i < l; i++) { // see corresponding code in jl_typemap_entry_assoc_exact - if (jl_subtype((jl_value_t*)types, jl_svecref(ml->guardsigs, i))) { + if (jl_subtype(types, jl_svecref(ml->guardsigs, i))) { ismatch = 0; break; } @@ -617,14 +619,14 @@ static jl_typemap_entry_t *jl_typemap_assoc_by_type_(jl_typemap_entry_t *ml, jl_ int jl_obviously_unequal(jl_value_t *a, jl_value_t *b); -static jl_typemap_entry_t *jl_typemap_lookup_by_type_(jl_typemap_entry_t *ml, jl_tupletype_t *types, +static jl_typemap_entry_t *jl_typemap_lookup_by_type_(jl_typemap_entry_t *ml, jl_value_t *types, size_t world, size_t max_world_mask) { for (; ml != (void*)jl_nothing; ml = ml->next) { if (world < ml->min_world || world > (ml->max_world | max_world_mask)) continue; // TODO: more efficient - jl_value_t *a = (jl_value_t*)types; + jl_value_t *a = types; jl_value_t *b = (jl_value_t*)ml->sig; while (jl_is_unionall(a)) a = ((jl_unionall_t*)a)->body; while (jl_is_unionall(b)) b = ((jl_unionall_t*)b)->body; @@ -651,7 +653,7 @@ static jl_typemap_entry_t *jl_typemap_lookup_by_type_(jl_typemap_entry_t *ml, jl // this is the general entry point for looking up a type in the cache // as a subtype, or with type_equal -jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_tupletype_t *types, jl_svec_t **penv, +jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_value_t *types, jl_svec_t **penv, int8_t subtype, int8_t offs, size_t world, size_t max_world_mask) { if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_level_type) { @@ -978,7 +980,7 @@ jl_typemap_entry_t *jl_typemap_insert(union jl_typemap_t *cache, jl_value_t *par jl_value_t *ttype = jl_unwrap_unionall((jl_value_t*)type); if ((jl_value_t*)simpletype == jl_nothing) { - jl_typemap_entry_t *ml = jl_typemap_assoc_by_type(*cache, type, NULL, 0, offs, min_world, 0); + jl_typemap_entry_t *ml = jl_typemap_assoc_by_type(*cache, (jl_value_t*)type, NULL, 0, offs, min_world, 0); if (ml && ml->simplesig == (void*)jl_nothing) { if (overwritten != NULL) *overwritten = ml->func.value; diff --git a/stdlib/Base64/test/runtests.jl b/stdlib/Base64/test/runtests.jl index 8eab331ee6b1b..405ccb830bb67 100644 --- a/stdlib/Base64/test/runtests.jl +++ b/stdlib/Base64/test/runtests.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random import Base64: Base64EncodePipe, base64encode, diff --git a/stdlib/CRC32c/test/runtests.jl b/stdlib/CRC32c/test/runtests.jl index 4f0fefe93c747..d672514496f18 100644 --- a/stdlib/CRC32c/test/runtests.jl +++ b/stdlib/CRC32c/test/runtests.jl @@ -1,4 +1,4 @@ -using Test +using Test, Random using CRC32c function test_crc32c(crc32c) @@ -60,4 +60,3 @@ end crc32c_sw(io::IO, crc::UInt32=0x00000000) = crc32c_sw(io, typemax(Int64), crc) test_crc32c(crc32c) test_crc32c(crc32c_sw) - diff --git a/stdlib/Dates/src/arithmetic.jl b/stdlib/Dates/src/arithmetic.jl index c1c1a623533b7..f1ca82e71c087 100644 --- a/stdlib/Dates/src/arithmetic.jl +++ b/stdlib/Dates/src/arithmetic.jl @@ -95,5 +95,5 @@ end (-)(y::T, x::AbstractArray{T}) where {T<:TimeType} = y .- x # AbstractArray{TimeType}, AbstractArray{TimeType} -(-)(x::OrdinalRange{T}, y::OrdinalRange{T}) where {T<:TimeType} = collect(x) - collect(y) -(-)(x::AbstractRange{T}, y::AbstractRange{T}) where {T<:TimeType} = collect(x) - collect(y) +(-)(x::OrdinalRange{T}, y::OrdinalRange{T}) where {T<:TimeType} = Vector(x) - Vector(y) +(-)(x::AbstractRange{T}, y::AbstractRange{T}) where {T<:TimeType} = Vector(x) - Vector(y) diff --git a/stdlib/Dates/src/parse.jl b/stdlib/Dates/src/parse.jl index 5f8698291ca36..1b0e4165394c0 100644 --- a/stdlib/Dates/src/parse.jl +++ b/stdlib/Dates/src/parse.jl @@ -16,7 +16,7 @@ function character_codes(directives::SimpleVector) return letters end -genvar(t::DataType) = Symbol(Base.Unicode.lowercase(string(Base.datatype_name(t)))) +genvar(t::DataType) = Symbol(lowercase(string(Base.datatype_name(t)))) """ tryparsenext_core(str::AbstractString, pos::Int, len::Int, df::DateFormat, raise=false) @@ -183,7 +183,7 @@ end max_pos = maxchars <= 0 ? len : min(len, nextind(str, i, maxchars-1)) @inbounds while i <= max_pos c, ii = next(str, i) - if Base.Unicode.isalpha(c) + if isalpha(c) word_end = i else break diff --git a/stdlib/Dates/src/periods.jl b/stdlib/Dates/src/periods.jl index 1a203ad3fbcde..946aee2fe5ef2 100644 --- a/stdlib/Dates/src/periods.jl +++ b/stdlib/Dates/src/periods.jl @@ -8,7 +8,7 @@ value(x::Period) = x.value # The following definitions are for Period-specific safety for period in (:Year, :Month, :Week, :Day, :Hour, :Minute, :Second, :Millisecond, :Microsecond, :Nanosecond) period_str = string(period) - accessor_str = Base.Unicode.lowercase(period_str) + accessor_str = lowercase(period_str) # Convenience method for show() @eval _units(x::$period) = " " * $accessor_str * (abs(value(x)) == 1 ? "" : "s") # periodisless diff --git a/stdlib/Dates/src/query.jl b/stdlib/Dates/src/query.jl index 801431329524b..88806673cc157 100644 --- a/stdlib/Dates/src/query.jl +++ b/stdlib/Dates/src/query.jl @@ -22,7 +22,7 @@ function locale_dict(names::Vector{<:AbstractString}) for i in 1:length(names) name = names[i] result[name] = i - result[Base.Unicode.lowercase(name)] = i + result[lowercase(name)] = i end return result end @@ -72,7 +72,7 @@ for (fn, field) in zip( # a case-sensitive lookup first value = get(locale.$field, word, 0) if value == 0 - value = get(locale.$field, Base.Unicode.lowercase(word), 0) + value = get(locale.$field, lowercase(word), 0) end value end diff --git a/stdlib/Dates/src/ranges.jl b/stdlib/Dates/src/ranges.jl index a6235c7755205..5fe51b298c0b7 100644 --- a/stdlib/Dates/src/ranges.jl +++ b/stdlib/Dates/src/ranges.jl @@ -40,5 +40,5 @@ Base.done(r::StepRange{<:TimeType,<:Period}, i::Integer) = length(r) <= i -(r::AbstractRange{<:TimeType}, x::Period) = (first(r)-x):step(r):(last(r)-x) # Combinations of types and periods for which the range step is regular -Base.TypeRangeStep(::Type{<:OrdinalRange{<:TimeType, <:FixedPeriod}}) = +Base.RangeStepStyle(::Type{<:OrdinalRange{<:TimeType, <:FixedPeriod}}) = Base.RangeStepRegular() diff --git a/stdlib/Dates/src/types.jl b/stdlib/Dates/src/types.jl index 9decf14ab581f..bb856d790baf0 100644 --- a/stdlib/Dates/src/types.jl +++ b/stdlib/Dates/src/types.jl @@ -356,5 +356,5 @@ sleep(time::Period) = sleep(toms(time) / 1000) Timer(time::Period, repeat::Period=Second(0)) = Timer(toms(time) / 1000, toms(repeat) / 1000) timedwait(testcb::Function, time::Period) = timedwait(testcb, toms(time) / 1000) -Base.TypeOrder(::Type{<:AbstractTime}) = Base.HasOrder() -Base.TypeArithmetic(::Type{<:AbstractTime}) = Base.ArithmeticOverflows() +Base.OrderStyle(::Type{<:AbstractTime}) = Base.Ordered() +Base.ArithmeticStyle(::Type{<:AbstractTime}) = Base.ArithmeticWraps() diff --git a/stdlib/Dates/test/io.jl b/stdlib/Dates/test/io.jl index 8ddf5367229de..ba30b84cd2005 100644 --- a/stdlib/Dates/test/io.jl +++ b/stdlib/Dates/test/io.jl @@ -297,7 +297,7 @@ end @test Dates.format(Dates.Date(2009, 12, 1), f) == "01Dec2009" f = "duy" globex = ["f", "g", "h", "j", "k", "m", "n", "q", "u", "v", "x", "z"] - locale = Dates.DateLocale(globex, map(Base.Unicode.uppercase, globex), globex[1:7], globex[1:7]) + locale = Dates.DateLocale(globex, map(uppercase, globex), globex[1:7], globex[1:7]) @test Dates.Date("1F4", f; locale=locale) + Dates.Year(2010) == Dates.Date(2014, 1, 1) @test Dates.format(Dates.Date(2014, 1, 1), f; locale=locale) == "1F4" diff --git a/stdlib/DelimitedFiles/src/DelimitedFiles.jl b/stdlib/DelimitedFiles/src/DelimitedFiles.jl index 714b02b4ee609..c8cf5c873f8fe 100644 --- a/stdlib/DelimitedFiles/src/DelimitedFiles.jl +++ b/stdlib/DelimitedFiles/src/DelimitedFiles.jl @@ -487,7 +487,7 @@ function val_opts(opts) for (opt_name, opt_val) in opts in(opt_name, valid_opts) || throw(ArgumentError("unknown option $opt_name")) - opt_typ = valid_opt_types[findfirst(equalto(opt_name), valid_opts)] + opt_typ = valid_opt_types[findfirst(equalto(opt_name), valid_opts)::Int] isa(opt_val, opt_typ) || throw(ArgumentError("$opt_name should be of type $opt_typ, got $(typeof(opt_val))")) d[opt_name] = opt_val diff --git a/stdlib/DelimitedFiles/test/runtests.jl b/stdlib/DelimitedFiles/test/runtests.jl index a1731ee1c82a3..de45de722028a 100644 --- a/stdlib/DelimitedFiles/test/runtests.jl +++ b/stdlib/DelimitedFiles/test/runtests.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random using DelimitedFiles isequaldlm(m1, m2, t) = isequal(m1, m2) && (eltype(m1) == eltype(m2) == t) diff --git a/stdlib/Distributed/src/Distributed.jl b/stdlib/Distributed/src/Distributed.jl index 31e2a8659dfbe..71fafdd7de280 100644 --- a/stdlib/Distributed/src/Distributed.jl +++ b/stdlib/Distributed/src/Distributed.jl @@ -17,7 +17,6 @@ using Base: Process, Semaphore, JLOptions, AnyDict, buffer_writes, wait_connecte binding_module, notify_error, atexit, julia_exename, julia_cmd, AsyncGenerator, acquire, release, invokelatest, shell_escape_posixly, uv_error, coalesce, notnothing -using Base.Unicode: isdigit, isnumeric # NOTE: clusterserialize.jl imports additional symbols from Base.Serializer for use diff --git a/stdlib/Distributed/src/cluster.jl b/stdlib/Distributed/src/cluster.jl index fea3fb1ea3496..12727f0584ac4 100644 --- a/stdlib/Distributed/src/cluster.jl +++ b/stdlib/Distributed/src/cluster.jl @@ -1106,6 +1106,8 @@ function init_bind_addr() LPROC.bind_port = UInt16(bind_port) end +using Random: randstring + function init_parallel() start_gc_msgs_task() atexit(terminate_all_workers) diff --git a/stdlib/Distributed/src/precompile.jl b/stdlib/Distributed/src/precompile.jl index bfbb73653f587..9f0bdca57eced 100644 --- a/stdlib/Distributed/src/precompile.jl +++ b/stdlib/Distributed/src/precompile.jl @@ -58,9 +58,6 @@ precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{Core precompile(Tuple{Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}, Type{Core.Inference.Const}, Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{typeof(Core.Inference.convert), Type{Tuple{Int64, typeof(Distributed.rmprocs)}}, Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{typeof(Core.Inference.collect), Type{Any}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{Int64, typeof(Distributed.rmprocs)}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{Int64, typeof(Distributed.rmprocs)}}) @@ -87,7 +84,6 @@ precompile(Tuple{typeof(Base.ht_keyindex), Base.Dict{Any, Any}, Distributed.RRID precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{QuoteNode}, Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}, Type{QuoteNode}, Tuple{Int64, typeof(Distributed.rmprocs)}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}) precompile(Tuple{typeof(Core.Inference.copyto!), Array{Any, 1}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}) @@ -148,9 +144,6 @@ precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{Core precompile(Tuple{Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}, Type{Core.Inference.Const}, Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{typeof(Core.Inference.convert), Type{Tuple{Int64, typeof(Distributed.rmprocs)}}, Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{typeof(Core.Inference.collect), Type{Any}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Tuple{Int64, typeof(Distributed.rmprocs)}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{Core.Inference.Const}}}) precompile(Tuple{typeof(Core.Inference.length), Tuple{Int64, typeof(Distributed.rmprocs)}}) @@ -174,7 +167,6 @@ precompile(Tuple{typeof(Base.Serializer.deserialize_expr), Distributed.ClusterSe precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{Type{Core.Inference.Generator{I, F} where F where I}, Type{QuoteNode}, Tuple{Int64, typeof(Distributed.rmprocs)}}) precompile(Tuple{Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}, Type{QuoteNode}, Tuple{Int64, typeof(Distributed.rmprocs)}}) -precompile(Tuple{typeof(Core.Inference.iteratorsize), Type{Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}}) precompile(Tuple{typeof(Core.Inference._collect), Type{Any}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}, Core.Inference.HasLength}) precompile(Tuple{typeof(Core.Inference.length), Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}) precompile(Tuple{typeof(Core.Inference.copyto!), Array{Any, 1}, Core.Inference.Generator{Tuple{Int64, typeof(Distributed.rmprocs)}, Type{QuoteNode}}}) diff --git a/stdlib/Distributed/test/distributed_exec.jl b/stdlib/Distributed/test/distributed_exec.jl index 8365d4ff904af..622eea4090784 100644 --- a/stdlib/Distributed/test/distributed_exec.jl +++ b/stdlib/Distributed/test/distributed_exec.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test, Distributed +using Test, Distributed, Random import Distributed: launch, manage include(joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testenv.jl")) @@ -18,7 +18,7 @@ include(joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testenv.jl")) addprocs_with_testenv(4) @test nprocs() == 5 -@everywhere using Test +@everywhere using Test, Random id_me = myid() id_other = filter(x -> x != id_me, procs())[rand(1:(nprocs()-1))] @@ -532,7 +532,6 @@ generic_map_tests(pmap_fallback) # pmap with various types. Test for equivalence with map run_map_equivalence_tests(pmap) -using Base.Unicode: uppercase @test pmap(uppercase, "Hello World!") == map(uppercase, "Hello World!") @@ -1499,4 +1498,3 @@ end # cluster at any time only supports a single topology. rmprocs(workers()) include("topology.jl") - diff --git a/stdlib/Distributed/test/topology.jl b/stdlib/Distributed/test/topology.jl index 32b868e5e1d81..2a659931ed306 100644 --- a/stdlib/Distributed/test/topology.jl +++ b/stdlib/Distributed/test/topology.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + pids = addprocs_with_testenv(4; topology="master_worker") let p1 = pids[1], p2 = pids[2] @@ -51,7 +53,7 @@ function launch(manager::TopoTestManager, params::Dict, launched::Array, c::Cond wconfig.process = io wconfig.io = io.out wconfig.ident = i - wconfig.connect_idents = collect(i+2:2:manager.np) + wconfig.connect_idents = Vector(i+2:2:manager.np) push!(launched, wconfig) end diff --git a/stdlib/Future/src/Future.jl b/stdlib/Future/src/Future.jl index 2a96ab53bbce2..1f4f8d98b8ed1 100644 --- a/stdlib/Future/src/Future.jl +++ b/stdlib/Future/src/Future.jl @@ -4,6 +4,8 @@ which will replace the current version in a future release of Julia." module Future +using Random + ## copy! """ @@ -24,4 +26,19 @@ function copy!(dst::AbstractArray, src::AbstractArray) copyto!(dst, src) end + +## randjump + +""" + randjump(r::MersenneTwister, steps::Integer) -> MersenneTwister + +Create an initialized `MersenneTwister` object, whose state is moved forward +(without generating numbers) from `r` by `steps` steps. +One such step corresponds to the generation of two `Float64` numbers. +For each different value of `steps`, a large polynomial has to be generated internally. +One is already pre-computed for `steps=big(10)^20`. +""" +randjump(r::MersenneTwister, steps::Integer) = + Random._randjump(r, Random.dSFMT.calc_jump(steps)) + end # module Future diff --git a/stdlib/Future/test/runtests.jl b/stdlib/Future/test/runtests.jl index 4233dc0fad0bd..820f4bdd3cedd 100644 --- a/stdlib/Future/test/runtests.jl +++ b/stdlib/Future/test/runtests.jl @@ -2,6 +2,7 @@ using Test using Future +using SparseArrays @testset "Future.copy! for AbstractSet" begin for S = (Set, BitSet) diff --git a/stdlib/IterativeEigensolvers/src/IterativeEigensolvers.jl b/stdlib/IterativeEigensolvers/src/IterativeEigensolvers.jl index ec9d6309154d2..6bee43e55d1ab 100644 --- a/stdlib/IterativeEigensolvers/src/IterativeEigensolvers.jl +++ b/stdlib/IterativeEigensolvers/src/IterativeEigensolvers.jl @@ -7,7 +7,7 @@ Arnoldi and Lanczos iteration for computing eigenvalues """ module IterativeEigensolvers -using Base.LinAlg: BlasFloat, BlasInt, SVD, checksquare, mul!, Adjoint, Transpose +using Base.LinAlg: BlasFloat, BlasInt, SVD, checksquare, mul! export eigs, svds @@ -208,7 +208,7 @@ end function Base.LinAlg.mul!(y::StridedVector{T}, A::SVDAugmented{T}, x::StridedVector{T}) where T m, mn = size(A.X, 1), length(x) mul!( view(y, 1:m), A.X, view(x, m + 1:mn)) # left singular vector - mul!(view(y, m + 1:mn), Adjoint(A.X), view(x, 1:m)) # right singular vector + mul!(view(y, m + 1:mn), adjoint(A.X), view(x, 1:m)) # right singular vector return y end Base.size(A::SVDAugmented) = ((+)(size(A.X)...), (+)(size(A.X)...)) @@ -228,9 +228,9 @@ end function Base.LinAlg.mul!(y::StridedVector{T}, A::AtA_or_AAt{T}, x::StridedVector{T}) where T if size(A.A, 1) >= size(A.A, 2) mul!(A.buffer, A.A, x) - return mul!(y, Adjoint(A.A), A.buffer) + return mul!(y, adjoint(A.A), A.buffer) else - mul!(A.buffer, Adjoint(A.A), x) + mul!(A.buffer, adjoint(A.A), x) return mul!(y, A.A, A.buffer) end end @@ -321,7 +321,7 @@ function _svds(X; nsv::Int = 6, ritzvec::Bool = true, tol::Float64 = 0.0, maxite end # right_sv = sqrt(2) * ex[2][ size(X,1)+1:end, ind ] - return (SVD(U, svals, adjoint(V)), ex[3], ex[4], ex[5], ex[6]) + return (SVD(U, svals, copy(V')), ex[3], ex[4], ex[5], ex[6]) else #The sort is necessary to work around #10329 return (SVD(zeros(eltype(svals), n, 0), diff --git a/stdlib/IterativeEigensolvers/test/runtests.jl b/stdlib/IterativeEigensolvers/test/runtests.jl index a8782939da55c..c61d875aeadb4 100644 --- a/stdlib/IterativeEigensolvers/test/runtests.jl +++ b/stdlib/IterativeEigensolvers/test/runtests.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using IterativeEigensolvers -using Test +using Test, SparseArrays, Random @testset "eigs" begin srand(1234) @@ -23,11 +23,11 @@ using Test end a_evs = eigvals(Array(a)) a = convert(SparseMatrixCSC{elty}, a) - asym = adjoint(a) + a # symmetric indefinite + asym = copy(a') + a # symmetric indefinite apd = a'*a # symmetric positive-definite b = convert(SparseMatrixCSC{elty}, b) - bsym = adjoint(b) + b + bsym = copy(b') + b bpd = b'*b (d,v) = eigs(a, nev=3) @@ -88,8 +88,8 @@ using Test @test_throws DimensionMismatch eigs(a, v0=zeros(elty,n+2)) @test_throws ArgumentError eigs(a, v0=zeros(Int,n)) if elty == Float64 - @test_throws ArgumentError eigs(a + transpose(a), which=:SI) - @test_throws ArgumentError eigs(a + transpose(a), which=:LI) + @test_throws ArgumentError eigs(a + copy(transpose(a)), which=:SI) + @test_throws ArgumentError eigs(a + copy(transpose(a)), which=:LI) @test_throws ArgumentError eigs(a, sigma = rand(ComplexF32)) end end @@ -167,7 +167,7 @@ let v = real(v) # @test vecnorm(v-v')/2 ≈ 0. # it should be Hermitian # Since this fails sometimes (numerical precision error),this test is commented out - v = (v+adjoint(v))/2 + v = (v + v')/2 @test isposdef(v) # Repeat with starting vector diff --git a/stdlib/Libdl/docs/src/index.md b/stdlib/Libdl/docs/src/index.md new file mode 100644 index 0000000000000..c25ad8c44fd21 --- /dev/null +++ b/stdlib/Libdl/docs/src/index.md @@ -0,0 +1,13 @@ +# Dynamic Linker + +```@docs +Libdl.dlopen +Libdl.dlopen_e +Libdl.RTLD_NOW +Libdl.dlsym +Libdl.dlsym_e +Libdl.dlclose +Libdl.dlext +Libdl.find_library +Libdl.DL_LOAD_PATH +``` diff --git a/base/libdl.jl b/stdlib/Libdl/src/Libdl.jl similarity index 98% rename from base/libdl.jl rename to stdlib/Libdl/src/Libdl.jl index ff2d05bfa0a6b..917269a37a64d 100644 --- a/base/libdl.jl +++ b/stdlib/Libdl/src/Libdl.jl @@ -1,10 +1,14 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +__precompile__(true) + module Libdl @doc """ Interface to libdl. Provides dynamic linking support. """ -> Libdl +import Base.DL_LOAD_PATH + export DL_LOAD_PATH, RTLD_DEEPBIND, RTLD_FIRST, RTLD_GLOBAL, RTLD_LAZY, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_NOW, dlclose, dlopen, dlopen_e, dlsym, dlsym_e, dlpath, find_library, dlext, dllist @@ -15,11 +19,7 @@ export DL_LOAD_PATH, RTLD_DEEPBIND, RTLD_FIRST, RTLD_GLOBAL, RTLD_LAZY, RTLD_LOC When calling [`dlopen`](@ref), the paths in this list will be searched first, in order, before searching the system locations for a valid library handle. """ -const DL_LOAD_PATH = String[] -if Sys.isapple() - push!(DL_LOAD_PATH, "@loader_path/julia") - push!(DL_LOAD_PATH, "@loader_path") -end +DL_LOAD_PATH # note: constants to match JL_RTLD_* in src/julia.h, translated # to system-specific values by JL_RTLD macro in src/dlload.c @@ -47,7 +47,6 @@ applicable. """ -> (RTLD_DEEPBIND, RTLD_FIRST, RTLD_GLOBAL, RTLD_LAZY, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_NOW) - """ dlsym(handle, sym) diff --git a/test/libdl.jl b/stdlib/Libdl/test/runtests.jl similarity index 99% rename from test/libdl.jl rename to stdlib/Libdl/test/runtests.jl index af2b396b92421..c2e410f25c86f 100644 --- a/test/libdl.jl +++ b/stdlib/Libdl/test/runtests.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +import Libdl + # these could fail on an embedded installation # but for now, we don't handle that case dlls = Libdl.dllist() diff --git a/stdlib/Logging/docs/src/index.md b/stdlib/Logging/docs/src/index.md deleted file mode 100644 index 091eef4035b11..0000000000000 --- a/stdlib/Logging/docs/src/index.md +++ /dev/null @@ -1,2 +0,0 @@ -# Logging - diff --git a/stdlib/Logging/src/ConsoleLogger.jl b/stdlib/Logging/src/ConsoleLogger.jl new file mode 100644 index 0000000000000..0cd6a6ce63370 --- /dev/null +++ b/stdlib/Logging/src/ConsoleLogger.jl @@ -0,0 +1,156 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +""" + ConsoleLogger(stream=STDERR, min_level=Info; meta_formatter=default_metafmt, + show_limited=true, right_justify=0) + +Logger with formatting optimized for readability in a text console, for example +interactive work with the Julia REPL. + +Log levels less than `min_level` are filtered out. + +Message formatting can be controlled by setting keyword arguments: + +* `meta_formatter` is a function which takes the log event metadata + `(level, _module, group, id, file, line)` and returns a color (as would be + passed to print_with_color), prefix and suffix for the log message. The + default is to prefix with the log level and a suffix containing the module, + file and line location. +* `show_limited` limits the printing of large data structures to something + which can fit on the screen by setting the `:limit` `IOContext` key during + formatting. +* `right_justify` is the integer column which log metadata is right justified + at. The default is zero (metadata goes on its own line). +""" +struct ConsoleLogger <: AbstractLogger + stream::IO + min_level::LogLevel + meta_formatter + show_limited::Bool + right_justify::Int + message_limits::Dict{Any,Int} +end +function ConsoleLogger(stream::IO=STDERR, min_level=Info; + meta_formatter=default_metafmt, show_limited=true, + right_justify=0) + ConsoleLogger(stream, min_level, meta_formatter, + show_limited, right_justify, Dict{Any,Int}()) +end + +shouldlog(logger::ConsoleLogger, level, _module, group, id) = + get(logger.message_limits, id, 1) > 0 + +min_enabled_level(logger::ConsoleLogger) = logger.min_level + +# Formatting of values in key value pairs +showvalue(io, msg) = show(io, "text/plain", msg) +function showvalue(io, e::Tuple{Exception,Any}) + ex,bt = e + showerror(io, ex, bt; backtrace = bt!=nothing) +end +showvalue(io, ex::Exception) = showvalue(io, (ex,catch_backtrace())) + +function default_logcolor(level) + level < Info ? Base.debug_color() : + level < Warn ? Base.info_color() : + level < Error ? Base.warn_color() : + Base.error_color() +end + +function default_metafmt(level, _module, group, id, file, line) + color = default_logcolor(level) + prefix = (level == Warn ? "Warning" : string(level))*':' + suffix = (Info <= level < Warn) ? "" : "@ $_module $(basename(file)):$line" + color,prefix,suffix +end + +# Length of a string as it will appear in the terminal (after ANSI color codes +# are removed) +function termlength(str) + N = 0 + in_esc = false + for c in str + if in_esc + if c == 'm' + in_esc = false + end + else + if c == '\e' + in_esc = true + else + N += 1 + end + end + end + return N +end + +function handle_message(logger::ConsoleLogger, level, message, _module, group, id, + filepath, line; maxlog=nothing, kwargs...) + if maxlog != nothing && maxlog isa Integer + remaining = get!(logger.message_limits, id, maxlog) + logger.message_limits[id] = remaining - 1 + remaining > 0 || return + end + + # Generate a text representation of the message and all key value pairs, + # split into lines. + msglines = [(indent=0,msg=l) for l in split(chomp(string(message)), '\n')] + dsize = displaysize(logger.stream) + if !isempty(kwargs) + valbuf = IOBuffer() + rows_per_value = max(1, dsize[1]÷(length(kwargs)+1)) + valio = IOContext(IOContext(valbuf, logger.stream), + :displaysize=>(rows_per_value,dsize[2]-5)) + if logger.show_limited + valio = IOContext(valio, :limit=>true) + end + for (key,val) in pairs(kwargs) + showvalue(valio, val) + vallines = split(String(take!(valbuf)), '\n') + if length(vallines) == 1 + push!(msglines, (indent=2,msg=SubString("$key = $(vallines[1])"))) + else + push!(msglines, (indent=2,msg=SubString("$key ="))) + append!(msglines, ((indent=3,msg=line) for line in vallines)) + end + end + end + + # Format lines as text with appropriate indentation and with a box + # decoration on the left. + color,prefix,suffix = logger.meta_formatter(level, _module, group, id, filepath, line) + minsuffixpad = 2 + buf = IOBuffer() + iob = IOContext(buf, logger.stream) + nonpadwidth = 2 + (isempty(prefix) || length(msglines) > 1 ? 0 : length(prefix)+1) + + msglines[end].indent + termlength(msglines[end].msg) + + (isempty(suffix) ? 0 : length(suffix)+minsuffixpad) + justify_width = min(logger.right_justify, dsize[2]) + if nonpadwidth > justify_width && !isempty(suffix) + push!(msglines, (indent=0,msg=SubString(""))) + minsuffixpad = 0 + nonpadwidth = 2 + length(suffix) + end + for (i,(indent,msg)) in enumerate(msglines) + boxstr = length(msglines) == 1 ? "[ " : + i == 1 ? "┌ " : + i < length(msglines) ? "│ " : + "└ " + print_with_color(color, iob, boxstr, bold=true) + if i == 1 && !isempty(prefix) + print_with_color(color, iob, prefix, " ", bold=true) + end + print(iob, " "^indent, msg) + if i == length(msglines) && !isempty(suffix) + npad = max(0, justify_width - nonpadwidth) + minsuffixpad + print(iob, " "^npad) + print_with_color(:light_black, iob, suffix) + end + println(iob) + end + + write(logger.stream, take!(buf)) + nothing +end + diff --git a/stdlib/Logging/src/Logging.jl b/stdlib/Logging/src/Logging.jl index 00aef043ece1a..8e38277bd513c 100644 --- a/stdlib/Logging/src/Logging.jl +++ b/stdlib/Logging/src/Logging.jl @@ -39,7 +39,10 @@ export current_logger, global_logger, disable_logging, - SimpleLogger + SimpleLogger, + ConsoleLogger + +include("ConsoleLogger.jl") # The following are also part of the public API, but not exported: # diff --git a/stdlib/Logging/test/runtests.jl b/stdlib/Logging/test/runtests.jl index 1cf40077a1476..8419527be6c53 100644 --- a/stdlib/Logging/test/runtests.jl +++ b/stdlib/Logging/test/runtests.jl @@ -1 +1,219 @@ -# TODO: Move SimpleLogger in here +using Logging + +import Logging: min_enabled_level, shouldlog, handle_message + +@noinline func1() = backtrace() + +@testset "Logging" begin + +@testset "ConsoleLogger" begin + # First pass log limiting + @test min_enabled_level(ConsoleLogger(DevNull, Logging.Debug)) == Logging.Debug + @test min_enabled_level(ConsoleLogger(DevNull, Logging.Error)) == Logging.Error + + # Second pass log limiting + logger = ConsoleLogger(DevNull) + @test shouldlog(logger, Logging.Info, Base, :group, :asdf) === true + handle_message(logger, Logging.Info, "msg", Base, :group, :asdf, "somefile", 1, maxlog=2) + @test shouldlog(logger, Logging.Info, Base, :group, :asdf) === true + handle_message(logger, Logging.Info, "msg", Base, :group, :asdf, "somefile", 1, maxlog=2) + @test shouldlog(logger, Logging.Info, Base, :group, :asdf) === false + + @testset "Default metadata formatting" begin + @test Logging.default_metafmt(Logging.Debug, Base, :g, :i, "path/to/somefile.jl", 42) == + (:blue, "Debug:", "@ Base somefile.jl:42") + @test Logging.default_metafmt(Logging.Info, Main, :g, :i, "a.jl", 1) == + (:cyan, "Info:", "") + @test Logging.default_metafmt(Logging.Warn, Main, :g, :i, "b.jl", 2) == + (:yellow, "Warning:", "@ Main b.jl:2") + @test Logging.default_metafmt(Logging.Error, Main, :g, :i, "", 0) == + (:light_red, "Error:", "@ Main :0") + end + + function dummy_metafmt(level, _module, group, id, file, line) + :cyan,"PREFIX","SUFFIX" + end + + # Log formatting + function genmsg(message; level=Logging.Info, _module=Main, + file="some/path.jl", line=101, color=false, width=75, + meta_formatter=dummy_metafmt, show_limited=true, + right_justify=0, kws...) + buf = IOBuffer() + io = IOContext(buf, :displaysize=>(30,width), :color=>color) + logger = ConsoleLogger(io, Logging.Debug, + meta_formatter=meta_formatter, + show_limited=show_limited, + right_justify=right_justify) + Logging.handle_message(logger, level, message, _module, :a_group, :an_id, + file, line; kws...) + String(take!(buf)) + end + + # Basic tests for the default setup + @test genmsg("msg", level=Logging.Info, meta_formatter=Logging.default_metafmt) == + """ + [ Info: msg + """ + @test genmsg("line1\nline2", level=Logging.Warn, _module=Base, + file="other.jl", line=42, meta_formatter=Logging.default_metafmt) == + """ + ┌ Warning: line1 + │ line2 + └ @ Base other.jl:42 + """ + # Full metadata formatting + @test genmsg("msg", level=Logging.Debug, + meta_formatter=(level, _module, group, id, file, line)-> + (:white,"Foo!", "$level $_module $group $id $file $line")) == + """ + ┌ Foo! msg + └ Debug Main a_group an_id some/path.jl 101 + """ + + @testset "Prefix and suffix layout" begin + @test genmsg("") == + replace(""" + ┌ PREFIX EOL + └ SUFFIX + """, "EOL"=>"") + @test genmsg("msg") == + """ + ┌ PREFIX msg + └ SUFFIX + """ + # Behavior with empty prefix / suffix + @test genmsg("msg", meta_formatter=(args...)->(:white, "PREFIX", "")) == + """ + [ PREFIX msg + """ + @test genmsg("msg", meta_formatter=(args...)->(:white, "", "SUFFIX")) == + """ + ┌ msg + └ SUFFIX + """ + end + + @testset "Metadata suffix, right justification" begin + @test genmsg("xxx", width=20, right_justify=200) == + """ + [ PREFIX xxx SUFFIX + """ + @test genmsg("xxx\nxxx", width=20, right_justify=200) == + """ + ┌ PREFIX xxx + └ xxx SUFFIX + """ + # When adding the suffix would overflow the display width, add it on + # the next line: + @test genmsg("xxxx", width=20, right_justify=200) == + """ + ┌ PREFIX xxxx + └ SUFFIX + """ + # Same for multiline messages + @test genmsg("""xxx + xxxxxxxxxx""", width=20, right_justify=200) == + """ + ┌ PREFIX xxx + └ xxxxxxxxxx SUFFIX + """ + @test genmsg("""xxx + xxxxxxxxxxx""", width=20, right_justify=200) == + """ + ┌ PREFIX xxx + │ xxxxxxxxxxx + └ SUFFIX + """ + # min(right_justify,width) is used + @test genmsg("xxx", width=200, right_justify=20) == + """ + [ PREFIX xxx SUFFIX + """ + @test genmsg("xxxx", width=200, right_justify=20) == + """ + ┌ PREFIX xxxx + └ SUFFIX + """ + end + + # Keywords + @test genmsg("msg", a=1, b="asdf") == + """ + ┌ PREFIX msg + │ a = 1 + │ b = "asdf" + └ SUFFIX + """ + # Exceptions shown with showerror + @test genmsg("msg", exception=DivideError()) == + """ + ┌ PREFIX msg + │ exception = DivideError: integer division error + └ SUFFIX + """ + + # Attaching backtraces + bt = func1() + @test startswith(genmsg("msg", exception=(DivideError(),bt)), + """ + ┌ PREFIX msg + │ exception = + │ DivideError: integer division error + │ Stacktrace: + │ [1] func1() at""") + + + @testset "Limiting large data structures" begin + @test genmsg("msg", a=fill(1.00001, 100,100), b=fill(2.00002, 10,10)) == + replace(""" + ┌ PREFIX msg + │ a = + │ 100×100 Array{Float64,2}: + │ 1.00001 1.00001 1.00001 1.00001 … 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ ⋮ ⋱ EOL + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ b = + │ 10×10 Array{Float64,2}: + │ 2.00002 2.00002 2.00002 2.00002 … 2.00002 2.00002 2.00002 + │ 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 + │ 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 + │ ⋮ ⋱ EOL + │ 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 + │ 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 2.00002 + └ SUFFIX + """, "EOL"=>"") # EOL hack to work around git whitespace errors + # Limiting the amount which is printed + @test genmsg("msg", a=fill(1.00001, 10,10), show_limited=false) == + """ + ┌ PREFIX msg + │ a = + │ 10×10 Array{Float64,2}: + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + │ 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 1.00001 + └ SUFFIX + """ + end + + # Basic colorization test + @test genmsg("line1\nline2", color=true) == + """ + \e[36m\e[1m┌ \e[22m\e[39m\e[36m\e[1mPREFIX \e[22m\e[39mline1 + \e[36m\e[1m│ \e[22m\e[39mline2 + \e[36m\e[1m└ \e[22m\e[39m\e[90mSUFFIX\e[39m + """ + +end + +end diff --git a/stdlib/Mmap/test/runtests.jl b/stdlib/Mmap/test/runtests.jl index ee77f392f4c72..7ca20e7aa42b3 100644 --- a/stdlib/Mmap/test/runtests.jl +++ b/stdlib/Mmap/test/runtests.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test, Mmap +using Test, Mmap, Random file = tempname() write(file, "Hello World\n") diff --git a/stdlib/Printf/test/runtests.jl b/stdlib/Printf/test/runtests.jl index 8ee99220258f0..e51c3ee299126 100644 --- a/stdlib/Printf/test/runtests.jl +++ b/stdlib/Printf/test/runtests.jl @@ -2,9 +2,10 @@ using Test, Printf -macro test_throws(ty, ex) +# this macro tests for exceptions thrown at macro expansion +macro test_me(ty, ex) return quote - Test.@test_throws $(esc(ty)) try + @test_throws $(esc(ty)) try $(esc(ex)) catch err @test err isa LoadError @@ -204,14 +205,14 @@ end # escape % @test (@sprintf "%%") == "%" @test (@sprintf "%%s") == "%s" -@test_throws ArgumentError("invalid printf format string: \"%\"") @macroexpand(@sprintf "%") #" (fixes syntax highlighting) +@test_me ArgumentError("invalid printf format string: \"%\"") @macroexpand(@sprintf "%") #" (fixes syntax highlighting) # argument count -@test_throws ArgumentError("@sprintf: wrong number of arguments (0) should be (1)") @macroexpand(@sprintf "%s") -@test_throws ArgumentError("@sprintf: wrong number of arguments (2) should be (1)") @macroexpand(@sprintf "%s" "1" "2") +@test_me ArgumentError("@sprintf: wrong number of arguments (0) should be (1)") @macroexpand(@sprintf "%s") +@test_me ArgumentError("@sprintf: wrong number of arguments (2) should be (1)") @macroexpand(@sprintf "%s" "1" "2") # no interpolation -@test_throws ArgumentError("@sprintf: format must be a plain static string (no interpolation or prefix)") @macroexpand(@sprintf "$n") +@test_me ArgumentError("@sprintf: format must be a plain static string (no interpolation or prefix)") @macroexpand(@sprintf "$n") # type width specifier parsing (ignored) @test (@sprintf "%llf" 1.2) == "1.200000" @@ -257,7 +258,7 @@ end # invalid format specifiers, not "diouxXDOUeEfFgGaAcCsSpn" for c in "bBhHIjJkKlLmMNPqQrRtTvVwWyYzZ" fmt_str = string("%", c) - @test_throws ArgumentError("@sprintf: first argument must be a format string") @macroexpand(@sprintf $fmt_str 1) + @test_me ArgumentError("@sprintf: first argument must be a format string") @macroexpand(@sprintf $fmt_str 1) end # combo @@ -270,7 +271,7 @@ end @test (@sprintf "%s %s %s %d %d %d %f %f %f" Any[10^x+y for x=1:3,y=1:3 ]...) == "11 101 1001 12 102 1002 13.000000 103.000000 1003.000000" # @printf -@test_throws ArgumentError("@printf: first or second argument must be a format string") @macroexpand(@printf 1) +@test_me ArgumentError("@printf: first or second argument must be a format string") @macroexpand(@printf 1) # Check bug with trailing nul printing BigFloat @test (@sprintf("%.330f", BigFloat(1)))[end] != '\0' @@ -285,7 +286,12 @@ end @test (@sprintf("%d\u0f00%d", 1, 2)) == "1\u0f002" @test (@sprintf("%d\U0001ffff%d", 1, 2)) == "1\U0001ffff2" @test (@sprintf("%d\u2203%d\u0203", 1, 2)) == "1\u22032\u0203" -@test_throws ArgumentError @macroexpand(@sprintf("%y%d", 1, 2)) -@test_throws ArgumentError @macroexpand(@sprintf("%\u00d0%d", 1, 2)) -@test_throws ArgumentError @macroexpand(@sprintf("%\u0f00%d", 1, 2)) -@test_throws ArgumentError @macroexpand(@sprintf("%\U0001ffff%d", 1, 2)) +@test_me ArgumentError @macroexpand(@sprintf("%y%d", 1, 2)) +@test_me ArgumentError @macroexpand(@sprintf("%\u00d0%d", 1, 2)) +@test_me ArgumentError @macroexpand(@sprintf("%\u0f00%d", 1, 2)) +@test_me ArgumentError @macroexpand(@sprintf("%\U0001ffff%d", 1, 2)) + +# test at macro execution time +@test_throws ArgumentError("@sprintf: wrong number of arguments (2) should be (3)") (@sprintf "%d%d%d" 1:2...) + + diff --git a/stdlib/Random/docs/src/index.md b/stdlib/Random/docs/src/index.md new file mode 100644 index 0000000000000..0ef892b0a3a96 --- /dev/null +++ b/stdlib/Random/docs/src/index.md @@ -0,0 +1,43 @@ +# Random Numbers + +Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) +via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types +can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple +streams of random numbers. Besides `MersenneTwister`, Julia also provides the `RandomDevice` RNG +type, which is a wrapper over the OS provided entropy. + +Most functions related to random generation accept an optional `AbstractRNG` as the first argument, +`rng` , which defaults to the global one if not provided. Morever, some of them accept optionally +dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random +values. + +A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the following types: +[`Float16`](@ref), [`Float32`](@ref), [`Float64`](@ref), [`BigFloat`](@ref), [`Bool`](@ref), +[`Int8`](@ref), [`UInt8`](@ref), [`Int16`](@ref), [`UInt16`](@ref), [`Int32`](@ref), +[`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), +[`BigInt`](@ref) (or complex numbers of those types). +Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents +unbounded integers, the interval must be specified (e.g. `rand(big(1:6))`). + +```@docs +Random.srand +Random.MersenneTwister +Random.RandomDevice +Random.rand +Random.rand! +Random.bitrand +Random.randn +Random.randn! +Random.randexp +Random.randexp! +Random.randjump +Random.randstring +Random.randsubseq +Random.randsubseq! +Random.randperm +Random.randperm! +Random.randcycle +Random.randcycle! +Random.shuffle +Random.shuffle! +``` diff --git a/base/random/RNGs.jl b/stdlib/Random/src/RNGs.jl similarity index 94% rename from base/random/RNGs.jl rename to stdlib/Random/src/RNGs.jl index af4d093678e87..9c802bef750e8 100644 --- a/base/random/RNGs.jl +++ b/stdlib/Random/src/RNGs.jl @@ -27,6 +27,16 @@ else # !windows end rand(rd::RandomDevice, sp::SamplerBoolBitInteger) = read( rd.file, sp[]) + + function serialize(s::AbstractSerializer, rd::RandomDevice) + Serializer.serialize_type(s, typeof(rd)) + serialize(s, rd.unlimited) + end + function deserialize(s::AbstractSerializer, t::Type{RandomDevice}) + unlimited = deserialize(s) + return RandomDevice(unlimited) + end + end # os-test # NOTE: this can't be put within the if-else block above @@ -536,34 +546,29 @@ end ### randjump """ - randjump(r::MersenneTwister, jumps, steps=10^20) -> Vector{MersenneTwister} + randjump(r::MersenneTwister, steps::Integer, len::Integer) -> Vector{MersenneTwister} -Create an array of size `jumps` of initialized `MersenneTwister` RNG objects. The +Create an array of size `len` of initialized `MersenneTwister` RNG objects. The first RNG object given as a parameter and following `MersenneTwister` RNGs in the array are initialized such that a state of the RNG object in the array would be moved forward (without generating numbers) from a previous RNG object array element by `steps` steps. One such step corresponds to the generation of two `Float64` numbers. +For each different value of `steps`, a large polynomial has to be generated internally. +One is already pre-computed for `steps=big(10)^20`. """ -randjump(r::MersenneTwister, jumps::Integer, steps::Integer=big(10)^20) = - randjump(r, jumps, dSFMT.calc_jump(steps)) +randjump(r::MersenneTwister, steps::Integer, len::Integer) = + _randjump(r, dSFMT.calc_jump(steps), len) -""" - randjump(r::MersenneTwister, jumps, jumppoly::AbstractString) -> Vector{MersenneTwister} -Similar to `randjump(r, jumps, steps)` where the number of steps is -determined by a jump polynomial `jumppoly` with coefficients in -``GF(2)`` (the field with two elements) encoded as an hexadecimal -string. -""" -randjump(mt::MersenneTwister, jumps::Integer, jumppoly::AbstractString) = - randjump(mt, jumps, dSFMT.GF2X(jumppoly)) +_randjump(r::MersenneTwister, jumppoly::dSFMT.GF2X) = + MersenneTwister(copy(r.seed), dSFMT.dsfmt_jump(r.state, jumppoly)) -function randjump(mt::MersenneTwister, jumps::Integer, jumppoly::dSFMT.GF2X) +function _randjump(mt::MersenneTwister, jumppoly::dSFMT.GF2X, len::Integer) mts = MersenneTwister[] push!(mts, mt) - for i in 1:jumps-1 + for i in 1:len-1 cmt = mts[end] - push!(mts, MersenneTwister(copy(cmt.seed), dSFMT.dsfmt_jump(cmt.state, jumppoly))) + push!(mts, _randjump(cmt, jumppoly)) end return mts end diff --git a/base/random/random.jl b/stdlib/Random/src/Random.jl similarity index 95% rename from base/random/random.jl rename to stdlib/Random/src/Random.jl index fcbe1fe8b659a..20ea4f923c472 100644 --- a/base/random/random.jl +++ b/stdlib/Random/src/Random.jl @@ -1,17 +1,22 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +__precompile__(true) + module Random -using Base.dSFMT +include("dSFMT.jl") + +using .dSFMT using Base.GMP.MPZ using Base.GMP: Limb + using Base: BitInteger, BitInteger_types, BitUnsigned, @gc_preserve -import Base: copymutable, copy, copy!, ==, hash +import Base: copymutable, copy, copy!, ==, hash, serialize, deserialize, convert +import Base: rand, randn export srand, - rand, rand!, - randn, randn!, + rand!, randn!, randexp, randexp!, bitrand, randstring, @@ -20,13 +25,15 @@ export srand, randperm, randperm!, randcycle, randcycle!, AbstractRNG, MersenneTwister, RandomDevice, - GLOBAL_RNG, randjump + defaultRNG, randjump ## general definitions abstract type AbstractRNG end +defaultRNG() = GLOBAL_RNG + ### integers @@ -65,6 +72,7 @@ for UI = (:UInt10, :UInt10Raw, :UInt23, :UInt23Raw, :UInt52, :UInt52Raw, end end + ### floats abstract type FloatInterval{T<:AbstractFloat} end @@ -212,10 +220,8 @@ function rand!(rng::AbstractRNG, A::AbstractArray{T}, sp::Sampler) where T A end -rand(r::AbstractRNG, dims::Dims) = rand(r, Float64, dims) -rand( dims::Dims) = rand(GLOBAL_RNG, dims) -rand(r::AbstractRNG, dims::Integer...) = rand(r, Dims(dims)) -rand( dims::Integer...) = rand(Dims(dims)) +rand(r::AbstractRNG, dims::Integer...) = rand(r, Float64, Dims(dims)) +rand( dims::Integer...) = rand(Float64, Dims(dims)) rand(r::AbstractRNG, X, dims::Dims) = rand!(r, Array{eltype(X)}(uninitialized, dims), X) rand( X, dims::Dims) = rand(GLOBAL_RNG, X, dims) @@ -248,7 +254,7 @@ include("RNGs.jl") include("generation.jl") include("normal.jl") include("misc.jl") - +include("deprecated.jl") ## rand & rand! & srand docstrings @@ -265,7 +271,8 @@ Pick a random element or array of random elements from the set of values specifi integers (this is not applicable to [`BigInt`](@ref)), and to ``[0, 1)`` for floating point numbers; -`S` defaults to [`Float64`](@ref). +`S` defaults to [`Float64`](@ref) +(except when `dims` is a tuple of integers, in which case `S` must be specified). # Examples ```julia-repl diff --git a/base/random/dSFMT.jl b/stdlib/Random/src/dSFMT.jl similarity index 99% rename from base/random/dSFMT.jl rename to stdlib/Random/src/dSFMT.jl index 70514a7284113..e500667687bd8 100644 --- a/base/random/dSFMT.jl +++ b/stdlib/Random/src/dSFMT.jl @@ -159,7 +159,10 @@ const JumpPolys = Dict{BigInt,GF2X}() const CharPoly = Ref{GF2X}() # Ref because it can not be initialized at compile time -__init__() = CharPoly[] = GF2X(Poly19937) +function __init__() + CharPoly[] = GF2X(Poly19937) + JumpPolys[big(10)^20] = GF2X(JPOLY1e20) +end """ calc_jump(steps::Integer) @@ -252,7 +255,7 @@ function dsfmt_jump_next_state!(mts::Vector{UInt64}) end "Jump polynomial for 10^20 steps for dSFMT with exponent 19937" -const JPOLY1e21 = "e172e20c5d2de26b567c0cace9e7c6cc4407bd5ffcd22ca59d37b73d54fdbd937cd3abc6f502e8c186dbd4f1a06b9e2b894f31be77424f94dddfd5a45888a84ca66eeeb242eefe6764ed859dafccae7a6a635b3a63fe9dfbbd5f2d3f2610d39388f53060e84edae75be4f4f2272c0f1f26d1231836ad040ab091550f8a3a5423fb3ab83e068fe2684057f15691c4dc757a3aee4bca8595bf1ad03500d9620a5dbe3b2d64380694895d2f379ca928238293ea267ce14236d5be816a61f018fe4f6bc3c9865f5d4d4186e320ab653d1f3c035ae83e2ad725648a67d3480331e763a1dcdfb5711b56796170b124f5febd723a664a2deefbfa9999d922a108b0e683582ae8d3baacb5bb56683405ea9e6e0d71ddb24b2229c72bb9d07061f2d1fa097ade823b607a2029d6e121ae09d93de01a154199e8e6a6e77c970bda72ba8079b2b3a15dd494a3188b1d94a25ae108a8a5bd0b050e6ce64a365a21420e07fdeebecae02eb68a4304b59283055d22c27d680ea35952834d828c9b9b9dd1a886b4f7fe82fe8f2a962e1e5390e563dc281c799aee2a441b7a813facb6ff5e94c059710dcfe7e6b1635e21ae0dc878dd5f7cc0e1101a74452495a67d23a2672c939f32c81d4a2611073990e92a084cc3a62fd42ee566f29d963a9cc5100ccd0a200f49ce0a74fa891efa1b974d342b7fedf9269e40d9b34e3c59c3d37201aecd5a04f4ae3d0c9a68c7ab78c662390e4cf36cb63ea3539c442efd0bf4aace4b8c8bde93c3d84b4d6290adfae1c5e3fcd457b6f3159e501f17b72ff6bc13d6bf61fbdafabefd16ac1dae0bca667e4e16a2b800732f1d0a9274c8a4c6cccd2db62fc275dc308c31c11cd6fda78de2f81f0e542b76b42b2cc09ed8f965d94c714c9918064f53af5379cfbbc31edf9cbce694f63a75f122048de6e57b094908f749661456813a908027f5d8397ab7962bf75ac779a3e1b7ae3fbc93397a67b486bb849befff1de6162ef2819715a88f41881e366ace692a900796a2806393898dd1750ac2b4ca3d34ca48942322fb6375f0c9a00c9701048ee8d7d7a17e11739177a7ad5027556e85835daf8594d84a97fe6621c0fce1495ae6ab8676cdc992d247acf5a4e5ec8c4755fde28117228d2c3ecf89edb91e93d949e2174924572265e36d176d082ed1be884e51d885ba3cda175c51edcee5042eaf519d292aa05aa4185b03858d710a9d0880b3d4e5111f858a52fe352cbe0a24f06a3d977ae2eb85e2a03a68131d0ab91dac4941067cf90ecd0fce156bcd40b8968cd4aa11e0b4353b14508d79d13ac00af4a4d452496b7f2393699889aa1e508427dbf0be3db91d955feb51e559af57640c6b3f9d5f95609852c28f9462a9869dd93acbdb1aafb2381ebb886a0b3fcec278f8bb0f62c23e157e49b89245b0881268ce594acbddd3605b9eaa77c9ff513e0dbad514914136d96fe2843fe2b4e886a0b718a9b8d1132132110618d0d3595da284cd2a4c9d09386199e4f4d7723983d3a374b51cf20dac5cabb4ff7e7197c2ebd9318463409baa583d6a6115c1b768282ff37b0fe152c97671e400d5ccba7d6875df0bf95c5d91257fedb124de393f31908d0e36251326aa29dd5be86291c80b4bf78f419ec151eeaeff643a58b48ab35ad2cd2c0b77b1965966ef3db6b6373cb2c4b590cef2f16f4d6f62f13a6cbf1a481565b5935edd4e76f7b6a8fd0d74bc336b40a803aec38125c006c877dfdcdb9ba2b7aecab5cafe6076e024c73e3567adf97f607a71d180402c22a20a8388f517484cc4198f97c2fe4f3407e0dc577e61f0f71354aa601cf4e3e42e1edd8722d50f5af3441f68caa568cc1c3a19956c1233f265bb47236afab24ee42b27b0042b90693d77c1923147360ae6503f6ba6abbc9dd52a7b4c36a3b6b55f6a80cfa7f101dd9f1bfc7d7eaf09a5d636b510228f245bfb37b4625025d2c911435cdf6f878113753e0804ab8ecab870ad733b9728d7636b17578b41239393e7de47cbce871137d2b61729dda67b2b84cd3363aad64c5dd5bd172f1f091305b1ff78982abe7dab1588036d097cf497e300e6c78a926048febd1b9462c07f5868928357b74297c87f503056b89f786d22a538b6702e290bca04639a0f1d0939b67f409e5e58e472a6a07fa543e2531c2567ec73c41f6769b6ba94c5aa0a030d006f5b6b1c5fb218b86a8f63a48bc867466f20f699859e87956f48a182d26ed451861dd21201ecc7239037ada67319bdf0849c387c73a110af798b4c5f9018bc97993e060ea2a2937fa2eb095d65ec07009fc407a350f1d6fb3c98a0a5f204be985b0cb6962f0eb7844a179c4598a92ea32d2d706c800034d2e960ded5b476d77073316b933fb3e6ba2f4f24a3b73a1e4d8ed1491d757ecf56fd72465dac0000736744d28d29073091587c8bccad302f7054e8a32bb8724974d9f3e449fc70b2a41f0008b548f717ac0a2c3a6580bfb50774933a578ad6acdcb89940bb406ea540893f097d8a88d1609ed605f25499de939083a0c8a7c6db462df5dfa06c298dd233e249433a54267d5cdc22e5524705b7d6b16b96bb2cb83e00cef62e21d91528a74cf95bfd1d391590c93f4058e9bb02656fd087a5b63d738d1c3b5cf533fd59c81cf9136bfcd3e955c19daf9906ef175791fde6a1d98155d7881e241c3522551cf9fcae42e1e46929ea39fd00943446823f9755085ccc8456a3090b73a3031a201d9c704a4ad4868dd9b6d06205560013973f60d637de2f18354bf4523d9d81dc2a7e78cd42c586364bbe0ed86fde0f081f801c1a4abb830839b7796d9a01f141bec8bd93144104c6dc59170162c0a5a639eb63a0a164970de50eb2e04f027394b26ed48d341f7851994df79d7cd663672a556f25e5e16a3adbe1003d631de938fabfed234df12b5ff3027f4a2da823834cb098e0f977a4eb9614579d5c7a1d400a1a933a657aef8ea1a66743d73b0cf37a7d64e9a63e4c7b09945f0db750b311b39783fb5ea216616751967d480a630d3da7c89d1c7beae20369137e96734a4cfedca56a7887f076fe4fe97534ad3e4f74d1a81750581a5ea214b440c7f30331ab86c257534c71175d1e731303a48b01c589fda4fb0d4368b4dd63d91204cb6fc389b2202aa94391907bfb72902a4031f5589ed5f391c2ce92aa998c200ba3c77d8bd747b9d0a29fa85cda3949a6d2bd0c3402e68f98fd451aa27b6c2dfd170e004577cbdb25e3a1b9852e9f66a370789c47bfce722446dade1b32ceae71ee0e1d96edf7ed08a93e3690056f46c3d8e63f88e53673ee71d72cfedbeba493ee91333120e09e9ce9f9c9a7a400f814ea618b1de48f9805e092f4e20f301fbb65caa83735a2a5c89befe4bce4116dca3688e1e14c6f09a945671dedbb5c0ba526842b6cae31d8b5ff978bae928a17a75c134630dd9de988f6ad3d89a071b33775a9660a40b48ec61ad3f93ac81cb1c65d8b0bab5c214786abd13cc10a8ea2e2a370e86e2fa1a372d83c9697b5e37b281e51507685f714fdaebe49ffc93a5582e1936eaee8e4140a4b72" +const JPOLY1e20 = "e172e20c5d2de26b567c0cace9e7c6cc4407bd5ffcd22ca59d37b73d54fdbd937cd3abc6f502e8c186dbd4f1a06b9e2b894f31be77424f94dddfd5a45888a84ca66eeeb242eefe6764ed859dafccae7a6a635b3a63fe9dfbbd5f2d3f2610d39388f53060e84edae75be4f4f2272c0f1f26d1231836ad040ab091550f8a3a5423fb3ab83e068fe2684057f15691c4dc757a3aee4bca8595bf1ad03500d9620a5dbe3b2d64380694895d2f379ca928238293ea267ce14236d5be816a61f018fe4f6bc3c9865f5d4d4186e320ab653d1f3c035ae83e2ad725648a67d3480331e763a1dcdfb5711b56796170b124f5febd723a664a2deefbfa9999d922a108b0e683582ae8d3baacb5bb56683405ea9e6e0d71ddb24b2229c72bb9d07061f2d1fa097ade823b607a2029d6e121ae09d93de01a154199e8e6a6e77c970bda72ba8079b2b3a15dd494a3188b1d94a25ae108a8a5bd0b050e6ce64a365a21420e07fdeebecae02eb68a4304b59283055d22c27d680ea35952834d828c9b9b9dd1a886b4f7fe82fe8f2a962e1e5390e563dc281c799aee2a441b7a813facb6ff5e94c059710dcfe7e6b1635e21ae0dc878dd5f7cc0e1101a74452495a67d23a2672c939f32c81d4a2611073990e92a084cc3a62fd42ee566f29d963a9cc5100ccd0a200f49ce0a74fa891efa1b974d342b7fedf9269e40d9b34e3c59c3d37201aecd5a04f4ae3d0c9a68c7ab78c662390e4cf36cb63ea3539c442efd0bf4aace4b8c8bde93c3d84b4d6290adfae1c5e3fcd457b6f3159e501f17b72ff6bc13d6bf61fbdafabefd16ac1dae0bca667e4e16a2b800732f1d0a9274c8a4c6cccd2db62fc275dc308c31c11cd6fda78de2f81f0e542b76b42b2cc09ed8f965d94c714c9918064f53af5379cfbbc31edf9cbce694f63a75f122048de6e57b094908f749661456813a908027f5d8397ab7962bf75ac779a3e1b7ae3fbc93397a67b486bb849befff1de6162ef2819715a88f41881e366ace692a900796a2806393898dd1750ac2b4ca3d34ca48942322fb6375f0c9a00c9701048ee8d7d7a17e11739177a7ad5027556e85835daf8594d84a97fe6621c0fce1495ae6ab8676cdc992d247acf5a4e5ec8c4755fde28117228d2c3ecf89edb91e93d949e2174924572265e36d176d082ed1be884e51d885ba3cda175c51edcee5042eaf519d292aa05aa4185b03858d710a9d0880b3d4e5111f858a52fe352cbe0a24f06a3d977ae2eb85e2a03a68131d0ab91dac4941067cf90ecd0fce156bcd40b8968cd4aa11e0b4353b14508d79d13ac00af4a4d452496b7f2393699889aa1e508427dbf0be3db91d955feb51e559af57640c6b3f9d5f95609852c28f9462a9869dd93acbdb1aafb2381ebb886a0b3fcec278f8bb0f62c23e157e49b89245b0881268ce594acbddd3605b9eaa77c9ff513e0dbad514914136d96fe2843fe2b4e886a0b718a9b8d1132132110618d0d3595da284cd2a4c9d09386199e4f4d7723983d3a374b51cf20dac5cabb4ff7e7197c2ebd9318463409baa583d6a6115c1b768282ff37b0fe152c97671e400d5ccba7d6875df0bf95c5d91257fedb124de393f31908d0e36251326aa29dd5be86291c80b4bf78f419ec151eeaeff643a58b48ab35ad2cd2c0b77b1965966ef3db6b6373cb2c4b590cef2f16f4d6f62f13a6cbf1a481565b5935edd4e76f7b6a8fd0d74bc336b40a803aec38125c006c877dfdcdb9ba2b7aecab5cafe6076e024c73e3567adf97f607a71d180402c22a20a8388f517484cc4198f97c2fe4f3407e0dc577e61f0f71354aa601cf4e3e42e1edd8722d50f5af3441f68caa568cc1c3a19956c1233f265bb47236afab24ee42b27b0042b90693d77c1923147360ae6503f6ba6abbc9dd52a7b4c36a3b6b55f6a80cfa7f101dd9f1bfc7d7eaf09a5d636b510228f245bfb37b4625025d2c911435cdf6f878113753e0804ab8ecab870ad733b9728d7636b17578b41239393e7de47cbce871137d2b61729dda67b2b84cd3363aad64c5dd5bd172f1f091305b1ff78982abe7dab1588036d097cf497e300e6c78a926048febd1b9462c07f5868928357b74297c87f503056b89f786d22a538b6702e290bca04639a0f1d0939b67f409e5e58e472a6a07fa543e2531c2567ec73c41f6769b6ba94c5aa0a030d006f5b6b1c5fb218b86a8f63a48bc867466f20f699859e87956f48a182d26ed451861dd21201ecc7239037ada67319bdf0849c387c73a110af798b4c5f9018bc97993e060ea2a2937fa2eb095d65ec07009fc407a350f1d6fb3c98a0a5f204be985b0cb6962f0eb7844a179c4598a92ea32d2d706c800034d2e960ded5b476d77073316b933fb3e6ba2f4f24a3b73a1e4d8ed1491d757ecf56fd72465dac0000736744d28d29073091587c8bccad302f7054e8a32bb8724974d9f3e449fc70b2a41f0008b548f717ac0a2c3a6580bfb50774933a578ad6acdcb89940bb406ea540893f097d8a88d1609ed605f25499de939083a0c8a7c6db462df5dfa06c298dd233e249433a54267d5cdc22e5524705b7d6b16b96bb2cb83e00cef62e21d91528a74cf95bfd1d391590c93f4058e9bb02656fd087a5b63d738d1c3b5cf533fd59c81cf9136bfcd3e955c19daf9906ef175791fde6a1d98155d7881e241c3522551cf9fcae42e1e46929ea39fd00943446823f9755085ccc8456a3090b73a3031a201d9c704a4ad4868dd9b6d06205560013973f60d637de2f18354bf4523d9d81dc2a7e78cd42c586364bbe0ed86fde0f081f801c1a4abb830839b7796d9a01f141bec8bd93144104c6dc59170162c0a5a639eb63a0a164970de50eb2e04f027394b26ed48d341f7851994df79d7cd663672a556f25e5e16a3adbe1003d631de938fabfed234df12b5ff3027f4a2da823834cb098e0f977a4eb9614579d5c7a1d400a1a933a657aef8ea1a66743d73b0cf37a7d64e9a63e4c7b09945f0db750b311b39783fb5ea216616751967d480a630d3da7c89d1c7beae20369137e96734a4cfedca56a7887f076fe4fe97534ad3e4f74d1a81750581a5ea214b440c7f30331ab86c257534c71175d1e731303a48b01c589fda4fb0d4368b4dd63d91204cb6fc389b2202aa94391907bfb72902a4031f5589ed5f391c2ce92aa998c200ba3c77d8bd747b9d0a29fa85cda3949a6d2bd0c3402e68f98fd451aa27b6c2dfd170e004577cbdb25e3a1b9852e9f66a370789c47bfce722446dade1b32ceae71ee0e1d96edf7ed08a93e3690056f46c3d8e63f88e53673ee71d72cfedbeba493ee91333120e09e9ce9f9c9a7a400f814ea618b1de48f9805e092f4e20f301fbb65caa83735a2a5c89befe4bce4116dca3688e1e14c6f09a945671dedbb5c0ba526842b6cae31d8b5ff978bae928a17a75c134630dd9de988f6ad3d89a071b33775a9660a40b48ec61ad3f93ac81cb1c65d8b0bab5c214786abd13cc10a8ea2e2a370e86e2fa1a372d83c9697b5e37b281e51507685f714fdaebe49ffc93a5582e1936eaee8e4140a4b72" "Characteristic polynomial used by dSFMT with exponent 19937" const Poly19937 = "10455110544511444054554514541dbbb0a20820a288a00a80a82208280b73237d2ff2ab5e2fcac914510101df18802aaaa08a022820a02aaa202ae822c364b91fb08598fe4410154041f028a266586e59cf12ce316b3a56af45cb49d02c7059cb89d2d81b0d288badbb25fa4e53b280aa88a22aa82abe7fc0645b7d7a4650c1dec48f21224e3d0e6e04c062c2273ef0d8361415c724dbc8f79118d5fac429f35dc460f6007e54c3966c28808e4c9308cc46e2e0e153bd922223796d4101af867e16e6641e6831e06ebbd2beaf52b2b47076dbf3a3e36c6d14d19dbf5d4b2b44b4d3aa6e1ea102578d765f08e1cb0749220075b8aae81c6e99692a56b35ddd4cf91b1034f1398c98e2d4ac8dbed09bc73ede098514cf3ffdf45cbb59335e3ec42f5f6a5672acc4ca8daa02a2502350ac0485f8b36f27d7a1d4d4b22fc7601e22a4f7c6ba53782b335837a21a068e8fcf3fdebb28860157301519cdea328b1ef4b8d5bc512ce65ff33298c34cc98ea1558f7b6d4db594f4bcab58d9f7bcf5cc59e259216de13f77569bbcee1c8abd55de985b7129e611d156c08cafa022ad7a2206a34a61e5c4c91e75495112003ec03c182a0155d9221382d0b30f45a00d6c19740f9ecebb448de78dfc0342f14166f54afdb97d00ac1a390355ce2aa9de1b3c919d8dd188fc9451ce9c86fa560a2da9dcaa681efd21fe5b6055f8e35a833e5704936245d06e387bf9956251bf0a252628be7a3cb0edab4aaaf141e6d7a9929cc03afa76ca433016d880def9e4cf10f7274e58aa35c372b7b7fb210fe0dc1a6b8445e7774ad6001b9aa1f2a01a790ee849e7ac810e0a646e733a7121bd727a9b593e0c9f5306dff5105af5967e3cee81069100d7e91a9c266e64c9e073a6e527765308879b22ca062668f9a564da6314dcad51405f160e8259582b7c06c313c84b0acba44958c052e6be540a7688e240232bee40b990dc48ee07d560786ca34e7df1bbdd2bca38a30c548ec57e91906b8417ff0da68db9c154d8ad83b06a6fc2b2e14ca5fbe7bd50382949c9b1f6e8540d9d43b35fa76a6ded27c2f17095a4f330626c5e86e8ff88ae53e05a434356a04a1ddae43b6e2ab883719360fbece72b6090ab17414ca7006e49d183813422c808fde53a30f872254bb554653aef86855f95a9361782100de2402efd749cc8cf6a837066c1c40c0160e415d8119e53a09877f1160ef8b99b2839e9b8c09b1e461e906041344c8fc2ef0a8eda04e319da41e001e60bc64dcdfc0593dff0f4b390580e1cd5b3c16204e77df10217791f99de49fcdc9160b793fd980bff7ae0cbd570425eb439352e5032e03797461376b5fb92aa156ad64935cc201a162f10f04b6d2d20a0415ae16f299e98baa86466f6f517f05f430254884a4010ac196540b0644e3c274323d4f0206780d38175f1e41fcb65bd387be073abee61b99d43f6b9106953ae4f6906e6ac0741e26af05fa9150c4f380558668aa667e404e3784b839d631e35af015024dbfc3dce4685574cd1e58eb72c70011090a2a876b65e34cb6cf297d24cb61ccca5a9706f34ae1f66345998f850de4e48d77cdf6e00fb0d2210ec9fb53fed02a781f7dfcdb609b9f955504f450e4b7b623cb0f5ba1ea09d92cd8d14f7e827b4580855f3a7dc2e5a45817df9e26adb5934f6026f745cb0f65e71c590bd954d1abc3826379719b7c6f4a0cbe6eb22a903b98bef785bb96efe2fc96988722c91f3e59d28d8244c8bfb59ee26082d82cad937ee70f178b44082533308ca24f236d8b91ca7af5b3d865c90d61410e1ffe39be6433a12ef2932e101b4bb34befa76748e0364a96f06e7932f44297fd5f85765b662c3ade19d9a9d9479f6de20b6b753d3dcbadf63e344578b98af85b4c4c63be9d154864f5d341f210f3503a60efec38ee59069499d0049aedfaef9264a7ce9de460a01e5437254fc68dfaebaa5e0e791380806bc149aedbc1d771457770937a5d606fc5ae728993783e6c45e1f5e1b9492a32f9df46a01020792a3803af04837a3905e7cc6ae68c512cb58f4facb457476729bac1ac89a7a32dc6857edbd6624ebeffed9d4e84a2f4ded9759962635aac94ca72d039c14af6e932fc84c25de28688acab0f41ae931a0f35b9c4195483d902f95e0d3e745e08f334cf5062da9fbd18fbb9efeb275a50a8a479939aa3e376821a030f0d241a4c4f6e3298a43a7f2166db483946c5ca623087b6252e27b09805d92a834ad914b9555f9c36150bb17d7e85f6b1a10b41a5c36a1fd0fdc354ec91720b245b0abcde6b38fdd33f471aa6ba1dbb4f178c3c6d8140a1f0700e072b0f9aafe1208abc94eea750b84e74ba6781b48c398ddfd2842e5447a11767e4f467864e4447382379010669f07870339ca42ac290063b40eaba1daa63cf6cd70c5a600c018f6933dc8bec000a521344cad7320ba121dd21f4723d38a8d3ab8c1f0f6c5a6995b796af79407ae1a7ce6d78922677d9990dd2a588f8a3323d80e9a69417f5224565afa60b64604e7316229514dcb7282b4e638981a5751d114da1ac9bf31f0e2fff5213f2020f9f2f31a8fd0c614e80c1a056d4b1af3ded2f696578f56427962ca54f4a28a502a0ac59013416abd81515fb1956ccb494c05ef61cab48474b6b1609cc5a3871a5111f8bf0a76b378f0e646687829e30f5762156da66c1b1c7abc0eb84e6ff2b9f5b22d34540ab97d643e8dd2e35f6e9e4fc2c30d8af88b2caab7bd5d4a6cf967e8ef79967c1ae85bf7d410a79f4630f13fdc6507d339909b81a29d84741103371310e5b4e279758431df627553b6826fc4c98e5fb6551315b0bd811b7b0f357198210dd99ccd8fba2904114c3e0b344eba43832b3c507e8b6b586e4ab3dc7a2ec71e150c54a13eca2340328d0b3e419ab2ba862ee93fc239fb46d907628055e105318e7fa52f9a83deb0e3cb02c62b8817702ead02a315f76aa1d08860cc5214a867808e33f8e075241956f148f876f3bc66566773610c9c5935b559c0ac47d84b6bfb112f59842be58df51055cf9180264f53f7795d4c934718bc65f359e34a8d230408854685b59c3a9f4d73a229bb465d4da3165404c6786c767299f57dfa85a83492fb4f61386441c928224cd88a7f4b36f245b7aa2b5c97b545ac4db8afe9a1a87e27b57d94c2bbffdb6e88f812aa27e0908048812086c2a72289d7bf136b3a1042a44d1913d39caec24ffda22814706f080b6cbe00e9cd442ccdcb600a436c0daeacbc5482021ba8a06c1fedbb333793557d5175b9313799ff91dfa620380a9e2a10132f0818bba72072e359726e2bd1f2ec98e0face32e0f88ee2c6f7cef7c2fbceffe8d3ccdff97b7ff71d861ba8b98237ccfb00176ee02206ccc08026cee082a88a8a349a1c9016983ea10789272105032f89b3113fd9b75b35c884622ec884622ee8aee2aaa2aeae86868c868ea68ea6862e0624062ea22aa66ee66ee44ee64ce64ce64ce646464c4808081808080a0a0828282828282822222a8898888888888aaaa2aaaaaaaaaaaaa2000000000000000008" diff --git a/stdlib/Random/src/deprecated.jl b/stdlib/Random/src/deprecated.jl new file mode 100644 index 0000000000000..c126d40ab5437 --- /dev/null +++ b/stdlib/Random/src/deprecated.jl @@ -0,0 +1,21 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# PR #21359 + +@deprecate srand(r::MersenneTwister, filename::AbstractString, n::Integer=4) srand(r, read!(filename, Vector{UInt32}(uninitialized, Int(n)))) +@deprecate srand(filename::AbstractString, n::Integer=4) srand(read!(filename, Vector{UInt32}(uninitialized, Int(n)))) +@deprecate MersenneTwister(filename::AbstractString) srand(MersenneTwister(0), read!(filename, Vector{UInt32}(uninitialized, Int(4)))) + +function randjump(mt::MersenneTwister, jumps::Integer, jumppoly::AbstractString) + depwarn("`randjump(rng, jumps, jumppoly::AbstractString)` is deprecated; use `randjump(rng, steps, jumps)` instead", :randjump) + Base.Random._randjump(mt, dSFMT.GF2X(jumppoly), jumps) +end + +@deprecate randjump(mt::MersenneTwister, jumps::Integer) randjump(mt, big(10)^20, jumps) + +@deprecate convert(::Type{UInt128}, u::UUID) UInt128(u) +@deprecate convert(::Type{UUID}, s::AbstractString) UUID(s) + +# PR #25429 +@deprecate rand(r::AbstractRNG, dims::Dims) rand(r, Float64, dims) +@deprecate rand( dims::Dims) rand(Float64, dims) diff --git a/base/random/generation.jl b/stdlib/Random/src/generation.jl similarity index 100% rename from base/random/generation.jl rename to stdlib/Random/src/generation.jl diff --git a/base/random/misc.jl b/stdlib/Random/src/misc.jl similarity index 98% rename from base/random/misc.jl rename to stdlib/Random/src/misc.jl index 68abece65b197..fc9980cdc1593 100644 --- a/base/random/misc.jl +++ b/stdlib/Random/src/misc.jl @@ -158,7 +158,7 @@ optionally supplying the random-number generator `rng`. ```jldoctest julia> rng = MersenneTwister(1234); -julia> shuffle!(rng, collect(1:16)) +julia> shuffle!(rng, Vector(1:16)) 16-element Array{Int64,1}: 2 15 @@ -204,7 +204,7 @@ indices, see [`randperm`](@ref). ```jldoctest julia> rng = MersenneTwister(1234); -julia> shuffle(rng, collect(1:10)) +julia> shuffle(rng, Vector(1:10)) 10-element Array{Int64,1}: 6 1 @@ -362,7 +362,7 @@ according to section 4.5 of the RFC. ```jldoctest julia> rng = MersenneTwister(1234); -julia> Base.Random.uuid1(rng) +julia> Random.uuid1(rng) 2cc938da-5937-11e7-196e-0f4ef71aa64b ``` """ @@ -399,7 +399,7 @@ as specified by RFC 4122. ```jldoctest julia> rng = MersenneTwister(1234); -julia> Base.Random.uuid4(rng) +julia> Random.uuid4(rng) 82015f10-44cc-4827-996e-0f4ef71aa64b ``` """ @@ -419,7 +419,7 @@ Inspects the given UUID and returns its version (see RFC 4122). ```jldoctest julia> rng = MersenneTwister(1234); -julia> Base.Random.uuid_version(Base.Random.uuid4(rng)) +julia> Random.uuid_version(Random.uuid4(rng)) 4 ``` """ @@ -430,7 +430,7 @@ UInt128(u::UUID) = u.value let groupings = [1:8; 10:13; 15:18; 20:23; 25:36] global UUID function UUID(s::AbstractString) - s = Base.Unicode.lowercase(s) + s = lowercase(s) if !contains(s, r"^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$") throw(ArgumentError("Malformed UUID string")) diff --git a/base/random/normal.jl b/stdlib/Random/src/normal.jl similarity index 100% rename from base/random/normal.jl rename to stdlib/Random/src/normal.jl diff --git a/stdlib/Random/test/OAs.jl b/stdlib/Random/test/OAs.jl new file mode 100644 index 0000000000000..0d0b64041f1b6 --- /dev/null +++ b/stdlib/Random/test/OAs.jl @@ -0,0 +1,124 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# copied verbatim from julia/test/TestHelpers.jl + +module OAs + +using Base: Indices, IndexCartesian, IndexLinear, tail + +export OffsetArray + +struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N} + parent::AA + offsets::NTuple{N,Int} +end +OffsetVector{T,AA<:AbstractArray} = OffsetArray{T,1,AA} + +OffsetArray(A::AbstractArray{T,N}, offsets::NTuple{N,Int}) where {T,N} = OffsetArray{T,N,typeof(A)}(A, offsets) +OffsetArray(A::AbstractArray{T,N}, offsets::Vararg{Int,N}) where {T,N} = OffsetArray(A, offsets) + +OffsetArray{T,N}(::Uninitialized, inds::Indices{N}) where {T,N} = + OffsetArray{T,N,Array{T,N}}(Array{T,N}(uninitialized, map(length, inds)), map(indsoffset, inds)) +OffsetArray{T}(::Uninitialized, inds::Indices{N}) where {T,N} = + OffsetArray{T,N}(uninitialized, inds) + +Base.IndexStyle(::Type{T}) where {T<:OffsetArray} = Base.IndexStyle(parenttype(T)) +parenttype(::Type{OffsetArray{T,N,AA}}) where {T,N,AA} = AA +parenttype(A::OffsetArray) = parenttype(typeof(A)) + +Base.parent(A::OffsetArray) = A.parent + +errmsg(A) = error("size not supported for arrays with indices $(axes(A)); see https://docs.julialang.org/en/latest/devdocs/offset-arrays/") +Base.size(A::OffsetArray) = errmsg(A) +Base.size(A::OffsetArray, d) = errmsg(A) +Base.eachindex(::IndexCartesian, A::OffsetArray) = CartesianIndices(axes(A)) +Base.eachindex(::IndexLinear, A::OffsetVector) = axes(A, 1) + +# Implementations of indices and indices1. Since bounds-checking is +# performance-critical and relies on indices, these are usually worth +# optimizing thoroughly. +@inline Base.axes(A::OffsetArray, d) = 1 <= d <= length(A.offsets) ? axes(parent(A))[d] .+ A.offsets[d] : (1:1) +@inline Base.axes(A::OffsetArray) = _indices(axes(parent(A)), A.offsets) # would rather use ntuple, but see #15276 +@inline _indices(inds, offsets) = (inds[1] .+ offsets[1], _indices(tail(inds), tail(offsets))...) +_indices(::Tuple{}, ::Tuple{}) = () +Base.indices1(A::OffsetArray{T,0}) where {T} = 1:1 # we only need to specialize this one + +function Base.similar(A::OffsetArray, T::Type, dims::Dims) + B = similar(parent(A), T, dims) +end +function Base.similar(A::AbstractArray, T::Type, inds::Tuple{UnitRange,Vararg{UnitRange}}) + B = similar(A, T, map(length, inds)) + OffsetArray(B, map(indsoffset, inds)) +end + +Base.similar(f::Union{Function,Type}, shape::Tuple{UnitRange,Vararg{UnitRange}}) = + OffsetArray(f(map(length, shape)), map(indsoffset, shape)) +Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:Array} = + OffsetArray(T(uninitialized, map(length, shape)), map(indsoffset, shape)) +Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:BitArray} = + OffsetArray(T(uninitialized, map(length, shape)), map(indsoffset, shape)) + +Base.reshape(A::AbstractArray, inds::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(reshape(A, map(length, inds)), map(indsoffset, inds)) + +@inline function Base.getindex(A::OffsetArray{T,N}, I::Vararg{Int,N}) where {T,N} + checkbounds(A, I...) + @inbounds ret = parent(A)[offset(A.offsets, I)...] + ret +end +# Vectors don't support one-based linear indexing; they always use the offsets +@inline function Base.getindex(A::OffsetVector, i::Int) + checkbounds(A, i) + @inbounds ret = parent(A)[offset(A.offsets, (i,))[1]] + ret +end +# But multidimensional arrays allow one-based linear indexing +@inline function Base.getindex(A::OffsetArray, i::Int) + checkbounds(A, i) + @inbounds ret = parent(A)[i] + ret +end +@inline function Base.setindex!(A::OffsetArray{T,N}, val, I::Vararg{Int,N}) where {T,N} + checkbounds(A, I...) + @inbounds parent(A)[offset(A.offsets, I)...] = val + val +end +@inline function Base.setindex!(A::OffsetVector, val, i::Int) + checkbounds(A, i) + @inbounds parent(A)[offset(A.offsets, (i,))[1]] = val + val +end +@inline function Base.setindex!(A::OffsetArray, val, i::Int) + checkbounds(A, i) + @inbounds parent(A)[i] = val + val +end + +@inline function Base.deleteat!(A::OffsetArray, i::Int) + checkbounds(A, i) + @inbounds deleteat!(parent(A), offset(A.offsets, (i,))[1]) +end + +@inline function Base.deleteat!(A::OffsetArray{T,N}, I::Vararg{Int, N}) where {T,N} + checkbounds(A, I...) + @inbounds deleteat!(parent(A), offset(A.offsets, I)...) +end + +@inline function Base.deleteat!(A::OffsetArray, i::UnitRange{Int}) + checkbounds(A, first(i)) + checkbounds(A, last(i)) + first_idx = offset(A.offsets, (first(i),))[1] + last_idx = offset(A.offsets, (last(i),))[1] + @inbounds deleteat!(parent(A), first_idx:last_idx) +end + +# Computing a shifted index (subtracting the offset) +offset(offsets::NTuple{N,Int}, inds::NTuple{N,Int}) where {N} = _offset((), offsets, inds) +_offset(out, ::Tuple{}, ::Tuple{}) = out +@inline _offset(out, offsets, inds) = _offset((out..., inds[1]-offsets[1]), Base.tail(offsets), Base.tail(inds)) + +indsoffset(r::AbstractRange) = first(r) - 1 +indsoffset(i::Integer) = 0 + +Base.resize!(A::OffsetVector, nl::Integer) = (resize!(A.parent, nl); A) + +end diff --git a/test/random.jl b/stdlib/Random/test/runtests.jl similarity index 94% rename from test/random.jl rename to stdlib/Random/test/runtests.jl index e36d04c519ac1..2f4865c857389 100644 --- a/test/random.jl +++ b/stdlib/Random/test/runtests.jl @@ -1,10 +1,14 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -isdefined(Main, :TestHelpers) || @eval Main include(joinpath(dirname(@__FILE__), "TestHelpers.jl")) -using Main.TestHelpers.OAs +using Test, SparseArrays -using Base.Random.dSFMT -using Base.Random: Sampler, SamplerRangeFast, SamplerRangeInt, MT_CACHE_F, MT_CACHE_I +include("OAs.jl") +using .OAs + +using Random +using Random.dSFMT + +using Random: Sampler, SamplerRangeFast, SamplerRangeInt, MT_CACHE_F, MT_CACHE_I @testset "Issue #6573" begin srand(0) @@ -93,10 +97,10 @@ for T in (Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt end end -@test !any([(Base.Random.maxmultiple(i)+i) > 0xFF for i in 0x00:0xFF]) -@test all([(Base.Random.maxmultiple(i)+1) % i for i in 0x01:0xFF] .== 0) -@test all([(Base.Random.maxmultiple(i)+1+i) > 0xFF for i in 0x00:0xFF]) -@test length(0x00:0xFF)== Base.Random.maxmultiple(0x0)+1 +@test !any([(Random.maxmultiple(i)+i) > 0xFF for i in 0x00:0xFF]) +@test all([(Random.maxmultiple(i)+1) % i for i in 0x01:0xFF] .== 0) +@test all([(Random.maxmultiple(i)+1+i) > 0xFF for i in 0x00:0xFF]) +@test length(0x00:0xFF)== Random.maxmultiple(0x0)+1 if sizeof(Int32) < sizeof(Int) @@ -109,7 +113,6 @@ if sizeof(Int32) < sizeof(Int) @test all(div(one(UInt128) << 64, k)*k - 1 == SamplerRangeInt(map(U, 1:k)).u for k in 13 .+ Int64(2).^(52:62)) end - end # BigInt specific @@ -206,12 +209,12 @@ function randmtzig_fill_ziggurat_tables() # Operates on the global arrays return nothing end randmtzig_fill_ziggurat_tables() -@test all(ki == Base.Random.ki) -@test all(wi == Base.Random.wi) -@test all(fi == Base.Random.fi) -@test all(ke == Base.Random.ke) -@test all(we == Base.Random.we) -@test all(fe == Base.Random.fe) +@test all(ki == Random.ki) +@test all(wi == Random.wi) +@test all(fi == Random.fi) +@test all(ke == Random.ke) +@test all(we == Random.we) +@test all(fe == Random.fe) #same random numbers on for small ranges on all systems guardsrand() do @@ -232,7 +235,7 @@ for U in (Int64, UInt64) end -import Base.Random: uuid1, uuid4, UUID, uuid_version +import Random: uuid1, uuid4, UUID, uuid_version # UUID u1 = uuid1() @@ -286,12 +289,12 @@ let mt = MersenneTwister(0) end srand(mt, 0) - AF64 = Vector{Float64}(uninitialized, Base.Random.dsfmt_get_min_array_size()-1) + AF64 = Vector{Float64}(uninitialized, Random.dsfmt_get_min_array_size()-1) @test rand!(mt, AF64)[end] == 0.957735065345398 @test rand!(mt, AF64)[end] == 0.6492481059865669 resize!(AF64, 2*length(mt.vals)) - @test invoke(rand!, Tuple{MersenneTwister,AbstractArray{Float64},Base.Random.SamplerTrivial{Base.Random.CloseOpen01_64}}, - mt, AF64, Base.Random.SamplerTrivial(Base.Random.CloseOpen01()))[end] == 0.1142787906708973 + @test invoke(rand!, Tuple{MersenneTwister,AbstractArray{Float64},Random.SamplerTrivial{Random.CloseOpen01_64}}, + mt, AF64, Random.SamplerTrivial(Random.CloseOpen01()))[end] == 0.1142787906708973 end # Issue #9037 @@ -352,7 +355,6 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()]) f(rng..., 5) ::Vector{Float64} f(rng..., 2, 3) ::Array{Float64, 2} f(rng..., b2, u3) ::Array{Float64, 2} - f(rng..., (2, 3)) ::Array{Float64, 2} for T in functypes[f] a0 = f(rng..., T) ::T a1 = f(rng..., T, 5) ::Vector{T} @@ -483,9 +485,9 @@ let mta = MersenneTwister(42), mtb = MersenneTwister(42) @test randsubseq(mta,1:10,0.4) == randsubseq(mtb,1:10,0.4) @test randsubseq!(mta,Int[],1:10,0.4) == randsubseq!(mtb,Int[],1:10,0.4) - @test shuffle(mta,collect(1:10)) == shuffle(mtb,collect(1:10)) - @test shuffle!(mta,collect(1:10)) == shuffle!(mtb,collect(1:10)) - @test shuffle(mta,collect(2:11)) == shuffle(mtb,2:11) + @test shuffle(mta,Vector(1:10)) == shuffle(mtb,Vector(1:10)) + @test shuffle!(mta,Vector(1:10)) == shuffle!(mtb,Vector(1:10)) + @test shuffle(mta,Vector(2:11)) == shuffle(mtb,2:11) @test shuffle!(mta, rand(mta, 2, 3)) == shuffle!(mtb, rand(mtb, 2, 3)) @test shuffle(mta, rand(mta, 2, 3)) == shuffle(mtb, rand(mtb, 2, 3)) @@ -525,10 +527,10 @@ let seed = rand(UInt) # test PRNG jump - mts = randjump(mta, size, jump25000) + mts = randjump(mta, 25000, size) @test length(mts) == 4 -for x in (rand(mts[k], Float64) for j=1:step, k=1:size) + for x in (rand(mts[k], Float64) for j=1:step, k=1:size) @test rand(mtb, Float64) == x end end @@ -560,18 +562,18 @@ let seed = rand(UInt32, 10) end # MersenneTwister initialization with invalid values -@test_throws DomainError Base.dSFMT.DSFMT_state(zeros(Int32, rand(0:Base.dSFMT.JN32-1))) +@test_throws DomainError dSFMT.DSFMT_state(zeros(Int32, rand(0:dSFMT.JN32-1))) -@test_throws DomainError MersenneTwister(zeros(UInt32, 1), Base.dSFMT.DSFMT_state(), +@test_throws DomainError MersenneTwister(zeros(UInt32, 1), dSFMT.DSFMT_state(), zeros(Float64, 10), zeros(UInt128, MT_CACHE_I>>4), 0, 0) -@test_throws DomainError MersenneTwister(zeros(UInt32, 1), Base.dSFMT.DSFMT_state(), +@test_throws DomainError MersenneTwister(zeros(UInt32, 1), dSFMT.DSFMT_state(), zeros(Float64, MT_CACHE_F), zeros(UInt128, MT_CACHE_I>>4), -1, 0) -@test_throws DomainError MersenneTwister(zeros(UInt32, 1), Base.dSFMT.DSFMT_state(), +@test_throws DomainError MersenneTwister(zeros(UInt32, 1), dSFMT.DSFMT_state(), zeros(Float64, MT_CACHE_F), zeros(UInt128, MT_CACHE_I>>3), 0, 0) -@test_throws DomainError MersenneTwister(zeros(UInt32, 1), Base.dSFMT.DSFMT_state(), +@test_throws DomainError MersenneTwister(zeros(UInt32, 1), dSFMT.DSFMT_state(), zeros(Float64, MT_CACHE_F), zeros(UInt128, MT_CACHE_I>>4), 0, -1) # seed is private to MersenneTwister @@ -579,7 +581,7 @@ let seed = rand(UInt32, 10) r = MersenneTwister(seed) @test r.seed == seed && r.seed !== seed # RNGs do not share their seed in randjump - let rs = randjump(r, 2) + let rs = randjump(r, big(10)^20, 2) @test rs[1].seed !== rs[2].seed srand(rs[2]) @test seed == rs[1].seed != rs[2].seed @@ -590,7 +592,7 @@ end # srand(rng, ...) returns rng (#21248) guardsrand() do - g = Base.Random.GLOBAL_RNG + g = Random.GLOBAL_RNG m = MersenneTwister(0) @test srand() === g @test srand(rand(UInt)) === g @@ -603,8 +605,8 @@ end # Issue 20062 - ensure internal functions reserve_1, reserve are type-stable let r = MersenneTwister(0) - @inferred Base.Random.reserve_1(r) - @inferred Base.Random.reserve(r, 1) + @inferred Random.reserve_1(r) + @inferred Random.reserve(r, 1) end # test randstring API diff --git a/stdlib/SharedArrays/src/SharedArrays.jl b/stdlib/SharedArrays/src/SharedArrays.jl index d7b933c723087..d66c2c42b956e 100644 --- a/stdlib/SharedArrays/src/SharedArrays.jl +++ b/stdlib/SharedArrays/src/SharedArrays.jl @@ -7,11 +7,11 @@ Provide the [`SharedArray`](@ref) type. It represents an array, which is shared """ module SharedArrays -using Mmap, Distributed +using Mmap, Distributed, Random import Base: length, size, ndims, IndexStyle, reshape, convert, deepcopy_internal, serialize, deserialize, - show, getindex, setindex!, fill!, rand!, similar, reduce, map!, copyto!, unsafe_convert -import Base.Random + show, getindex, setindex!, fill!, similar, reduce, map!, copyto!, unsafe_convert +import Random import Base.Serializer: serialize_cycle_header, serialize_type, writetag, UNDEFREF_TAG import Distributed: RRID, procs import Base.Filesystem: JL_O_CREAT, JL_O_RDWR, S_IRUSR, S_IWUSR @@ -507,7 +507,7 @@ function fill!(S::SharedArray, v) return S end -function rand!(S::SharedArray{T}) where T +function Random.rand!(S::SharedArray{T}) where T f = S->map!(x -> rand(T), S.loc_subarr_1d, S.loc_subarr_1d) @sync for p in procs(S) @async remotecall_wait(f, p, S) diff --git a/stdlib/SharedArrays/test/runtests.jl b/stdlib/SharedArrays/test/runtests.jl index d69b3e0ce2f16..9230a6b2e204c 100644 --- a/stdlib/SharedArrays/test/runtests.jl +++ b/stdlib/SharedArrays/test/runtests.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test, Distributed, SharedArrays +using Test, Distributed, SharedArrays, Random include(joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testenv.jl")) addprocs_with_testenv(4) @@ -78,7 +78,7 @@ copyto!(s, d) s = SharedArrays.shmem_rand(dims) copyto!(s, sdata(d)) @test s == d -a = rand(dims) +a = rand(Float64, dims) @test sdata(a) == a d = SharedArray{Int}(dims, init = D->fill!(D.loc_subarr_1d, myid())) @@ -190,7 +190,7 @@ s = copy(sdata(d)) ds = deepcopy(d) @test ds == d pids_d = procs(d) -remotecall_fetch(setindex!, pids_d[findfirst(id->(id != myid()), pids_d)], d, 1.0, 1:10) +remotecall_fetch(setindex!, pids_d[findfirst(id->(id != myid()), pids_d)::Int], d, 1.0, 1:10) @test ds != d @test s != d copyto!(d, s) @@ -212,8 +212,8 @@ d[5,1:2:4,8] = 19 AA = rand(4,2) A = @inferred(convert(SharedArray, AA)) -B = @inferred(convert(SharedArray, adjoint(AA))) -@test B*A == adjoint(AA)*AA +B = @inferred(convert(SharedArray, copy(AA'))) +@test B*A == AA'*AA d=SharedArray{Int64,2}((10,10); init = D->fill!(D.loc_subarr_1d, myid()), pids=[id_me, id_other]) d2 = map(x->1, d) diff --git a/stdlib/SparseArrays/docs/src/index.md b/stdlib/SparseArrays/docs/src/index.md new file mode 100644 index 0000000000000..f5d1652cae6e5 --- /dev/null +++ b/stdlib/SparseArrays/docs/src/index.md @@ -0,0 +1,221 @@ +# Sparse Arrays + +Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) +in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros +that storing them in a special data structure leads to savings in space and execution time, +compared to dense arrays. + +## [Compressed Sparse Column (CSC) Sparse Matrix Storage](@id man-csc) + +In Julia, sparse matrices are stored in the [Compressed Sparse Column (CSC) format](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29). +Julia sparse matrices have the type [`SparseMatrixCSC{Tv,Ti}`](@ref), where `Tv` is the +type of the stored values, and `Ti` is the integer type for storing column pointers and +row indices. The internal representation of `SparseMatrixCSC` is as follows: + +```julia +struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti} + m::Int # Number of rows + n::Int # Number of columns + colptr::Vector{Ti} # Column i is in colptr[i]:(colptr[i+1]-1) + rowval::Vector{Ti} # Row indices of stored values + nzval::Vector{Tv} # Stored values, typically nonzeros +end +``` + +The compressed sparse column storage makes it easy and quick to access the elements in the column +of a sparse matrix, whereas accessing the sparse matrix by rows is considerably slower. Operations +such as insertion of previously unstored entries one at a time in the CSC structure tend to be slow. This is +because all elements of the sparse matrix that are beyond the point of insertion have to be moved +one place over. + +All operations on sparse matrices are carefully implemented to exploit the CSC data structure +for performance, and to avoid expensive operations. + +If you have data in CSC format from a different application or library, and wish to import it +in Julia, make sure that you use 1-based indexing. The row indices in every column need to be +sorted. If your `SparseMatrixCSC` object contains unsorted row indices, one quick way to sort +them is by doing a double transpose. + +In some applications, it is convenient to store explicit zero values in a `SparseMatrixCSC`. These +*are* accepted by functions in `Base` (but there is no guarantee that they will be preserved in +mutating operations). Such explicitly stored zeros are treated as structural nonzeros by many +routines. The [`nnz`](@ref) function returns the number of elements explicitly stored in the +sparse data structure, including structural nonzeros. In order to count the exact number of +numerical nonzeros, use [`count(!iszero, x)`](@ref), which inspects every stored element of a sparse +matrix. [`dropzeros`](@ref), and the in-place [`dropzeros!`](@ref), can be used to +remove stored zeros from the sparse matrix. + +```jldoctest +julia> A = sparse([1, 2, 3], [1, 2, 3], [0, 2, 0]) +3×3 SparseMatrixCSC{Int64,Int64} with 3 stored entries: + [1, 1] = 0 + [2, 2] = 2 + [3, 3] = 0 + +julia> dropzeros(A) +3×3 SparseMatrixCSC{Int64,Int64} with 1 stored entry: + [2, 2] = 2 +``` + +## Sparse Vector Storage + +Sparse vectors are stored in a close analog to compressed sparse column format for sparse +matrices. In Julia, sparse vectors have the type [`SparseVector{Tv,Ti}`](@ref) where `Tv` +is the type of the stored values and `Ti` the integer type for the indices. The internal +representation is as follows: + +```julia +struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti} + n::Int # Length of the sparse vector + nzind::Vector{Ti} # Indices of stored values + nzval::Vector{Tv} # Stored values, typically nonzeros +end +``` + +As for [`SparseMatrixCSC`](@ref), the `SparseVector` type can also contain explicitly +stored zeros. (See [Sparse Matrix Storage](@ref man-csc).). + +## Sparse Vector and Matrix Constructors + +The simplest way to create a sparse array is to use a function equivalent to the [`zeros`](@ref) +function that Julia provides for working with dense arrays. To produce a +sparse array instead, you can use the same name with an `sp` prefix: + +```jldoctest +julia> spzeros(3) +3-element SparseVector{Float64,Int64} with 0 stored entries +``` + +The [`sparse`](@ref) function is often a handy way to construct sparse arrays. For +example, to construct a sparse matrix we can input a vector `I` of row indices, a vector +`J` of column indices, and a vector `V` of stored values (this is also known as the +[COO (coordinate) format](https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29)). +`sparse(I,J,V)` then constructs a sparse matrix such that `S[I[k], J[k]] = V[k]`. The +equivalent sparse vector constructor is [`sparsevec`](@ref), which takes the (row) index +vector `I` and the vector `V` with the stored values and constructs a sparse vector `R` +such that `R[I[k]] = V[k]`. + +```jldoctest sparse_function +julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3]; + +julia> S = sparse(I,J,V) +5×18 SparseMatrixCSC{Int64,Int64} with 4 stored entries: + [1 , 4] = 1 + [4 , 7] = 2 + [5 , 9] = 3 + [3 , 18] = -5 + +julia> R = sparsevec(I,V) +5-element SparseVector{Int64,Int64} with 4 stored entries: + [1] = 1 + [3] = -5 + [4] = 2 + [5] = 3 +``` + +The inverse of the [`sparse`](@ref) and [`sparsevec`](@ref) functions is +[`findnz`](@ref), which retrieves the inputs used to create the sparse array. +[`find(!iszero, x)`](@ref) returns the cartesian indices of non-zero entries in `x` +(including stored entries equal to zero). + +```jldoctest sparse_function +julia> findnz(S) +([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5]) + +julia> find(!iszero, S) +4-element Array{CartesianIndex{2},1}: + CartesianIndex(1, 4) + CartesianIndex(4, 7) + CartesianIndex(5, 9) + CartesianIndex(3, 18) + +julia> findnz(R) +([1, 3, 4, 5], [1, -5, 2, 3]) + +julia> find(!iszero, R) +4-element Array{Int64,1}: + 1 + 3 + 4 + 5 +``` + +Another way to create a sparse array is to convert a dense array into a sparse array using +the [`sparse`](@ref) function: + +```jldoctest +julia> sparse(Matrix(1.0I, 5, 5)) +5×5 SparseMatrixCSC{Float64,Int64} with 5 stored entries: + [1, 1] = 1.0 + [2, 2] = 1.0 + [3, 3] = 1.0 + [4, 4] = 1.0 + [5, 5] = 1.0 + +julia> sparse([1.0, 0.0, 1.0]) +3-element SparseVector{Float64,Int64} with 2 stored entries: + [1] = 1.0 + [3] = 1.0 +``` + +You can go in the other direction using the [`Array`](@ref) constructor. The [`issparse`](@ref) +function can be used to query if a matrix is sparse. + +```jldoctest +julia> issparse(spzeros(5)) +true +``` + +## Sparse matrix operations + +Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, +assignment into, and concatenation of sparse matrices work in the same way as dense matrices. +Indexing operations, especially assignment, are expensive, when carried out one element at a time. +In many cases it may be better to convert the sparse matrix into `(I,J,V)` format using [`findnz`](@ref), +manipulate the values or the structure in the dense vectors `(I,J,V)`, and then reconstruct +the sparse matrix. + +## Correspondence of dense and sparse methods + +The following table gives a correspondence between built-in methods on sparse matrices and their +corresponding methods on dense matrix types. In general, methods that generate sparse matrices +differ from their dense counterparts in that the resulting matrix follows the same sparsity pattern +as a given sparse matrix `S`, or that the resulting sparse matrix has density `d`, i.e. each matrix +element has a probability `d` of being non-zero. + +Details can be found in the [Sparse Vectors and Matrices](@ref stdlib-sparse-arrays) +section of the standard library reference. + +| Sparse | Dense | Description | +|:-------------------------- |:---------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`spzeros(m,n)`](@ref) | [`zeros(m,n)`](@ref) | Creates a *m*-by-*n* matrix of zeros. ([`spzeros(m,n)`](@ref) is empty.) | +| [`sparse(I, n, n)`](@ref) | [`Matrix(I,n,n)`](@ref)| Creates a *n*-by-*n* identity matrix. | +| [`Array(S)`](@ref) | [`sparse(A)`](@ref) | Interconverts between dense and sparse formats. | +| [`sprand(m,n,d)`](@ref) | [`rand(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed uniformly on the half-open interval ``[0, 1)``. | +| [`sprandn(m,n,d)`](@ref) | [`randn(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution. | +| [`sprandn(m,n,d,X)`](@ref) | [`randn(m,n,X)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the *X* distribution. (Requires the `Distributions` package.) | + +# [Sparse Arrays](@id stdlib-sparse-arrays) + +```@docs +SparseArrays.SparseVector +SparseArrays.SparseMatrixCSC +SparseArrays.sparse +SparseArrays.sparsevec +SparseArrays.issparse +SparseArrays.nnz +SparseArrays.spzeros +SparseArrays.spdiagm +SparseArrays.blkdiag +SparseArrays.sprand +SparseArrays.sprandn +SparseArrays.nonzeros +SparseArrays.rowvals +SparseArrays.nzrange +SparseArrays.dropzeros!(::SparseMatrixCSC, ::Bool) +SparseArrays.dropzeros(::SparseMatrixCSC, ::Bool) +SparseArrays.dropzeros!(::SparseVector, ::Bool) +SparseArrays.dropzeros(::SparseVector, ::Bool) +SparseArrays.permute +permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) +``` diff --git a/base/sparse/sparse.jl b/stdlib/SparseArrays/src/SparseArrays.jl similarity index 64% rename from base/sparse/sparse.jl rename to stdlib/SparseArrays/src/SparseArrays.jl index 8c9133aabe6ab..1d4b396376d6b 100644 --- a/base/sparse/sparse.jl +++ b/stdlib/SparseArrays/src/SparseArrays.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +__precompile__(true) + """ Support for sparse arrays. Provides `AbstractSparseArray` and subtypes. """ @@ -15,9 +17,9 @@ import Base.LinAlg: mul!, ldiv!, rdiv! import Base: @get!, acos, acosd, acot, acotd, acsch, asech, asin, asind, asinh, atan, atand, atanh, broadcast!, chol, conj!, cos, cosc, cosd, cosh, cospi, cot, cotd, coth, count, csc, cscd, csch, adjoint!, diag, diff, done, dot, eig, - exp10, exp2, findn, floor, hash, indmin, inv, issymmetric, istril, istriu, - log10, log2, lu, next, sec, secd, sech, show, sin, - sinc, sind, sinh, sinpi, squeeze, start, sum, summary, tan, + exp10, exp2, findprev, findnext, floor, hash, indmin, inv, + issymmetric, istril, istriu, log10, log2, lu, next, sec, secd, sech, show, + sin, sinc, sind, sinh, sinpi, squeeze, start, sum, summary, tan, tand, tanh, trace, transpose!, tril!, triu!, trunc, vecnorm, abs, abs2, broadcast, ceil, complex, cond, conj, convert, copy, copyto!, adjoint, diagm, exp, expm1, factorize, find, findmax, findmin, findnz, float, getindex, @@ -26,6 +28,8 @@ import Base: @get!, acos, acosd, acot, acotd, acsch, asech, asin, asind, asinh, rotl90, rotr90, round, scale!, setindex!, similar, size, transpose, tril, triu, vec, permute!, map, map!, Array +using Random: defaultRNG, AbstractRNG, randsubseq, randsubseq! + export AbstractSparseArray, AbstractSparseMatrix, AbstractSparseVector, SparseMatrixCSC, SparseVector, blkdiag, droptol!, dropzeros!, dropzeros, issparse, nonzeros, nzrange, rowvals, sparse, sparsevec, spdiagm, @@ -36,5 +40,14 @@ include("sparsematrix.jl") include("sparsevector.jl") include("higherorderfns.jl") include("linalg.jl") +include("deprecated.jl") + + +# temporarily moved here and commented out from from base/linalg/diagonal.jl, base/linalg/tridiag.jl +# and base/linalg/bidiag.jl due to their usage of spzeros +similar(B::Bidiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) +similar(D::Diagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) +similar(S::SymTridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) +similar(M::Tridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...) end diff --git a/base/sparse/abstractsparse.jl b/stdlib/SparseArrays/src/abstractsparse.jl similarity index 62% rename from base/sparse/abstractsparse.jl rename to stdlib/SparseArrays/src/abstractsparse.jl index 5a360376841de..7ec75e1e6d03e 100644 --- a/base/sparse/abstractsparse.jl +++ b/stdlib/SparseArrays/src/abstractsparse.jl @@ -42,3 +42,24 @@ function Base.reinterpret(::Type, A::AbstractSparseArray) Try reinterpreting the value itself instead. """) end + +# The following two methods should be overloaded by concrete types to avoid +# allocating the I = find(...) +_sparse_findnextnz(v::AbstractSparseArray, i::Integer) = (I = find(!iszero, v); n = searchsortedfirst(I, i); n<=length(I) ? I[n] : nothing) +_sparse_findprevnz(v::AbstractSparseArray, i::Integer) = (I = find(!iszero, v); n = searchsortedlast(I, i); !iszero(n) ? I[n] : nothing) + +function findnext(f::typeof(!iszero), v::AbstractSparseArray, i::Integer) + j = _sparse_findnextnz(v, i) + while j !== nothing && !f(v[j]) + j = _sparse_findnextnz(v, j+1) + end + return j +end + +function findprev(f::typeof(!iszero), v::AbstractSparseArray, i::Integer) + j = _sparse_findprevnz(v, i) + while j !== nothing && !f(v[j]) + j = _sparse_findprevnz(v, j-1) + end + return j +end diff --git a/stdlib/SparseArrays/src/deprecated.jl b/stdlib/SparseArrays/src/deprecated.jl new file mode 100644 index 0000000000000..8cae8ed0d544f --- /dev/null +++ b/stdlib/SparseArrays/src/deprecated.jl @@ -0,0 +1,229 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Base: @deprecate, depwarn + +# BEGIN 0.7 deprecations + +# PR #22475 +import Base: cat +@deprecate cat(::Type{Val{N}}, A::_SparseConcatGroup...) where {N} cat(Val(N), A...) +@deprecate cat(::Type{Val{N}}, A::_DenseConcatGroup...) where {N} cat(Val(N), A...) + +# deprecate remaining vectorized methods over SparseVectors (zero-preserving) +for op in (:floor, :ceil, :trunc, :round, + :log1p, :expm1, :sinpi, + :sin, :tan, :sind, :tand, + :asin, :atan, :asind, :atand, + :sinh, :tanh, :asinh, :atanh) + @eval import Base.Math: $op + @eval @deprecate ($op)(x::AbstractSparseVector{<:Number,<:Integer}) ($op).(x) +end +# deprecate remaining vectorized methods over SparseVectors (not-zero-preserving) +for op in (:exp, :exp2, :exp10, :log, :log2, :log10, + :cos, :cosd, :acos, :cosh, :cospi, + :csc, :cscd, :acot, :csch, :acsch, + :cot, :cotd, :acosd, :coth, + :sec, :secd, :acotd, :sech, :asech) + @eval import Base.Math: $op + @eval @deprecate ($op)(x::AbstractSparseVector{<:Number,<:Integer}) ($op).(x) +end + +# PR 23341 +import Base.LinAlg: diagm +@deprecate diagm(A::SparseMatrixCSC) sparse(Diagonal(sparsevec(A))) + +# PR #23757 +@deprecate spdiagm(x::AbstractVector) sparse(Diagonal(x)) +function spdiagm(x::AbstractVector, d::Number) + depwarn(string("`spdiagm(x::AbstractVector, d::Number)` is deprecated, use ", + "`spdiagm(d => x)` instead, which now returns a square matrix. To preserve the old ", + "behaviour, use `sparse(SparseArrays.spdiagm_internal(d => x)...)`"), :spdiagm) + I, J, V = spdiagm_internal(d => x) + return sparse(I, J, V) +end +function spdiagm(x, d) + depwarn(string("`spdiagm((x1, x2, ...), (d1, d2, ...))` is deprecated, use ", + "`spdiagm(d1 => x1, d2 => x2, ...)` instead, which now returns a square matrix. ", + "To preserve the old behaviour, use ", + "`sparse(SparseArrays.spdiagm_internal(d1 => x1, d2 => x2, ...)...)`"), :spdiagm) + I, J, V = spdiagm_internal((d[i] => x[i] for i in 1:length(x))...) + return sparse(I, J, V) +end +function spdiagm(x, d, m::Integer, n::Integer) + depwarn(string("`spdiagm((x1, x2, ...), (d1, d2, ...), m, n)` is deprecated, use ", + "`spdiagm(d1 => x1, d2 => x2, ...)` instead, which now returns a square matrix. ", + "To specify a non-square matrix and preserve the old behaviour, use ", + "`I, J, V = SparseArrays.spdiagm_internal(d1 => x1, d2 => x2, ...); sparse(I, J, V, m, n)`"), :spdiagm) + I, J, V = spdiagm_internal((d[i] => x[i] for i in 1:length(x))...) + return sparse(I, J, V, m, n) +end + +@deprecate sparse(s::UniformScaling, m::Integer) sparse(s, m, m) + +# PR #25037 +@deprecate spones(A::SparseMatrixCSC) LinAlg.fillstored!(copy(A), 1) +@deprecate spones(A::SparseVector) LinAlg.fillstored!(copy(A), 1) +export spones + +# full for sparse arrays +import Base: full +function full(S::Union{SparseVector,SparseMatrixCSC}) + (arrtypestr, desttypestr) = + isa(S, SparseVector) ? ("SparseVector", "Vector") : + isa(S, SparseMatrixCSC) ? ("SparseMatrixCSC", "Matrix") : + error("should not be reachable!") + depwarn(string( + "`full(S::$(arrtypestr))` (and `full` in general) has been deprecated. ", + "To replace `full(S::$(arrtypestr))`, consider `$(desttypestr)(S)` or, ", + "if that option is too narrow, `Array(S)`."), :full) + return Array(S) +end + +# issue #22849 +import Base: reinterpret +@deprecate reinterpret(::Type{T}, a::SparseMatrixCSC{S}, dims::NTuple{N,Int}) where {T, S, N} reinterpret(T, reshape(a, dims)) + +# deprecate speye +export speye +function speye(n::Integer) + depwarn(string("`speye(n::Integer)` has been deprecated in favor of `I`, `sparse`, and ", + "`SparseMatrixCSC` constructor methods. For a direct replacement, consider ", + "`sparse(1.0I, n, n)`, `SparseMatrixCSC(1.0I, n, n)`, or `SparseMatrixCSC{Float64}(I, n, n)`. ", + "If `Float64` element type is not necessary, consider the shorter `sparse(I, n, n)` ", + "or `SparseMatrixCSC(I, n, n)` (with default `eltype(I)` of `Bool`)."), :speye) + return sparse(1.0I, n, n) +end +function speye(m::Integer, n::Integer) + depwarn(string("`speye(m::Integer, n::Integer)` has been deprecated in favor of `I`, ", + "`sparse`, and `SparseMatrixCSC` constructor methods. For a direct ", + "replacement, consider `sparse(1.0I, m, n)`, `SparseMatrixCSC(1.0I, m, n)`, ", + "or `SparseMatrixCSC{Float64}(I, m, n)`. If `Float64` element type is not ", + " necessary, consider the shorter `sparse(I, m, n)` or `SparseMatrixCSC(I, m, n)` ", + "(with default `eltype(I)` of `Bool`)."), :speye) + return sparse(1.0I, m, n) +end +function speye(::Type{T}, n::Integer) where T + depwarn(string("`speye(T, n::Integer)` has been deprecated in favor of `I`, `sparse`, and ", + "`SparseMatrixCSC` constructor methods. For a direct replacement, consider ", + "`sparse(T(1)I, n, n)` if `T` is concrete or `SparseMatrixCSC{T}(I, n, n)` ", + "if `T` is either concrete or abstract. If element type `T` is not necessary, ", + "consider the shorter `sparse(I, n, n)` or `SparseMatrixCSC(I, n, n)` ", + "(with default `eltype(I)` of `Bool`)."), :speye) + return SparseMatrixCSC{T}(I, n, n) +end +function speye(::Type{T}, m::Integer, n::Integer) where T + depwarn(string("`speye(T, m::Integer, n::Integer)` has been deprecated in favor of `I`, ", + "`sparse`, and `SparseMatrixCSC` constructor methods. For a direct ", + "replacement, consider `sparse(T(1)I, m, n)` if `T` is concrete or ", + "`SparseMatrixCSC{T}(I, m, n)` if `T` is either concrete or abstract. ", + "If element type `T` is not necessary, consider the shorter ", + "`sparse(I, m, n)` or `SparseMatrixCSC(I, m, n)` (with default `eltype(I)` ", + "of `Bool`)."), :speye) + return SparseMatrixCSC{T}(I, m, n) +end +function speye(S::SparseMatrixCSC{T}) where T + depwarn(string("`speye(S::SparseMatrixCSC{T})` has been deprecated in favor of `I`, ", + "`sparse`, and `SparseMatrixCSC` constructor methods. For a direct ", + "replacement, consider `sparse(T(1)I, size(S)...)` if `T` is concrete or ", + "`SparseMatrixCSC{eltype(S)}(I, size(S))` if `T` is either concrete or abstract. ", + "If preserving element type `T` is not necessary, consider the shorter ", + "`sparse(I, size(S)...)` or `SparseMatrixCSC(I, size(S))` (with default ", + "`eltype(I)` of `Bool`)."), :speye) + return SparseMatrixCSC{T}(I, size(S)...) +end + +# former imports into SparseArrays +import Base: A_mul_B!, Ac_mul_B, Ac_mul_B!, At_mul_B, At_mul_B! +import Base: A_mul_Bc, A_mul_Bt, Ac_mul_Bc, At_mul_Bt +import Base: At_ldiv_B, Ac_ldiv_B, A_ldiv_B! +import Base.LinAlg: At_ldiv_B!, Ac_ldiv_B!, A_rdiv_B!, A_rdiv_Bc!, mul!, ldiv!, rdiv! + +# A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/sparse/linalg.jl, to deprecate +using Base.LinAlg: Adjoint, Transpose +@deprecate Ac_ldiv_B(A::SparseMatrixCSC, B::RowVector) (\)(adjoint(A), B) +@deprecate At_ldiv_B(A::SparseMatrixCSC, B::RowVector) (\)(transpose(A), B) +@deprecate Ac_ldiv_B(A::SparseMatrixCSC, B::AbstractVecOrMat) (\)(adjoint(A), B) +@deprecate At_ldiv_B(A::SparseMatrixCSC, B::AbstractVecOrMat) (\)(transpose(A), B) +@deprecate A_rdiv_Bc!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, adjoint(D)) +@deprecate A_rdiv_Bt!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, transpose(D)) +@deprecate A_rdiv_B!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where {T} rdiv!(A, D) +@deprecate A_ldiv_B!(L::LowerTriangular{T,<:SparseMatrixCSCUnion{T}}, B::StridedVecOrMat) where {T} ldiv!(L, B) +@deprecate A_ldiv_B!(U::UpperTriangular{T,<:SparseMatrixCSCUnion{T}}, B::StridedVecOrMat) where {T} ldiv!(U, B) +@deprecate A_mul_Bt(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(A, transpose(B)) +@deprecate A_mul_Bc(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(A, adjoint(B)) +@deprecate At_mul_B(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(transpose(A), B) +@deprecate Ac_mul_B(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(adjoint(A), B) +@deprecate At_mul_Bt(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(transpose(A), transpose(B)) +@deprecate Ac_mul_Bc(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} (*)(adjoint(A), adjoint(B)) +@deprecate A_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, A, B) +@deprecate Ac_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, adjoint(A), B) +@deprecate At_mul_B!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) mul!(C, transpose(A), B) +@deprecate A_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, A, B, β, C) +@deprecate A_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(A, x) +@deprecate A_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(A, B) +@deprecate Ac_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, adjoint(A), B, β, C) +@deprecate Ac_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(adjoint(A), x) +@deprecate Ac_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(adjoint(A), B) +@deprecate At_mul_B!(α::Number, A::SparseMatrixCSC, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) mul!(α, transpose(A), B, β, C) +@deprecate At_mul_B(A::SparseMatrixCSC{TA,S}, x::StridedVector{Tx}) where {TA,S,Tx} (*)(transpose(A), x) +@deprecate At_mul_B(A::SparseMatrixCSC{TA,S}, B::StridedMatrix{Tx}) where {TA,S,Tx} (*)(transpose(A), B) +@deprecate A_mul_Bt(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(A, transpose(B)) +@deprecate A_mul_Bc(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(A, adjoint(B)) +@deprecate At_mul_B(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(transpose(A), B) +@deprecate Ac_mul_B(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(adjoint(A),B) +@deprecate At_mul_Bt(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(transpose(A), transpose(B)) +@deprecate Ac_mul_Bc(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} (*)(adjoint(A), adjoint(B)) + +# A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/sparse/sparsevector.jl, to deprecate +for isunittri in (true, false), islowertri in (true, false) + unitstr = isunittri ? "Unit" : "" + halfstr = islowertri ? "Lower" : "Upper" + tritype = :(Base.LinAlg.$(Symbol(unitstr, halfstr, "Triangular"))) + @eval #=Base.SparseArrays=# begin + using Base.LinAlg: Adjoint, Transpose + @deprecate At_ldiv_B(A::$tritype{TA,<:AbstractMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(transpose(A), b) + @deprecate At_ldiv_B(A::$tritype{TA,<:StridedMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(transpose(A), b) + @deprecate At_ldiv_B(A::$tritype, b::SparseVector) (\)(transpose(A), b) + @deprecate Ac_ldiv_B(A::$tritype{TA,<:AbstractMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(adjoint(A), b) + @deprecate Ac_ldiv_B(A::$tritype{TA,<:StridedMatrix}, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} (\)(adjoint(A), b) + @deprecate Ac_ldiv_B(A::$tritype, b::SparseVector) (\)(adjoint(A), b) + @deprecate A_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(A, b) + @deprecate At_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(transpose(A), b) + @deprecate Ac_ldiv_B!(A::$tritype{<:Any,<:StridedMatrix}, b::SparseVector) ldiv!(adjoint(A), b) + end +end + +using Base.LinAlg: Adjoint, Transpose +@deprecate Ac_mul_B(A::SparseMatrixCSC, x::AbstractSparseVector) (*)(adjoint(A), x) +@deprecate At_mul_B(A::SparseMatrixCSC, x::AbstractSparseVector) (*)(transpose(A), x) +@deprecate Ac_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, adjoint(A), x, β, y) +@deprecate Ac_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, adjoint(A), x) +@deprecate At_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, transpose(A), x, β, y) +@deprecate At_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, transpose(A), x) +@deprecate A_mul_B!(α::Number, A::SparseMatrixCSC, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, A, x, β, y) +@deprecate A_mul_B!(y::StridedVector{Ty}, A::SparseMatrixCSC, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, A, x) +@deprecate At_mul_B!(α::Number, A::StridedMatrix, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, transpose(A), x, β, y) +@deprecate At_mul_B!(y::StridedVector{Ty}, A::StridedMatrix, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, transpose(A), x) +@deprecate At_mul_B(A::StridedMatrix{Ta}, x::AbstractSparseVector{Tx}) where {Ta,Tx} (*)(transpose(A), x) +@deprecate A_mul_B!(α::Number, A::StridedMatrix, x::AbstractSparseVector, β::Number, y::StridedVector) mul!(α, A, x, β, y) +@deprecate A_mul_B!(y::StridedVector{Ty}, A::StridedMatrix, x::AbstractSparseVector{Tx}) where {Tx,Ty} mul!(y, A, x) + +# methods involving RowVector from base/sparse/linalg.jl, to deprecate +\(::SparseMatrixCSC, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector")) +\(::Adjoint{<:Any,<:SparseMatrixCSC}, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector")) +\(::Transpose{<:Any,<:SparseMatrixCSC}, ::RowVector) = throw(DimensionMismatch("Cannot left-divide matrix by transposed vector")) + +# methods involving RowVector from base/sparse/higherorderfns.jl, to deprecate +@eval SparseArrays.HigherOrderFns begin + BroadcastStyle(::Type{<:Base.RowVector{T,<:Vector}}) where T = Broadcast.MatrixStyle() +end + +import Base: asyncmap +@deprecate asyncmap(f, s::AbstractSparseArray...; kwargs...) sparse(asyncmap(f, map(Array, s)...; kwargs...)) + + +# END 0.7 deprecations + +# BEGIN 1.0 deprecations + +# END 1.0 deprecations diff --git a/base/sparse/higherorderfns.jl b/stdlib/SparseArrays/src/higherorderfns.jl similarity index 100% rename from base/sparse/higherorderfns.jl rename to stdlib/SparseArrays/src/higherorderfns.jl diff --git a/base/sparse/linalg.jl b/stdlib/SparseArrays/src/linalg.jl similarity index 92% rename from base/sparse/linalg.jl rename to stdlib/SparseArrays/src/linalg.jl index 79d15212c89cc..f3b65b5dd5bdb 100644 --- a/base/sparse/linalg.jl +++ b/stdlib/SparseArrays/src/linalg.jl @@ -1,6 +1,5 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Base.LinAlg: Adjoint, Transpose import Base.LinAlg: checksquare ## sparse matrix multiplication @@ -8,17 +7,17 @@ import Base.LinAlg: checksquare *(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} = *(sppromote(A, B)...) *(A::SparseMatrixCSC{TvA,TiA}, transB::Transpose{<:Any,<:SparseMatrixCSC{TvB,TiB}}) where {TvA,TiA,TvB,TiB} = - (B = transB.parent; (pA, pB) = sppromote(A, B); *(pA, Transpose(pB))) + (B = transB.parent; (pA, pB) = sppromote(A, B); *(pA, transpose(pB))) *(A::SparseMatrixCSC{TvA,TiA}, adjB::Adjoint{<:Any,<:SparseMatrixCSC{TvB,TiB}}) where {TvA,TiA,TvB,TiB} = - (B = adjB.parent; (pA, pB) = sppromote(A, B); *(pA, Adjoint(pB))) + (B = adjB.parent; (pA, pB) = sppromote(A, B); *(pA, adjoint(pB))) *(transA::Transpose{<:Any,<:SparseMatrixCSC{TvA,TiA}}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} = - (A = transA.parent; (pA, pB) = sppromote(A, B); *(Transpose(pA), pB)) + (A = transA.parent; (pA, pB) = sppromote(A, B); *(transpose(pA), pB)) *(adjA::Adjoint{<:Any,<:SparseMatrixCSC{TvA,TiA}}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} = - (A = adjA.parent; (pA, pB) = sppromote(A, B); *(Adjoint(pA), pB)) + (A = adjA.parent; (pA, pB) = sppromote(A, B); *(adjoint(pA), pB)) *(transA::Transpose{<:Any,<:SparseMatrixCSC{TvA,TiA}}, transB::Transpose{<:Any,<:SparseMatrixCSC{TvB,TiB}}) where {TvA,TiA,TvB,TiB} = - (A = transA.parent; B = transB.parent; (pA, pB) = sppromote(A, B); *(Transpose(pA), Transpose(pB))) + (A = transA.parent; B = transB.parent; (pA, pB) = sppromote(A, B); *(transpose(pA), transpose(pB))) *(adjA::Adjoint{<:Any,<:SparseMatrixCSC{TvA,TiA}}, adjB::Adjoint{<:Any,<:SparseMatrixCSC{TvB,TiB}}) where {TvA,TiA,TvB,TiB} = - (A = adjA.parent; B = adjB.parent; (pA, pB) = sppromote(A, B); *(Adjoint(pA), Adjoint(pB))) + (A = adjA.parent; B = adjB.parent; (pA, pB) = sppromote(A, B); *(adjoint(pA), adjoint(pB))) function sppromote(A::SparseMatrixCSC{TvA,TiA}, B::SparseMatrixCSC{TvB,TiB}) where {TvA,TiA,TvB,TiB} Tv = promote_type(TvA, TvB) @@ -76,9 +75,9 @@ function mul!(α::Number, adjA::Adjoint{<:Any,<:SparseMatrixCSC}, B::StridedVecO C end *(adjA::Adjoint{<:Any,<:SparseMatrixCSC{TA,S}}, x::StridedVector{Tx}) where {TA,S,Tx} = - (A = adjA.parent; T = promote_type(TA, Tx); mul!(one(T), Adjoint(A), x, zero(T), similar(x, T, A.n))) + (A = adjA.parent; T = promote_type(TA, Tx); mul!(one(T), adjoint(A), x, zero(T), similar(x, T, A.n))) *(adjA::Adjoint{<:Any,<:SparseMatrixCSC{TA,S}}, B::StridedMatrix{Tx}) where {TA,S,Tx} = - (A = adjA.parent; T = promote_type(TA, Tx); mul!(one(T), Adjoint(A), B, zero(T), similar(B, T, (A.n, size(B, 2))))) + (A = adjA.parent; T = promote_type(TA, Tx); mul!(one(T), adjoint(A), B, zero(T), similar(B, T, (A.n, size(B, 2))))) function mul!(α::Number, transA::Transpose{<:Any,<:SparseMatrixCSC}, B::StridedVecOrMat, β::Number, C::StridedVecOrMat) A = transA.parent @@ -102,18 +101,18 @@ function mul!(α::Number, transA::Transpose{<:Any,<:SparseMatrixCSC}, B::Strided C end *(transA::Transpose{<:Any,<:SparseMatrixCSC{TA,S}}, x::StridedVector{Tx}) where {TA,S,Tx} = - (A = transA.parent; T = promote_type(TA, Tx); mul!(one(T), Transpose(A), x, zero(T), similar(x, T, A.n))) + (A = transA.parent; T = promote_type(TA, Tx); mul!(one(T), transpose(A), x, zero(T), similar(x, T, A.n))) *(transA::Transpose{<:Any,<:SparseMatrixCSC{TA,S}}, B::StridedMatrix{Tx}) where {TA,S,Tx} = - (A = transA.parent; T = promote_type(TA, Tx); mul!(one(T), Transpose(A), B, zero(T), similar(B, T, (A.n, size(B, 2))))) + (A = transA.parent; T = promote_type(TA, Tx); mul!(one(T), transpose(A), B, zero(T), similar(B, T, (A.n, size(B, 2))))) # For compatibility with dense multiplication API. Should be deleted when dense multiplication # API is updated to follow BLAS API. mul!(C::StridedVecOrMat, A::SparseMatrixCSC, B::StridedVecOrMat) = mul!(one(eltype(B)), A, B, zero(eltype(C)), C) mul!(C::StridedVecOrMat, adjA::Adjoint{<:Any,<:SparseMatrixCSC}, B::StridedVecOrMat) = - (A = adjA.parent; mul!(one(eltype(B)), Adjoint(A), B, zero(eltype(C)), C)) + (A = adjA.parent; mul!(one(eltype(B)), adjoint(A), B, zero(eltype(C)), C)) mul!(C::StridedVecOrMat, transA::Transpose{<:Any,<:SparseMatrixCSC}, B::StridedVecOrMat) = - (A = transA.parent; mul!(one(eltype(B)), Transpose(A), B, zero(eltype(C)), C)) + (A = transA.parent; mul!(one(eltype(B)), transpose(A), B, zero(eltype(C)), C)) function (*)(X::StridedMatrix{TX}, A::SparseMatrixCSC{TvA,TiA}) where {TX,TvA,TiA} mX, nX = size(X) @@ -139,19 +138,13 @@ end # Sparse matrix multiplication as described in [Gustavson, 1978]: # http://dl.acm.org/citation.cfm?id=355796 -(*)(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = spmatmul(A,B) -*(A::SparseMatrixCSC{Tv,Ti}, transB::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = - (B = transB.parent; spmatmul(A, transpose(B))) -*(A::SparseMatrixCSC{Tv,Ti}, adjB::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = - (B = adjB.parent; spmatmul(A, adjoint(B))) -*(transA::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = - (A = transA.parent; spmatmul(tranpsose(A), B)) -*(adjA::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = - (A = adjA.parent; spmatmul(adjoint(A), B)) -*(transA::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}, transB::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = - (A = transA.parent; B = transB.parent; spmatmul(transpose(A), transpose(B))) -*(adjA::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}, adjB::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = - (A = adjA.parent; B = adjB.parent; spmatmul(adjoint(A), adjoint(B))) +*(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = spmatmul(A,B) +*(A::SparseMatrixCSC{Tv,Ti}, B::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = spmatmul(A, copy(B)) +*(A::SparseMatrixCSC{Tv,Ti}, B::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = spmatmul(A, copy(B)) +*(A::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = spmatmul(copy(A), B) +*(A::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}, B::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = spmatmul(copy(A), B) +*(A::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}, B::Adjoint{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = spmatmul(copy(A), copy(B)) +*(A::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}, B::Transpose{<:Any,<:SparseMatrixCSC{Tv,Ti}}) where {Tv,Ti} = spmatmul(copy(A), copy(B)) function spmatmul(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}; sortindices::Symbol = :sortcols) where {Tv,Ti} @@ -307,7 +300,7 @@ ldiv!(U::UpperTriangular{T,<:SparseMatrixCSCUnion{T}}, B::StridedVecOrMat) where (\)(L::LowerTriangular{T,<:SparseMatrixCSCUnion{T}}, B::SparseMatrixCSC) where {T} = ldiv!(L, Array(B)) (\)(U::UpperTriangular{T,<:SparseMatrixCSCUnion{T}}, B::SparseMatrixCSC) where {T} = ldiv!(U, Array(B)) \(A::Transpose{<:Real,<:Hermitian{<:Real,<:SparseMatrixCSC}}, B::Vector) = A.parent \ B -\(A::Transpose{<:Complex,<:Hermitian{<:Complex,<:SparseMatrixCSC}}, B::Vector) = transpose(A.parent) \ B +\(A::Transpose{<:Complex,<:Hermitian{<:Complex,<:SparseMatrixCSC}}, B::Vector) = copy(A) \ B \(A::Transpose{<:Number,<:Symmetric{<:Number,<:SparseMatrixCSC}}, B::Vector) = A.parent \ B function rdiv!(A::SparseMatrixCSC{T}, D::Diagonal{T}) where T @@ -580,7 +573,7 @@ function cond(A::SparseMatrixCSC, p::Real=2) normA = norm(A, 1) return normA * normAinv elseif p == Inf - normAinv = normestinv(adjoint(A)) + normAinv = normestinv(copy(A')) normA = norm(A, Inf) return normA * normAinv elseif p == 2 @@ -941,27 +934,27 @@ function \(A::SparseMatrixCSC, B::AbstractVecOrMat) return \(qrfact(A), B) end end -for xform in (:Adjoint, :Transpose) +for (xformtype, xformop) in ((:Adjoint, :adjoint), (:Transpose, :transpose)) @eval begin - function \(xformA::($xform){<:Any,<:SparseMatrixCSC}, B::AbstractVecOrMat) + function \(xformA::($xformtype){<:Any,<:SparseMatrixCSC}, B::AbstractVecOrMat) A = xformA.parent m, n = size(A) if m == n if istril(A) if istriu(A) - return \($xform(Diagonal(Vector(diag(A)))), B) + return \($xformop(Diagonal(Vector(diag(A)))), B) else - return \($xform(LowerTriangular(A)), B) + return \($xformop(LowerTriangular(A)), B) end elseif istriu(A) - return \($xform(UpperTriangular(A)), B) + return \($xformop(UpperTriangular(A)), B) end if ishermitian(A) - return \($xform(Hermitian(A)), B) + return \($xformop(Hermitian(A)), B) end - return \($xform(lufact(A)), B) + return \($xformop(lufact(A)), B) else - return \($xform(qrfact(A)), B) + return \($xformop(qrfact(A)), B) end end end diff --git a/base/sparse/sparsematrix.jl b/stdlib/SparseArrays/src/sparsematrix.jl similarity index 98% rename from base/sparse/sparsematrix.jl rename to stdlib/SparseArrays/src/sparsematrix.jl index 7c5c27d49f443..40ce469a5f9d5 100644 --- a/base/sparse/sparsematrix.jl +++ b/stdlib/SparseArrays/src/sparsematrix.jl @@ -729,7 +729,7 @@ end function sparse(D::Diagonal{T}) where T m = length(D.diag) - return SparseMatrixCSC(m, m, collect(1:(m+1)), collect(1:m), Vector{T}(D.diag)) + return SparseMatrixCSC(m, m, Vector(1:(m+1)), Vector(1:m), Vector{T}(D.diag)) end ## Transposition and permutation methods @@ -830,8 +830,10 @@ function ftranspose(A::SparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti} Vector{Tv}(uninitialized, nnz(A))) halfperm!(X, A, 1:A.n, f) end -transpose(A::SparseMatrixCSC) = ftranspose(A, identity) -adjoint(A::SparseMatrixCSC) = ftranspose(A, conj) +adjoint(A::SparseMatrixCSC) = Adjoint(A) +transpose(A::SparseMatrixCSC) = Transpose(A) +Base.copy(A::Adjoint{<:Any,<:SparseMatrixCSC}) = ftranspose(A.parent, conj) +Base.copy(A::Transpose{<:Any,<:SparseMatrixCSC}) = ftranspose(A.parent, identity) """ unchecked_noalias_permute!(X::SparseMatrixCSC{Tv,Ti}, @@ -1272,31 +1274,22 @@ function find(p::Function, S::SparseMatrixCSC) if p(zero(eltype(S))) return invoke(find, Tuple{Function, Any}, p, S) end - sz = size(S) - I, J = _findn(p, S) - return Base._sub2ind(sz, I, J) -end -find(p::Base.OccursIn, x::SparseMatrixCSC) = - invoke(find, Tuple{Base.OccursIn, AbstractArray}, p, x) - -findn(S::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = _findn(x->true, S) -function _findn(p::Function, S::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} numnz = nnz(S) - I = Vector{Ti}(uninitialized, numnz) - J = Vector{Ti}(uninitialized, numnz) + inds = Vector{CartesianIndex{2}}(uninitialized, numnz) count = 1 @inbounds for col = 1 : S.n, k = S.colptr[col] : (S.colptr[col+1]-1) if p(S.nzval[k]) - I[count] = S.rowval[k] - J[count] = col + inds[count] = CartesianIndex(S.rowval[k], col) count += 1 end end - return (I, J) + return inds end +find(p::Base.OccursIn, x::SparseMatrixCSC) = + invoke(find, Tuple{Base.OccursIn, AbstractArray}, p, x) function findnz(S::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} numnz = nnz(S) @@ -1315,7 +1308,38 @@ function findnz(S::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} return (I, J, V) end -import Base.Random.GLOBAL_RNG +function _sparse_findnextnz(m::SparseMatrixCSC, i::Integer) + if i > length(m) + return nothing + end + row, col = Tuple(CartesianIndices(m)[i]) + lo, hi = m.colptr[col], m.colptr[col+1] + n = searchsortedfirst(m.rowval, row, lo, hi-1, Base.Order.Forward) + if lo <= n <= hi-1 + return LinearIndices(m)[m.rowval[n], col] + end + nextcol = findnext(c->(c>hi), m.colptr, col+1) + nextcol === nothing && return nothing + nextlo = m.colptr[nextcol-1] + return LinearIndices(m)[m.rowval[nextlo], nextcol-1] +end + +function _sparse_findprevnz(m::SparseMatrixCSC, i::Integer) + if iszero(i) + return nothing + end + row, col = Tuple(CartesianIndices(m)[i]) + lo, hi = m.colptr[col], m.colptr[col+1] + n = searchsortedlast(m.rowval, row, lo, hi-1, Base.Order.Forward) + if lo <= n <= hi-1 + return LinearIndices(m)[m.rowval[n], col] + end + prevcol = findprev(c->(c rand(r, T, i), T) sprand(r::AbstractRNG, ::Type{Bool}, m::Integer, n::Integer, density::AbstractFloat) = sprand(r,m,n,density, truebools, Bool) -sprand(::Type{T}, m::Integer, n::Integer, density::AbstractFloat) where {T} = sprand(GLOBAL_RNG, T, m, n, density) +sprand(::Type{T}, m::Integer, n::Integer, density::AbstractFloat) where {T} = sprand(defaultRNG(), T, m, n, density) """ sprandn([rng], m[,n],p::AbstractFloat) @@ -1426,7 +1450,7 @@ julia> sprandn(rng, 2, 2, 0.75) ``` """ sprandn(r::AbstractRNG, m::Integer, n::Integer, density::AbstractFloat) = sprand(r,m,n,density,randn,Float64) -sprandn(m::Integer, n::Integer, density::AbstractFloat) = sprandn(GLOBAL_RNG,m,n,density) +sprandn(m::Integer, n::Integer, density::AbstractFloat) = sprandn(defaultRNG(),m,n,density) LinAlg.fillstored!(S::SparseMatrixCSC, x) = (fill!(view(S.nzval, 1:(S.colptr[S.n + 1] - 1)), x); S) diff --git a/base/sparse/sparsevector.jl b/stdlib/SparseArrays/src/sparsevector.jl similarity index 96% rename from base/sparse/sparsevector.jl rename to stdlib/SparseArrays/src/sparsevector.jl index 649b8252062ca..dd9c979bd349b 100644 --- a/base/sparse/sparsevector.jl +++ b/stdlib/SparseArrays/src/sparsevector.jl @@ -2,8 +2,7 @@ ### Common definitions -using Base.LinAlg: Adjoint, Transpose -import Base: scalarmax, scalarmin, sort, find, findnz +import Base: sort, find, findnz import Base.LinAlg: promote_to_array_type, promote_to_arrays_ ### The SparseVector @@ -188,7 +187,7 @@ function sparsevec(I::AbstractVector{<:Integer}, V::AbstractVector, combine::Fun len = i end end - _sparsevector!(collect(I), collect(V), len, combine) + _sparsevector!(Vector(I), Vector(V), len, combine) end function sparsevec(I::AbstractVector{<:Integer}, V::AbstractVector, len::Integer, combine::Function) @@ -197,7 +196,7 @@ function sparsevec(I::AbstractVector{<:Integer}, V::AbstractVector, len::Integer for i in I 1 <= i <= len || throw(ArgumentError("An index is out of bound.")) end - _sparsevector!(collect(I), collect(V), len, combine) + _sparsevector!(Vector(I), Vector(V), len, combine) end sparsevec(I::AbstractVector, V::Union{Number, AbstractVector}, args...) = @@ -473,28 +472,28 @@ copyto!(A::SparseMatrixCSC, B::SparseVector{TvB,TiB}) where {TvB,TiB} = ### Rand Construction -sprand(n::Integer, p::AbstractFloat, rfn::Function, ::Type{T}) where {T} = sprand(GLOBAL_RNG, n, p, rfn, T) +sprand(n::Integer, p::AbstractFloat, rfn::Function, ::Type{T}) where {T} = sprand(defaultRNG(), n, p, rfn, T) function sprand(r::AbstractRNG, n::Integer, p::AbstractFloat, rfn::Function, ::Type{T}) where T I = randsubseq(r, 1:convert(Int, n), p) V = rfn(r, T, length(I)) SparseVector(n, I, V) end -sprand(n::Integer, p::AbstractFloat, rfn::Function) = sprand(GLOBAL_RNG, n, p, rfn) +sprand(n::Integer, p::AbstractFloat, rfn::Function) = sprand(defaultRNG(), n, p, rfn) function sprand(r::AbstractRNG, n::Integer, p::AbstractFloat, rfn::Function) I = randsubseq(r, 1:convert(Int, n), p) V = rfn(r, length(I)) SparseVector(n, I, V) end -sprand(n::Integer, p::AbstractFloat) = sprand(GLOBAL_RNG, n, p, rand) +sprand(n::Integer, p::AbstractFloat) = sprand(defaultRNG(), n, p, rand) sprand(r::AbstractRNG, n::Integer, p::AbstractFloat) = sprand(r, n, p, rand) sprand(r::AbstractRNG, ::Type{T}, n::Integer, p::AbstractFloat) where {T} = sprand(r, n, p, (r, i) -> rand(r, T, i)) sprand(r::AbstractRNG, ::Type{Bool}, n::Integer, p::AbstractFloat) = sprand(r, n, p, truebools) -sprand(::Type{T}, n::Integer, p::AbstractFloat) where {T} = sprand(GLOBAL_RNG, T, n, p) +sprand(::Type{T}, n::Integer, p::AbstractFloat) where {T} = sprand(defaultRNG(), T, n, p) -sprandn(n::Integer, p::AbstractFloat) = sprand(GLOBAL_RNG, n, p, randn) +sprandn(n::Integer, p::AbstractFloat) = sprand(defaultRNG(), n, p, randn) sprandn(r::AbstractRNG, n::Integer, p::AbstractFloat) = sprand(r, n, p, randn) ## Indexing into Matrices can return SparseVectors @@ -735,6 +734,24 @@ function findnz(x::SparseVector{Tv,Ti}) where {Tv,Ti} return (I, V) end +function _sparse_findnextnz(v::SparseVector, i::Integer) + n = searchsortedfirst(v.nzind, i) + if n > length(v.nzind) + return nothing + else + return v.nzind[n] + end +end + +function _sparse_findprevnz(v::SparseVector, i::Integer) + n = searchsortedlast(v.nzind, i) + if iszero(n) + return nothing + else + return v.nzind[n] + end +end + ### Generic functions operating on AbstractSparseVector ### getindex @@ -849,8 +866,8 @@ function SparseMatrixCSC{Tv,Ti}(x::AbstractSparseVector) where {Tv,Ti} colptr = Ti[1, m+1] # Note that this *cannot* share data like normal array conversions, since # modifying one would put the other in an inconsistent state - rowval = collect(Ti, xnzind) - nzval = collect(Tv, xnzval) + rowval = Vector{Ti}(xnzind) + nzval = Vector{Tv}(xnzval) SparseMatrixCSC(n, 1, colptr, rowval, nzval) end @@ -879,12 +896,6 @@ vec(x::AbstractSparseVector) = x copy(x::AbstractSparseVector) = SparseVector(length(x), copy(nonzeroinds(x)), copy(nonzeros(x))) -function reinterpret(::Type{T}, x::AbstractSparseVector{Tv}) where {T,Tv} - sizeof(T) == sizeof(Tv) || - throw(ArgumentError("reinterpret of sparse vectors only supports element types of the same size.")) - SparseVector(length(x), copy(nonzeroinds(x)), reinterpret(T, nonzeros(x))) -end - float(x::AbstractSparseVector{<:AbstractFloat}) = x float(x::AbstractSparseVector) = SparseVector(length(x), copy(nonzeroinds(x)), float(nonzeros(x))) @@ -1594,7 +1605,7 @@ function mul!(α::Number, A::StridedMatrix, x::AbstractSparseVector, β::Number, return y end -# * and mul!(C, Transpose(A), B) +# * and mul!(C, transpose(A), B) function *(transA::Transpose{<:Any,<:StridedMatrix{Ta}}, x::AbstractSparseVector{Tx}) where {Ta,Tx} A = transA.parent @@ -1602,11 +1613,11 @@ function *(transA::Transpose{<:Any,<:StridedMatrix{Ta}}, x::AbstractSparseVector length(x) == m || throw(DimensionMismatch()) Ty = promote_type(Ta, Tx) y = Vector{Ty}(uninitialized, n) - mul!(y, Transpose(A), x) + mul!(y, transpose(A), x) end mul!(y::AbstractVector{Ty}, transA::Transpose{<:Any,<:StridedMatrix}, x::AbstractSparseVector{Tx}) where {Tx,Ty} = - (A = transA.parent; mul!(one(Tx), Transpose(A), x, zero(Ty), y)) + (A = transA.parent; mul!(one(Tx), transpose(A), x, zero(Ty), y)) function mul!(α::Number, transA::Transpose{<:Any,<:StridedMatrix}, x::AbstractSparseVector, β::Number, y::AbstractVector) A = transA.parent @@ -1653,9 +1664,9 @@ function densemv(A::SparseMatrixCSC, x::AbstractSparseVector; trans::Char='N') if trans == 'N' || trans == 'N' mul!(y, A, x) elseif trans == 'T' || trans == 't' - mul!(y, Transpose(A), x) + mul!(y, transpose(A), x) elseif trans == 'C' || trans == 'c' - mul!(y, Adjoint(A), x) + mul!(y, adjoint(A), x) else throw(ArgumentError("Invalid trans character $trans")) end @@ -1698,13 +1709,13 @@ end # * and *(Tranpose(A), B) mul!(y::AbstractVector{Ty}, transA::Transpose{<:Any,<:SparseMatrixCSC}, x::AbstractSparseVector{Tx}) where {Tx,Ty} = - (A = transA.parent; mul!(one(Tx), Transpose(A), x, zero(Ty), y)) + (A = transA.parent; mul!(one(Tx), transpose(A), x, zero(Ty), y)) mul!(α::Number, transA::Transpose{<:Any,<:SparseMatrixCSC}, x::AbstractSparseVector, β::Number, y::AbstractVector) = (A = transA.parent; _At_or_Ac_mul_B!(*, α, A, x, β, y)) mul!(y::AbstractVector{Ty}, adjA::Adjoint{<:Any,<:SparseMatrixCSC}, x::AbstractSparseVector{Tx}) where {Tx,Ty} = - (A = adjA.parent; mul!(one(Tx), Adjoint(A), x, zero(Ty), y)) + (A = adjA.parent; mul!(one(Tx), adjoint(A), x, zero(Ty), y)) mul!(α::Number, adjA::Adjoint{<:Any,<:SparseMatrixCSC}, x::AbstractSparseVector, β::Number, y::AbstractVector) = (A = adjA.parent; _At_or_Ac_mul_B!(dot, α, A, x, β, y)) @@ -1795,25 +1806,25 @@ for isunittri in (true, false), islowertri in (true, false) tritype = :(Base.LinAlg.$(Symbol(unitstr, halfstr, "Triangular"))) # build out-of-place left-division operations - for (istrans, applyxform, xform) in ( - (false, false, :identity), - (true, true, :Transpose), - (true, true, :Adjoint) ) + for (istrans, applyxform, xformtype, xformop) in ( + (false, false, :identity, :identity), + (true, true, :Transpose, :transpose), + (true, true, :Adjoint, :adjoint) ) # broad method where elements are Numbers - xformtritype = applyxform ? :($xform{<:TA,<:$tritype{<:Any,<:AbstractMatrix}}) : + xformtritype = applyxform ? :($xformtype{<:TA,<:$tritype{<:Any,<:AbstractMatrix}}) : :($tritype{<:TA,<:AbstractMatrix}) @eval function \(xformA::$xformtritype, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} A = $(applyxform ? :(xformA.parent) : :(xformA) ) TAb = $(isunittri ? :(typeof(zero(TA)*zero(Tb) + zero(TA)*zero(Tb))) : :(typeof((zero(TA)*zero(Tb) + zero(TA)*zero(Tb))/one(TA))) ) - Base.LinAlg.ldiv!($xform(convert(AbstractArray{TAb}, A)), convert(Array{TAb}, b)) + Base.LinAlg.ldiv!($xformop(convert(AbstractArray{TAb}, A)), convert(Array{TAb}, b)) end # faster method requiring good view support of the # triangular matrix type. hence the StridedMatrix restriction. - xformtritype = applyxform ? :($xform{<:TA,<:$tritype{<:Any,<:StridedMatrix}}) : + xformtritype = applyxform ? :($xformtype{<:TA,<:$tritype{<:Any,<:StridedMatrix}}) : :($tritype{<:TA,<:StridedMatrix}) @eval function \(xformA::$xformtritype, b::SparseVector{Tb}) where {TA<:Number,Tb<:Number} A = $(applyxform ? :(xformA.parent) : :(xformA) ) @@ -1830,25 +1841,25 @@ for isunittri in (true, false), islowertri in (true, false) :(1:b.nzind[end]) ) nzrangeviewr = view(r, nzrange) nzrangeviewA = $tritype(view(A.data, nzrange, nzrange)) - Base.LinAlg.ldiv!($xform(convert(AbstractArray{TAb}, nzrangeviewA)), nzrangeviewr) + Base.LinAlg.ldiv!($xformop(convert(AbstractArray{TAb}, nzrangeviewA)), nzrangeviewr) end r end # fallback where elements are not Numbers - xformtritype = applyxform ? :($xform{<:Any,<:$tritype}) : :($tritype) + xformtritype = applyxform ? :($xformtype{<:Any,<:$tritype}) : :($tritype) @eval function \(xformA::$xformtritype, b::SparseVector) A = $(applyxform ? :(xformA.parent) : :(xformA) ) - Base.LinAlg.ldiv!($xform(A), copy(b)) + Base.LinAlg.ldiv!($xformop(A), copy(b)) end end # build in-place left-division operations - for (istrans, applyxform, xform) in ( - (false, false, :identity), - (true, true, :Transpose), - (true, true, :Adjoint) ) - xformtritype = applyxform ? :($xform{<:Any,<:$tritype{<:Any,<:StridedMatrix}}) : + for (istrans, applyxform, xformtype, xformop) in ( + (false, false, :identity, :identity), + (true, true, :Transpose, :transpose), + (true, true, :Adjoint, :adjoint) ) + xformtritype = applyxform ? :($xformtype{<:Any,<:$tritype{<:Any,<:StridedMatrix}}) : :($tritype{<:Any,<:StridedMatrix}) # the generic in-place left-division methods handle these cases, but @@ -1873,7 +1884,7 @@ for isunittri in (true, false), islowertri in (true, false) :(1:b.nzind[end]) ) nzrangeviewbnz = view(b.nzval, nzrange .- (b.nzind[1] - 1)) nzrangeviewA = $tritype(view(A.data, nzrange, nzrange)) - Base.LinAlg.ldiv!($xform(nzrangeviewA), nzrangeviewbnz) + Base.LinAlg.ldiv!($xformop(nzrangeviewA), nzrangeviewbnz) end b end @@ -1933,8 +1944,8 @@ function sort(x::SparseVector{Tv,Ti}; kws...) where {Tv,Ti} allvals = push!(copy(nonzeros(x)),zero(Tv)) sinds = sortperm(allvals;kws...) n,k = length(x),length(allvals) - z = findfirst(equalto(k),sinds) - newnzind = collect(Ti,1:k-1) + z = findfirst(equalto(k),sinds)::Int + newnzind = Vector{Ti}(1:k-1) newnzind[z:end] .+= n-k+1 newnzvals = allvals[deleteat!(sinds[1:k],z)] SparseVector(n,newnzind,newnzvals) diff --git a/test/sparse/higherorderfns.jl b/stdlib/SparseArrays/test/higherorderfns.jl similarity index 99% rename from test/sparse/higherorderfns.jl rename to stdlib/SparseArrays/test/higherorderfns.jl index 719e9fa83ffdb..1e0516102cf00 100644 --- a/test/sparse/higherorderfns.jl +++ b/stdlib/SparseArrays/test/higherorderfns.jl @@ -4,6 +4,8 @@ # base/sparse/higherorderfns.jl, particularly map[!]/broadcast[!] for SparseVectors and # SparseMatrixCSCs at present. +using Random + @testset "map[!] implementation specialized for a single (input) sparse vector/matrix" begin N, M = 10, 12 for shapeA in ((N,), (N, M)) @@ -415,8 +417,10 @@ end @test broadcast(*, s, V, A, X)::SparseMatrixCSC == sparse(broadcast(*, s, fV, fA, X)) @test broadcast!(*, Z, s, V, A, X) == sparse(broadcast(*, s, fV, fA, X)) # Issue #20954 combinations of sparse arrays and Adjoint/Transpose vectors - @test broadcast(+, A, adjoint(X))::SparseMatrixCSC == sparse(broadcast(+, fA, adjoint(X))) - @test broadcast(*, V, adjoint(X))::SparseMatrixCSC == sparse(broadcast(*, fV, adjoint(X))) + if X isa Vector + @test broadcast(+, A, X')::SparseMatrixCSC == sparse(broadcast(+, fA, X')) + @test broadcast(*, V, X')::SparseMatrixCSC == sparse(broadcast(*, fV, X')) + end end @test V .+ ntuple(identity, N) isa Vector @test A .+ ntuple(identity, N) isa Matrix @@ -427,7 +431,7 @@ end # to the generic AbstractArray broadcast! code (at least for now). N, p = 5, 0.4 A = sprand(N, N, p) - sA = A + transpose(A) + sA = A + copy(A') D = Diagonal(rand(N)) B = Bidiagonal(rand(N), rand(N - 1), :U) T = Tridiagonal(rand(N - 1), rand(N), rand(N - 1)) diff --git a/stdlib/SparseArrays/test/runtests.jl b/stdlib/SparseArrays/test/runtests.jl new file mode 100644 index 0000000000000..e761a2fd34567 --- /dev/null +++ b/stdlib/SparseArrays/test/runtests.jl @@ -0,0 +1,7 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Test, SparseArrays + +include("higherorderfns.jl") +include("sparse.jl") +include("sparsevector.jl") diff --git a/test/sparse/sparse.jl b/stdlib/SparseArrays/test/sparse.jl similarity index 85% rename from test/sparse/sparse.jl rename to stdlib/SparseArrays/test/sparse.jl index 4727949818754..e841b71515ae1 100644 --- a/test/sparse/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -1,7 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Base.LinAlg: mul!, ldiv!, rdiv!, Adjoint, Transpose +using Base.LinAlg: mul!, rdiv! using Base.Printf: @printf +using Random @testset "issparse" begin @test issparse(sparse(fill(1,5,5))) @@ -23,7 +24,7 @@ end end @testset "indtype" begin - @test Base.SparseArrays.indtype(sparse(Int8[1,1],Int8[1,1],[1,1])) == Int8 + @test SparseArrays.indtype(sparse(Int8[1,1],Int8[1,1],[1,1])) == Int8 end @testset "sparse matrix construction" begin @@ -163,7 +164,7 @@ end am = sprand(1, 20, 0.2) av = squeeze(am, 1) @test ndims(av) == 1 - @test all(transpose(av) .== am) + @test all(av' .== am) end end @@ -196,73 +197,73 @@ end @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(mul!(similar(b), a, b) - Array(a)*b)) < 100*eps()) # for compatibility with present matmul API. Should go away eventually. @test (maximum(abs.(mul!(similar(c), a, c) - Array(a)*c)) < 100*eps()) # for compatibility with present matmul API. Should go away eventually. - @test (maximum(abs.(mul!(similar(b), Transpose(a), b) - Transpose(Array(a))*b)) < 100*eps()) # for compatibility with present matmul API. Should go away eventually. - @test (maximum(abs.(mul!(similar(c), Transpose(a), c) - Transpose(Array(a))*c)) < 100*eps()) # for compatibility with present matmul API. Should go away eventually. + @test (maximum(abs.(mul!(similar(b), transpose(a), b) - transpose(Array(a))*b)) < 100*eps()) # for compatibility with present matmul API. Should go away eventually. + @test (maximum(abs.(mul!(similar(c), transpose(a), c) - transpose(Array(a))*c)) < 100*eps()) # for compatibility with present matmul API. Should go away eventually. @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) @test (maximum(abs.((a'*c + d) - (Array(a)'*c + d))) < 1000*eps()) - @test (maximum(abs.((α*Transpose(a)*c + β*d) - (α*Transpose(Array(a))*c + β*d))) < 1000*eps()) - @test (maximum(abs.((Transpose(a)*c + d) - (Transpose(Array(a))*c + d))) < 1000*eps()) + @test (maximum(abs.((α*transpose(a)*c + β*d) - (α*transpose(Array(a))*c + β*d))) < 1000*eps()) + @test (maximum(abs.((transpose(a)*c + d) - (transpose(Array(a))*c + d))) < 1000*eps()) c = randn(6) + im*randn(6) - @test_throws DimensionMismatch α*Transpose(a)*c + β*c - @test_throws DimensionMismatch α*Transpose(a)*fill(1.,5) + β*c + @test_throws DimensionMismatch α*transpose(a)*c + β*c + @test_throws DimensionMismatch α*transpose(a)*fill(1.,5) + β*c a = I + 0.1*sprandn(5, 5, 0.2) + 0.1*im*sprandn(5, 5, 0.2) b = randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) a = I + tril(0.1*sprandn(5, 5, 0.2)) b = randn(5,3) + im*randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) a = I + tril(0.1*sprandn(5, 5, 0.2) + 0.1*im*sprandn(5, 5, 0.2)) b = randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) a = I + triu(0.1*sprandn(5, 5, 0.2)) b = randn(5,3) + im*randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) a = I + triu(0.1*sprandn(5, 5, 0.2) + 0.1*im*sprandn(5, 5, 0.2)) b = randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) a = I + triu(0.1*sprandn(5, 5, 0.2)) b = randn(5,3) + im*randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) # UpperTriangular/LowerTriangular solve a = UpperTriangular(I + triu(0.1*sprandn(5, 5, 0.2))) @@ -282,18 +283,18 @@ end b = randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) b = randn(5,3) + im*randn(5,3) @test (maximum(abs.(a*b - Array(a)*b)) < 100*eps()) @test (maximum(abs.(a'b - Array(a)'b)) < 100*eps()) - @test (maximum(abs.(Transpose(a)*b - Transpose(Array(a))*b)) < 100*eps()) + @test (maximum(abs.(transpose(a)*b - transpose(Array(a))*b)) < 100*eps()) @test (maximum(abs.(a\b - Array(a)\b)) < 1000*eps()) - @test (maximum(abs.(a'\b - Array(adjoint(a))\b)) < 1000*eps()) - @test (maximum(abs.(Transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) + @test (maximum(abs.(a'\b - Array(a')\b)) < 1000*eps()) + @test (maximum(abs.(transpose(a)\b - Array(transpose(a))\b)) < 1000*eps()) end end end @@ -303,8 +304,8 @@ end a = sprand(10, 5, 0.7) b = sprand(5, 15, 0.3) @test maximum(abs.(a*b - Array(a)*Array(b))) < 100*eps() - @test maximum(abs.(Base.SparseArrays.spmatmul(a,b,sortindices=:sortcols) - Array(a)*Array(b))) < 100*eps() - @test maximum(abs.(Base.SparseArrays.spmatmul(a,b,sortindices=:doubletranspose) - Array(a)*Array(b))) < 100*eps() + @test maximum(abs.(SparseArrays.spmatmul(a,b,sortindices=:sortcols) - Array(a)*Array(b))) < 100*eps() + @test maximum(abs.(SparseArrays.spmatmul(a,b,sortindices=:doubletranspose) - Array(a)*Array(b))) < 100*eps() @test Array(kron(a,b)) == kron(Array(a), Array(b)) @test Array(kron(Array(a),b)) == kron(Array(a), Array(b)) @test Array(kron(a,Array(b))) == kron(Array(a), Array(b)) @@ -341,11 +342,11 @@ dA = Array(sA) @testset "inverse scale!" begin bi = inv.(b) - dAt = transpose(dA) - sAt = transpose(sA) + dAt = copy(transpose(dA)) + sAt = copy(transpose(sA)) @test scale!(copy(dAt), bi) ≈ rdiv!(copy(sAt), Diagonal(b)) - @test scale!(copy(dAt), bi) ≈ rdiv!(copy(sAt), Transpose(Diagonal(b))) - @test scale!(copy(dAt), conj(bi)) ≈ rdiv!(copy(sAt), Adjoint(Diagonal(b))) + @test scale!(copy(dAt), bi) ≈ rdiv!(copy(sAt), transpose(Diagonal(b))) + @test scale!(copy(dAt), conj(bi)) ≈ rdiv!(copy(sAt), adjoint(Diagonal(b))) @test_throws DimensionMismatch rdiv!(copy(sAt), Diagonal(fill(1., length(b)+1))) @test_throws LinAlg.SingularException rdiv!(copy(sAt), Diagonal(zeros(length(b)))) end @@ -403,7 +404,7 @@ end (m, n) = (smalldim, smalldim) A = sprand(m, n, nzprob) X = similar(A) - C = transpose(A) + C = copy(transpose(A)) p = randperm(m) q = randperm(n) @testset "common error checking of [c]transpose! methods (ftranspose!)" begin @@ -440,15 +441,15 @@ end @testset "overall functionality of [c]transpose[!] and permute[!]" begin for (m, n) in ((smalldim, smalldim), (smalldim, largedim), (largedim, smalldim)) A = sprand(m, n, nzprob) - At = transpose(A) + At = copy(transpose(A)) # transpose[!] - fullAt = transpose(Array(A)) - @test transpose(A) == fullAt + fullAt = Array(transpose(A)) + @test copy(transpose(A)) == fullAt @test transpose!(similar(At), A) == fullAt # adjoint[!] C = A + im*A/2 - fullCh = adjoint(Array(C)) - @test adjoint(C) == fullCh + fullCh = Array(C') + @test copy(C') == fullCh @test adjoint!(similar(sparse(fullCh)), C) == fullCh # permute[!] p = randperm(m) @@ -466,8 +467,8 @@ end @testset "transpose of SubArrays" begin A = view(sprandn(10, 10, 0.3), 1:4, 1:4) - @test transpose(Array(A)) == Array(transpose(A)) - @test adjoint(Array(A)) == Array(adjoint(A)) + @test copy(transpose(Array(A))) == Array(transpose(A)) + @test copy(adjoint(Array(A))) == Array(adjoint(A)) end @testset "exp" begin @@ -867,7 +868,7 @@ end @test nnz(A) == 13 @test count(!iszero, A) == 3 @test A[lininds] == A[X] == zeros(Int, 10) - c = collect(11:20); c[1] = c[3] = 0 + c = Vector(11:20); c[1] = c[3] = 0 A[lininds] = c @test nnz(A) == 13 @test count(!iszero, A) == 11 @@ -929,47 +930,47 @@ end @test nnz(A) == 19 # Test argument bounds checking for dropstored!(A, i, j) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 0, 1) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 1, 0) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 1, 11) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 11, 1) + @test_throws BoundsError SparseArrays.dropstored!(A, 0, 1) + @test_throws BoundsError SparseArrays.dropstored!(A, 1, 0) + @test_throws BoundsError SparseArrays.dropstored!(A, 1, 11) + @test_throws BoundsError SparseArrays.dropstored!(A, 11, 1) # Test argument bounds checking for dropstored!(A, I, J) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 0:1, 1:1) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 1:1, 0:1) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 10:11, 1:1) - @test_throws BoundsError Base.SparseArrays.dropstored!(A, 1:1, 10:11) + @test_throws BoundsError SparseArrays.dropstored!(A, 0:1, 1:1) + @test_throws BoundsError SparseArrays.dropstored!(A, 1:1, 0:1) + @test_throws BoundsError SparseArrays.dropstored!(A, 10:11, 1:1) + @test_throws BoundsError SparseArrays.dropstored!(A, 1:1, 10:11) # Test behavior of dropstored!(A, i, j) # --> Test dropping a single stored entry - Base.SparseArrays.dropstored!(A, 1, 2) + SparseArrays.dropstored!(A, 1, 2) @test nnz(A) == 18 # --> Test dropping a single nonstored entry - Base.SparseArrays.dropstored!(A, 2, 1) + SparseArrays.dropstored!(A, 2, 1) @test nnz(A) == 18 # Test behavior of dropstored!(A, I, J) and derivs. # --> Test dropping a single row including stored and nonstored entries - Base.SparseArrays.dropstored!(A, 1, :) + SparseArrays.dropstored!(A, 1, :) @test nnz(A) == 9 # --> Test dropping a single column including stored and nonstored entries - Base.SparseArrays.dropstored!(A, :, 2) + SparseArrays.dropstored!(A, :, 2) @test nnz(A) == 0 # --> Introduce nonzeros in rows one and two and columns two and three A[1:2,:] = 1 A[:,2:3] = 2 @test nnz(A) == 36 # --> Test dropping multiple rows containing stored and nonstored entries - Base.SparseArrays.dropstored!(A, 1:3, :) + SparseArrays.dropstored!(A, 1:3, :) @test nnz(A) == 14 # --> Test dropping multiple columns containing stored and nonstored entries - Base.SparseArrays.dropstored!(A, :, 2:4) + SparseArrays.dropstored!(A, :, 2:4) @test nnz(A) == 0 # --> Introduce nonzeros in every other row A[1:2:9, :] = 1 @test nnz(A) == 50 # --> Test dropping a block of the matrix towards the upper left - Base.SparseArrays.dropstored!(A, 2:5, 2:5) + SparseArrays.dropstored!(A, 2:5, 2:5) @test nnz(A) == 42 end @@ -1048,116 +1049,112 @@ end @test iA === iS === nothing end -# findmin/findmax/minumum/maximum +@testset "findmin/findmax/minumum/maximum" begin + A = sparse([1.0 5.0 6.0; + 5.0 2.0 4.0]) + for (tup, rval, rind) in [((1,), [1.0 2.0 4.0], [CartesianIndex(1,1) CartesianIndex(2,2) CartesianIndex(2,3)]), + ((2,), reshape([1.0,2.0], 2, 1), reshape([CartesianIndex(1,1),CartesianIndex(2,2)], 2, 1)), + ((1,2), fill(1.0,1,1),fill(CartesianIndex(1,1),1,1))] + @test findmin(A, tup) == (rval, rind) + end -A = sparse([1.0 5.0 6.0; - 5.0 2.0 4.0]) -for (tup, rval, rind) in [((1,), [1.0 2.0 4.0], [CartesianIndex(1,1) CartesianIndex(2,2) CartesianIndex(2,3)]), - ((2,), reshape([1.0,2.0], 2, 1), reshape([CartesianIndex(1,1),CartesianIndex(2,2)], 2, 1)), - ((1,2), fill(1.0,1,1),fill(CartesianIndex(1,1),1,1))] - @test findmin(A, tup) == (rval, rind) -end + for (tup, rval, rind) in [((1,), [5.0 5.0 6.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(1,3)]), + ((2,), reshape([6.0,5.0], 2, 1), reshape([CartesianIndex(1,3),CartesianIndex(2,1)], 2, 1)), + ((1,2), fill(6.0,1,1),fill(CartesianIndex(1,3),1,1))] + @test findmax(A, tup) == (rval, rind) + end -for (tup, rval, rind) in [((1,), [5.0 5.0 6.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(1,3)]), - ((2,), reshape([6.0,5.0], 2, 1), reshape([CartesianIndex(1,3),CartesianIndex(2,1)], 2, 1)), - ((1,2), fill(6.0,1,1),fill(CartesianIndex(1,3),1,1))] - @test findmax(A, tup) == (rval, rind) -end + #issue 23209 -#issue 23209 + A = sparse([1.0 5.0 6.0; + NaN 2.0 4.0]) + for (tup, rval, rind) in [((1,), [NaN 2.0 4.0], [CartesianIndex(2,1) CartesianIndex(2,2) CartesianIndex(2,3)]), + ((2,), reshape([1.0, NaN], 2, 1), reshape([CartesianIndex(1,1),CartesianIndex(2,1)], 2, 1)), + ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] + @test isequal(findmin(A, tup), (rval, rind)) + end -A = sparse([1.0 5.0 6.0; - NaN 2.0 4.0]) -for (tup, rval, rind) in [((1,), [NaN 2.0 4.0], [CartesianIndex(2,1) CartesianIndex(2,2) CartesianIndex(2,3)]), - ((2,), reshape([1.0, NaN], 2, 1), reshape([CartesianIndex(1,1),CartesianIndex(2,1)], 2, 1)), - ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] - @test isequal(findmin(A, tup), (rval, rind)) -end + for (tup, rval, rind) in [((1,), [NaN 5.0 6.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(1,3)]), + ((2,), reshape([6.0, NaN], 2, 1), reshape([CartesianIndex(1,3),CartesianIndex(2,1)], 2, 1)), + ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] + @test isequal(findmax(A, tup), (rval, rind)) + end -for (tup, rval, rind) in [((1,), [NaN 5.0 6.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(1,3)]), - ((2,), reshape([6.0, NaN], 2, 1), reshape([CartesianIndex(1,3),CartesianIndex(2,1)], 2, 1)), - ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] - @test isequal(findmax(A, tup), (rval, rind)) -end + A = sparse([1.0 NaN 6.0; + NaN 2.0 4.0]) + for (tup, rval, rind) in [((1,), [NaN NaN 4.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(2,3)]), + ((2,), reshape([NaN, NaN], 2, 1), reshape([CartesianIndex(1,2),CartesianIndex(2,1)], 2, 1)), + ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] + @test isequal(findmin(A, tup), (rval, rind)) + end -A = sparse([1.0 NaN 6.0; - NaN 2.0 4.0]) -for (tup, rval, rind) in [((1,), [NaN NaN 4.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(2,3)]), - ((2,), reshape([NaN, NaN], 2, 1), reshape([CartesianIndex(1,2),CartesianIndex(2,1)], 2, 1)), - ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] - @test isequal(findmin(A, tup), (rval, rind)) -end + for (tup, rval, rind) in [((1,), [NaN NaN 6.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(1,3)]), + ((2,), reshape([NaN, NaN], 2, 1), reshape([CartesianIndex(1,2),CartesianIndex(2,1)], 2, 1)), + ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] + @test isequal(findmax(A, tup), (rval, rind)) + end -for (tup, rval, rind) in [((1,), [NaN NaN 6.0], [CartesianIndex(2,1) CartesianIndex(1,2) CartesianIndex(1,3)]), - ((2,), reshape([NaN, NaN], 2, 1), reshape([CartesianIndex(1,2),CartesianIndex(2,1)], 2, 1)), - ((1,2), fill(NaN,1,1),fill(CartesianIndex(2,1),1,1))] - @test isequal(findmax(A, tup), (rval, rind)) -end + A = sparse([Inf -Inf Inf -Inf; + Inf Inf -Inf -Inf]) + for (tup, rval, rind) in [((1,), [Inf -Inf -Inf -Inf], [CartesianIndex(1,1) CartesianIndex(1,2) CartesianIndex(2,3) CartesianIndex(1,4)]), + ((2,), reshape([-Inf -Inf], 2, 1), reshape([CartesianIndex(1,2),CartesianIndex(2,3)], 2, 1)), + ((1,2), fill(-Inf,1,1),fill(CartesianIndex(1,2),1,1))] + @test isequal(findmin(A, tup), (rval, rind)) + end -A = sparse([Inf -Inf Inf -Inf; - Inf Inf -Inf -Inf]) -for (tup, rval, rind) in [((1,), [Inf -Inf -Inf -Inf], [CartesianIndex(1,1) CartesianIndex(1,2) CartesianIndex(2,3) CartesianIndex(1,4)]), - ((2,), reshape([-Inf -Inf], 2, 1), reshape([CartesianIndex(1,2),CartesianIndex(2,3)], 2, 1)), - ((1,2), fill(-Inf,1,1),fill(CartesianIndex(1,2),1,1))] - @test isequal(findmin(A, tup), (rval, rind)) -end + for (tup, rval, rind) in [((1,), [Inf Inf Inf -Inf], [CartesianIndex(1,1) CartesianIndex(2,2) CartesianIndex(1,3) CartesianIndex(1,4)]), + ((2,), reshape([Inf Inf], 2, 1), reshape([CartesianIndex(1,1),CartesianIndex(2,1)], 2, 1)), + ((1,2), fill(Inf,1,1),fill(CartesianIndex(1,1),1,1))] + @test isequal(findmax(A, tup), (rval, rind)) + end -for (tup, rval, rind) in [((1,), [Inf Inf Inf -Inf], [CartesianIndex(1,1) CartesianIndex(2,2) CartesianIndex(1,3) CartesianIndex(1,4)]), - ((2,), reshape([Inf Inf], 2, 1), reshape([CartesianIndex(1,1),CartesianIndex(2,1)], 2, 1)), - ((1,2), fill(Inf,1,1),fill(CartesianIndex(1,1),1,1))] - @test isequal(findmax(A, tup), (rval, rind)) -end + A = sparse([BigInt(10)]) + for (tup, rval, rind) in [((2,), [BigInt(10)], [1])] + @test isequal(findmin(A, tup), (rval, rind)) + end -A = sparse([BigInt(10)]) -for (tup, rval, rind) in [((2,), [BigInt(10)], [1])] - @test isequal(findmin(A, tup), (rval, rind)) -end + for (tup, rval, rind) in [((2,), [BigInt(10)], [1])] + @test isequal(findmax(A, tup), (rval, rind)) + end -for (tup, rval, rind) in [((2,), [BigInt(10)], [1])] - @test isequal(findmax(A, tup), (rval, rind)) -end + A = sparse([BigInt(-10)]) + for (tup, rval, rind) in [((2,), [BigInt(-10)], [1])] + @test isequal(findmin(A, tup), (rval, rind)) + end -A = sparse([BigInt(-10)]) -for (tup, rval, rind) in [((2,), [BigInt(-10)], [1])] - @test isequal(findmin(A, tup), (rval, rind)) -end + for (tup, rval, rind) in [((2,), [BigInt(-10)], [1])] + @test isequal(findmax(A, tup), (rval, rind)) + end -for (tup, rval, rind) in [((2,), [BigInt(-10)], [1])] - @test isequal(findmax(A, tup), (rval, rind)) -end + A = sparse([BigInt(10) BigInt(-10)]) + for (tup, rval, rind) in [((2,), reshape([BigInt(-10)], 1, 1), reshape([CartesianIndex(1,2)], 1, 1))] + @test isequal(findmin(A, tup), (rval, rind)) + end -A = sparse([BigInt(10) BigInt(-10)]) -for (tup, rval, rind) in [((2,), reshape([BigInt(-10)], 1, 1), reshape([CartesianIndex(1,2)], 1, 1))] - @test isequal(findmin(A, tup), (rval, rind)) -end + for (tup, rval, rind) in [((2,), reshape([BigInt(10)], 1, 1), reshape([CartesianIndex(1,1)], 1, 1))] + @test isequal(findmax(A, tup), (rval, rind)) + end -for (tup, rval, rind) in [((2,), reshape([BigInt(10)], 1, 1), reshape([CartesianIndex(1,1)], 1, 1))] - @test isequal(findmax(A, tup), (rval, rind)) + A = sparse(["a", "b"]) + @test_throws MethodError findmin(A, 1) end -A = sparse(["a", "b"]) -@test_throws MethodError findmin(A, 1) - # Support the case when user defined `zero` and `isless` for non-numerical type struct CustomType x::String end Base.zero(::Type{CustomType}) = CustomType("") Base.isless(x::CustomType, y::CustomType) = isless(x.x, y.x) -A = sparse([CustomType("a"), CustomType("b")]) +@testset "findmin/findmax for non-numerical type" begin + A = sparse([CustomType("a"), CustomType("b")]) -for (tup, rval, rind) in [((1,), [CustomType("a")], [1])] - @test isequal(findmin(A, tup), (rval, rind)) -end - -for (tup, rval, rind) in [((1,), [CustomType("b")], [2])] - @test isequal(findmax(A, tup), (rval, rind)) -end + for (tup, rval, rind) in [((1,), [CustomType("a")], [1])] + @test isequal(findmin(A, tup), (rval, rind)) + end -@testset "findn" begin - b = findn( sparse(1.0I, 4, 4) ) - @test (length(b[1]) == 4) - @test (length(b[2]) == 4) + for (tup, rval, rind) in [((1,), [CustomType("b")], [2])] + @test isequal(findmax(A, tup), (rval, rind)) + end end @testset "rotations" begin @@ -1190,9 +1187,9 @@ function test_getindex_algs(A::SparseMatrixCSC{Tv,Ti}, I::AbstractVector, J::Abs ((minj < 1) || (maxj > n)) && BoundsError() end - (alg == 0) ? Base.SparseArrays.getindex_I_sorted_bsearch_A(A, I, J) : - (alg == 1) ? Base.SparseArrays.getindex_I_sorted_bsearch_I(A, I, J) : - Base.SparseArrays.getindex_I_sorted_linear(A, I, J) + (alg == 0) ? SparseArrays.getindex_I_sorted_bsearch_A(A, I, J) : + (alg == 1) ? SparseArrays.getindex_I_sorted_bsearch_I(A, I, J) : + SparseArrays.getindex_I_sorted_linear(A, I, J) end @testset "test_getindex_algs" begin @@ -1313,7 +1310,7 @@ end end @testset "issue #9917" begin - @test sparse(adjoint([])) == reshape(sparse([]), 1, 0) + @test sparse([]') == reshape(sparse([]), 1, 0) @test Array(sparse([])) == zeros(0) @test_throws BoundsError sparse([])[1] @test_throws BoundsError sparse([])[1] = 1 @@ -1396,8 +1393,8 @@ end local A = guardsrand(1234321) do triu(sprand(10, 10, 0.2)) end - @test Base.droptol!(A, 0.01).colptr == [1,1,1,2,2,3,4,6,6,7,9] - @test isequal(Base.droptol!(sparse([1], [1], [1]), 1), SparseMatrixCSC(1, 1, Int[1, 1], Int[], Int[])) + @test SparseArrays.droptol!(A, 0.01).colptr == [1,1,1,2,2,3,4,6,6,7,9] + @test isequal(SparseArrays.droptol!(sparse([1], [1], [1]), 1), SparseMatrixCSC(1, 1, Int[1, 1], Int[], Int[])) end @testset "dropzeros[!]" begin @@ -1487,10 +1484,10 @@ end @testset "expandptr" begin local A = sparse(1.0I, 5, 5) - @test Base.SparseArrays.expandptr(A.colptr) == 1:5 + @test SparseArrays.expandptr(A.colptr) == 1:5 A[1,2] = 1 - @test Base.SparseArrays.expandptr(A.colptr) == [1; 2; 2; 3; 4; 5] - @test_throws ArgumentError Base.SparseArrays.expandptr([2; 3]) + @test SparseArrays.expandptr(A.colptr) == [1; 2; 2; 3; 4; 5] + @test_throws ArgumentError SparseArrays.expandptr([2; 3]) end @testset "triu/tril" begin @@ -1697,18 +1694,18 @@ end Ari = ceil.(Int64, 100*Ar) if Base.USE_GPL_LIBS # NOTE: normestinv is probabilistic, so requires a fixed seed (set above in srand(1234)) - @test Base.SparseArrays.normestinv(Ac,3) ≈ norm(inv(Array(Ac)),1) atol=1e-4 - @test Base.SparseArrays.normestinv(Aci,3) ≈ norm(inv(Array(Aci)),1) atol=1e-4 - @test Base.SparseArrays.normestinv(Ar) ≈ norm(inv(Array(Ar)),1) atol=1e-4 - @test_throws ArgumentError Base.SparseArrays.normestinv(Ac,0) - @test_throws ArgumentError Base.SparseArrays.normestinv(Ac,21) + @test SparseArrays.normestinv(Ac,3) ≈ norm(inv(Array(Ac)),1) atol=1e-4 + @test SparseArrays.normestinv(Aci,3) ≈ norm(inv(Array(Aci)),1) atol=1e-4 + @test SparseArrays.normestinv(Ar) ≈ norm(inv(Array(Ar)),1) atol=1e-4 + @test_throws ArgumentError SparseArrays.normestinv(Ac,0) + @test_throws ArgumentError SparseArrays.normestinv(Ac,21) end - @test_throws DimensionMismatch Base.SparseArrays.normestinv(sprand(3,5,.9)) + @test_throws DimensionMismatch SparseArrays.normestinv(sprand(3,5,.9)) end @testset "issue #13008" begin - @test_throws ArgumentError sparse(collect(1:100), collect(1:100), fill(5,100), 5, 5) - @test_throws ArgumentError sparse(Int[], collect(1:5), collect(1:5)) + @test_throws ArgumentError sparse(Vector(1:100), Vector(1:100), fill(5,100), 5, 5) + @test_throws ArgumentError sparse(Int[], Vector(1:5), Vector(1:5)) end @testset "issue #13024" begin @@ -1746,16 +1743,16 @@ end srand(123) local A A = sparse(Diagonal(rand(5))) + sprandn(5, 5, 0.2) + im*sprandn(5, 5, 0.2) - A = A + adjoint(A) + A = A + copy(A') @test !Base.USE_GPL_LIBS || abs(det(factorize(Hermitian(A)))) ≈ abs(det(factorize(Array(A)))) A = sparse(Diagonal(rand(5))) + sprandn(5, 5, 0.2) + im*sprandn(5, 5, 0.2) A = A*A' @test !Base.USE_GPL_LIBS || abs(det(factorize(Hermitian(A)))) ≈ abs(det(factorize(Array(A)))) A = sparse(Diagonal(rand(5))) + sprandn(5, 5, 0.2) - A = A + transpose(A) + A = A + copy(transpose(A)) @test !Base.USE_GPL_LIBS || abs(det(factorize(Symmetric(A)))) ≈ abs(det(factorize(Array(A)))) A = sparse(Diagonal(rand(5))) + sprandn(5, 5, 0.2) - A = A*Transpose(A) + A = A*transpose(A) @test !Base.USE_GPL_LIBS || abs(det(factorize(Symmetric(A)))) ≈ abs(det(factorize(Array(A)))) @test factorize(triu(A)) == triu(A) @test isa(factorize(triu(A)), UpperTriangular{Float64, SparseMatrixCSC{Float64, Int}}) @@ -1846,13 +1843,13 @@ end m = 5 intmat = fill(1, m, m) ltintmat = LowerTriangular(rand(1:5, m, m)) - @test \(Transpose(ltintmat), sparse(intmat)) ≈ \(Transpose(ltintmat), intmat) + @test \(transpose(ltintmat), sparse(intmat)) ≈ \(transpose(ltintmat), intmat) end # Test temporary fix for issue #16548 in PR #16979. Somewhat brittle. Expect to remove with `\` revisions. @testset "issue #16548" begin ms = methods(\, (SparseMatrixCSC, AbstractVecOrMat)).ms - @test all(m -> m.module == Base.SparseArrays, ms) + @test all(m -> m.module == SparseArrays, ms) end @testset "row indexing a SparseMatrixCSC with non-Int integer type" begin @@ -1864,7 +1861,7 @@ end # are called. (Issue #18705.) EDIT: #19239 unified broadcast over a single sparse matrix, # eliminating the former operation classes. @testset "issue #18705" begin - S = sparse(Diagonal(collect(1.0:5.0))) + S = sparse(Diagonal(1.0:5.0)) @test isa(sin.(S), SparseMatrixCSC) end @@ -1906,31 +1903,31 @@ end # Check that `broadcast` methods specialized for unary operations over # `SparseMatrixCSC`s determine a reasonable return type. @testset "issue #18974" begin - S = sparse(Diagonal(collect(Int64(1):Int64(4)))) + S = sparse(Diagonal(Int64(1):Int64(4))) @test eltype(sin.(S)) == Float64 end # Check calling of unary minus method specialized for SparseMatrixCSCs @testset "issue #19503" begin - @test which(-, (SparseMatrixCSC,)).module == Base.SparseArrays + @test which(-, (SparseMatrixCSC,)).module == SparseArrays end @testset "issue #14398" begin - @test transpose(view(sparse(I, 10, 10), 1:5, 1:5)) ≈ Matrix(I, 5, 5) + @test collect(view(sparse(I, 10, 10), 1:5, 1:5)') ≈ Matrix(I, 5, 5) end @testset "dropstored issue #20513" begin x = sparse(rand(3,3)) - Base.SparseArrays.dropstored!(x, 1, 1) + SparseArrays.dropstored!(x, 1, 1) @test x[1, 1] == 0.0 @test x.colptr == [1, 3, 6, 9] - Base.SparseArrays.dropstored!(x, 2, 1) + SparseArrays.dropstored!(x, 2, 1) @test x.colptr == [1, 2, 5, 8] @test x[2, 1] == 0.0 - Base.SparseArrays.dropstored!(x, 2, 2) + SparseArrays.dropstored!(x, 2, 2) @test x.colptr == [1, 2, 4, 7] @test x[2, 2] == 0.0 - Base.SparseArrays.dropstored!(x, 2, 3) + SparseArrays.dropstored!(x, 2, 3) @test x.colptr == [1, 2, 4, 6] @test x[2, 3] == 0.0 end @@ -1949,47 +1946,47 @@ end @testset "show" begin io = IOBuffer() show(io, MIME"text/plain"(), sparse(Int64[1], Int64[1], [1.0])) - @test String(take!(io)) == "1×1 SparseMatrixCSC{Float64,Int64} with 1 stored entry:\n [1, 1] = 1.0" + @test String(take!(io)) == "1×1 SparseArrays.SparseMatrixCSC{Float64,Int64} with 1 stored entry:\n [1, 1] = 1.0" show(io, MIME"text/plain"(), spzeros(Float32, Int64, 2, 2)) - @test String(take!(io)) == "2×2 SparseMatrixCSC{Float32,Int64} with 0 stored entries" + @test String(take!(io)) == "2×2 SparseArrays.SparseMatrixCSC{Float32,Int64} with 0 stored entries" ioc = IOContext(io, :displaysize => (5, 80), :limit => true) show(ioc, MIME"text/plain"(), sparse(Int64[1], Int64[1], [1.0])) - @test String(take!(io)) == "1×1 SparseMatrixCSC{Float64,Int64} with 1 stored entry:\n [1, 1] = 1.0" + @test String(take!(io)) == "1×1 SparseArrays.SparseMatrixCSC{Float64,Int64} with 1 stored entry:\n [1, 1] = 1.0" show(ioc, MIME"text/plain"(), sparse(Int64[1, 1], Int64[1, 2], [1.0, 2.0])) - @test String(take!(io)) == "1×2 SparseMatrixCSC{Float64,Int64} with 2 stored entries:\n ⋮" + @test String(take!(io)) == "1×2 SparseArrays.SparseMatrixCSC{Float64,Int64} with 2 stored entries:\n ⋮" # even number of rows ioc = IOContext(io, :displaysize => (8, 80), :limit => true) show(ioc, MIME"text/plain"(), sparse(Int64[1,2,3,4], Int64[1,1,2,2], [1.0,2.0,3.0,4.0])) - @test String(take!(io)) == string("4×2 SparseMatrixCSC{Float64,Int64} with 4 stored entries:\n [1, 1]", + @test String(take!(io)) == string("4×2 SparseArrays.SparseMatrixCSC{Float64,Int64} with 4 stored entries:\n [1, 1]", " = 1.0\n [2, 1] = 2.0\n [3, 2] = 3.0\n [4, 2] = 4.0") show(ioc, MIME"text/plain"(), sparse(Int64[1,2,3,4,5], Int64[1,1,2,2,3], [1.0,2.0,3.0,4.0,5.0])) - @test String(take!(io)) == string("5×3 SparseMatrixCSC{Float64,Int64} with 5 stored entries:\n [1, 1]", + @test String(take!(io)) == string("5×3 SparseArrays.SparseMatrixCSC{Float64,Int64} with 5 stored entries:\n [1, 1]", " = 1.0\n ⋮\n [5, 3] = 5.0") show(ioc, MIME"text/plain"(), sparse(fill(1.,5,3))) - @test String(take!(io)) == string("5×3 SparseMatrixCSC{Float64,$Int} with 15 stored entries:\n [1, 1]", + @test String(take!(io)) == string("5×3 SparseArrays.SparseMatrixCSC{Float64,$Int} with 15 stored entries:\n [1, 1]", " = 1.0\n ⋮\n [5, 3] = 1.0") # odd number of rows ioc = IOContext(io, :displaysize => (9, 80), :limit => true) show(ioc, MIME"text/plain"(), sparse(Int64[1,2,3,4,5], Int64[1,1,2,2,3], [1.0,2.0,3.0,4.0,5.0])) - @test String(take!(io)) == string("5×3 SparseMatrixCSC{Float64,Int64} with 5 stored entries:\n [1, 1]", + @test String(take!(io)) == string("5×3 SparseArrays.SparseMatrixCSC{Float64,Int64} with 5 stored entries:\n [1, 1]", " = 1.0\n [2, 1] = 2.0\n [3, 2] = 3.0\n [4, 2] = 4.0\n [5, 3] = 5.0") show(ioc, MIME"text/plain"(), sparse(Int64[1,2,3,4,5,6], Int64[1,1,2,2,3,3], [1.0,2.0,3.0,4.0,5.0,6.0])) - @test String(take!(io)) == string("6×3 SparseMatrixCSC{Float64,Int64} with 6 stored entries:\n [1, 1]", + @test String(take!(io)) == string("6×3 SparseArrays.SparseMatrixCSC{Float64,Int64} with 6 stored entries:\n [1, 1]", " = 1.0\n [2, 1] = 2.0\n ⋮\n [5, 3] = 5.0\n [6, 3] = 6.0") show(ioc, MIME"text/plain"(), sparse(fill(1.,6,3))) - @test String(take!(io)) == string("6×3 SparseMatrixCSC{Float64,$Int} with 18 stored entries:\n [1, 1]", + @test String(take!(io)) == string("6×3 SparseArrays.SparseMatrixCSC{Float64,$Int} with 18 stored entries:\n [1, 1]", " = 1.0\n [2, 1] = 1.0\n ⋮\n [5, 3] = 1.0\n [6, 3] = 1.0") ioc = IOContext(io, :displaysize => (9, 80)) show(ioc, MIME"text/plain"(), sparse(Int64[1,2,3,4,5,6], Int64[1,1,2,2,3,3], [1.0,2.0,3.0,4.0,5.0,6.0])) - @test String(take!(io)) == string("6×3 SparseMatrixCSC{Float64,Int64} with 6 stored entries:\n [1, 1] = 1.0\n", + @test String(take!(io)) == string("6×3 SparseArrays.SparseMatrixCSC{Float64,Int64} with 6 stored entries:\n [1, 1] = 1.0\n", " [2, 1] = 2.0\n [3, 2] = 3.0\n [4, 2] = 4.0\n [5, 3] = 5.0\n [6, 3] = 6.0") end @@ -2012,7 +2009,7 @@ end A = guardsrand(1234) do sprand(5, 5, 1/5) end - A = max.(A, adjoint(A)) + A = max.(A, copy(A')) LinAlg.fillstored!(A, 1) B = A[5:-1:1, 5:-1:1] @test issymmetric(B) @@ -2079,7 +2076,7 @@ end a = sparse(rand(3,3) .+ 0.1) b = similar(a, Float32, Int32) c = similar(b, Float32, Int32) - Base.SparseArrays.dropstored!(b, 1, 1) + SparseArrays.dropstored!(b, 1, 1) @test length(c.rowval) == 9 @test length(c.nzval) == 9 end @@ -2169,6 +2166,37 @@ end @test count(SparseMatrixCSC(2, 2, Int[1, 2, 3], Int[1, 2], Bool[true, true, true])) == 2 end +@testset "sparse findprev/findnext operations" begin + + x = [0,0,0,0,1,0,1,0,1,1,0] + x_sp = sparse(x) + + for i=1:length(x) + @test findnext(!iszero, x,i) == findnext(!iszero, x_sp,i) + @test findprev(!iszero, x,i) == findprev(!iszero, x_sp,i) + end + + y = [0 0 0 0 0; + 1 0 1 0 0; + 1 0 0 0 1; + 0 0 1 0 0; + 1 0 1 1 0] + y_sp = sparse(y) + + for i=1:length(y) + @test findnext(!iszero, y,i) == findnext(!iszero, y_sp,i) + @test findprev(!iszero, y,i) == findprev(!iszero, y_sp,i) + end + + z_sp = sparsevec(Dict(1=>1, 5=>1, 8=>0, 10=>1)) + z = collect(z_sp) + + for i=1:length(z) + @test findnext(!iszero, z,i) == findnext(!iszero, z_sp,i) + @test findprev(!iszero, z,i) == findprev(!iszero, z_sp,i) + end +end + # #20711 @testset "vec returns a view" begin local A = sparse(Matrix(1.0I, 3, 3)) diff --git a/test/sparse/sparsevector.jl b/stdlib/SparseArrays/test/sparsevector.jl similarity index 94% rename from test/sparse/sparsevector.jl rename to stdlib/SparseArrays/test/sparsevector.jl index d2a822cd03226..199f49ab6d963 100644 --- a/test/sparse/sparsevector.jl +++ b/stdlib/SparseArrays/test/sparsevector.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Base.LinAlg: mul!, ldiv!, Adjoint, Transpose +using Base.LinAlg: mul!, ldiv! +using Random ### Data @@ -260,13 +261,13 @@ end @testset "dropstored!" begin x = SparseVector(10, [2, 7, 9], [2.0, 7.0, 9.0]) # Test argument bounds checking for dropstored!(x, i) - @test_throws BoundsError Base.SparseArrays.dropstored!(x, 0) - @test_throws BoundsError Base.SparseArrays.dropstored!(x, 11) + @test_throws BoundsError SparseArrays.dropstored!(x, 0) + @test_throws BoundsError SparseArrays.dropstored!(x, 11) # Test behavior of dropstored!(x, i) # --> Test dropping a single stored entry - @test Base.SparseArrays.dropstored!(x, 2) == SparseVector(10, [7, 9], [7.0, 9.0]) + @test SparseArrays.dropstored!(x, 2) == SparseVector(10, [7, 9], [7.0, 9.0]) # --> Test dropping a single nonstored entry - @test Base.SparseArrays.dropstored!(x, 5) == SparseVector(10, [7, 9], [7.0, 9.0]) + @test SparseArrays.dropstored!(x, 5) == SparseVector(10, [7, 9], [7.0, 9.0]) end @testset "find and findnz" begin @@ -392,7 +393,7 @@ end @test complex(acp) == acp @test isa(acp, SparseVector{ComplexF64,Int}) @test exact_equal(acp, SparseVector(8, [2, 5, 6], complex([12., 35., 72.]))) - @test sparsevec(adjoint(adjoint(acp))) == acp + @test sparsevec((acp')') == acp end @testset "Type conversion" begin @@ -680,7 +681,7 @@ end @test spresvec == op.(densevec) @test all(!iszero, spresvec.nzval) resvaltype = typeof(op(zero(eltype(spvec)))) - resindtype = Base.SparseArrays.indtype(spvec) + resindtype = SparseArrays.indtype(spvec) @test isa(spresvec, SparseVector{resvaltype,resindtype}) end end @@ -696,7 +697,7 @@ end spresvec = op.(spvec) @test spresvec == op.(densevec) resvaltype = typeof(op(zero(eltype(spvec)))) - resindtype = Base.SparseArrays.indtype(spvec) + resindtype = SparseArrays.indtype(spvec) @test isa(spresvec, SparseVector{resvaltype,resindtype}) end end @@ -830,12 +831,12 @@ end for α in [0.0, 1.0, 2.0], β in [0.0, 0.5, 1.0] y = rand(9) rr = α*A'xf + β*y - @test mul!(α, Transpose(A), x, β, y) === y + @test mul!(α, transpose(A), x, β, y) === y @test y ≈ rr end - y = *(Transpose(A), x) + y = *(transpose(A), x) @test isa(y, Vector{Float64}) - @test y ≈ *(Transpose(A), xf) + @test y ≈ *(transpose(A), xf) end end @testset "sparse A * sparse x -> dense y" begin @@ -859,12 +860,12 @@ end for α in [0.0, 1.0, 2.0], β in [0.0, 0.5, 1.0] y = rand(9) rr = α*Af'xf + β*y - @test mul!(α, Transpose(A), x, β, y) === y + @test mul!(α, transpose(A), x, β, y) === y @test y ≈ rr end y = SparseArrays.densemv(A, x; trans='T') @test isa(y, Vector{Float64}) - @test y ≈ *(Transpose(Af), xf) + @test y ≈ *(transpose(Af), xf) end let A = complex.(sprandn(7, 8, 0.5), sprandn(7, 8, 0.5)), @@ -874,7 +875,7 @@ end xf = Array(x) x2f = Array(x2) @test SparseArrays.densemv(A, x; trans='N') ≈ Af * xf - @test SparseArrays.densemv(A, x2; trans='T') ≈ Transpose(Af) * x2f + @test SparseArrays.densemv(A, x2; trans='T') ≈ transpose(Af) * x2f @test SparseArrays.densemv(A, x2; trans='C') ≈ Af'x2f @test_throws ArgumentError SparseArrays.densemv(A, x; trans='D') end @@ -890,7 +891,7 @@ end @test all(nonzeros(y) .!= 0.0) @test Array(y) ≈ Af * xf - y = *(Transpose(A), x2) + y = *(transpose(A), x2) @test isa(y, SparseVector{Float64,Int}) @test all(nonzeros(y) .!= 0.0) @test Array(y) ≈ Af'x2f @@ -907,11 +908,11 @@ end @test isa(y, SparseVector{ComplexF64,Int}) @test Array(y) ≈ Af * xf - y = *(Transpose(A), x2) + y = *(transpose(A), x2) @test isa(y, SparseVector{ComplexF64,Int}) - @test Array(y) ≈ Transpose(Af) * x2f + @test Array(y) ≈ transpose(Af) * x2f - y = *(Adjoint(A), x2) + y = *(adjoint(A), x2) @test isa(y, SparseVector{ComplexF64,Int}) @test Array(y) ≈ Af'x2f end @@ -958,23 +959,23 @@ end # test out-of-place left-division methods for mat in (trimats..., unittrimats...) @test \(mat, spvec) ≈ \(mat, fspvec) - @test \(Adjoint(mat), spvec) ≈ \(Adjoint(mat), fspvec) - @test \(Transpose(mat), spvec) ≈ \(Transpose(mat), fspvec) + @test \(adjoint(mat), spvec) ≈ \(adjoint(mat), fspvec) + @test \(transpose(mat), spvec) ≈ \(transpose(mat), fspvec) end # test in-place left-division methods not involving quotients if eltypevec == typeof(zero(eltypemat)*zero(eltypevec) + zero(eltypemat)*zero(eltypevec)) for mat in unittrimats @test ldiv!(mat, copy(spvec)) ≈ ldiv!(mat, copy(fspvec)) - @test ldiv!(Adjoint(mat), copy(spvec)) ≈ ldiv!(Adjoint(mat), copy(fspvec)) - @test ldiv!(Transpose(mat), copy(spvec)) ≈ ldiv!(Transpose(mat), copy(fspvec)) + @test ldiv!(adjoint(mat), copy(spvec)) ≈ ldiv!(adjoint(mat), copy(fspvec)) + @test ldiv!(transpose(mat), copy(spvec)) ≈ ldiv!(transpose(mat), copy(fspvec)) end end # test in-place left-division methods involving quotients if eltypevec == typeof((zero(eltypemat)*zero(eltypevec) + zero(eltypemat)*zero(eltypevec))/one(eltypemat)) for mat in trimats @test ldiv!(mat, copy(spvec)) ≈ ldiv!(mat, copy(fspvec)) - @test ldiv!(Adjoint(mat), copy(spvec)) ≈ ldiv!(Adjoint(mat), copy(fspvec)) - @test ldiv!(Transpose(mat), copy(spvec)) ≈ ldiv!(Transpose(mat), copy(fspvec)) + @test ldiv!(adjoint(mat), copy(spvec)) ≈ ldiv!(adjoint(mat), copy(fspvec)) + @test ldiv!(transpose(mat), copy(spvec)) ≈ ldiv!(transpose(mat), copy(fspvec)) end end end @@ -984,7 +985,7 @@ end @testset "#16716" begin # The preceding tests miss the edge case where the sparse vector is empty origmat = [-1.5 -0.7; 0.0 1.0] - transmat = transpose(origmat) + transmat = copy(origmat') utmat = UpperTriangular(origmat) ltmat = LowerTriangular(transmat) uutmat = Base.LinAlg.UnitUpperTriangular(origmat) @@ -995,11 +996,11 @@ end for mat in (utmat, ltmat, uutmat, ultmat) @test isequal(\(mat, zerospvec), zerodvec) - @test isequal(\(Adjoint(mat), zerospvec), zerodvec) - @test isequal(\(Transpose(mat), zerospvec), zerodvec) + @test isequal(\(adjoint(mat), zerospvec), zerodvec) + @test isequal(\(transpose(mat), zerospvec), zerodvec) @test isequal(ldiv!(mat, copy(zerospvec)), zerospvec) - @test isequal(ldiv!(Adjoint(mat), copy(zerospvec)), zerospvec) - @test isequal(ldiv!(Transpose(mat), copy(zerospvec)), zerospvec) + @test isequal(ldiv!(adjoint(mat), copy(zerospvec)), zerospvec) + @test isequal(ldiv!(transpose(mat), copy(zerospvec)), zerospvec) end end end @@ -1020,17 +1021,17 @@ end @testset "fkeep!" begin x = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 7) # droptol - xdrop = Base.droptol!(copy(x), 1.5) + xdrop = SparseArrays.droptol!(copy(x), 1.5) @test exact_equal(xdrop, SparseVector(7, [1, 2, 5, 6, 7], [3., 2., -2., -3., 3.])) - Base.droptol!(xdrop, 2.5) + SparseArrays.droptol!(xdrop, 2.5) @test exact_equal(xdrop, SparseVector(7, [1, 6, 7], [3., -3., 3.])) - Base.droptol!(xdrop, 3.) + SparseArrays.droptol!(xdrop, 3.) @test exact_equal(xdrop, SparseVector(7, Int[], Float64[])) xdrop = copy(x) # This will keep index 1, 3, 4, 7 in xdrop f_drop(i, x) = (abs(x) == 1.) || (i in [1, 7]) - Base.SparseArrays.fkeep!(xdrop, f_drop) + SparseArrays.fkeep!(xdrop, f_drop) @test exact_equal(xdrop, SparseVector(7, [1, 3, 4, 7], [3., -1., 1., 3.])) end @testset "dropzeros[!]" begin @@ -1063,7 +1064,7 @@ end # original dropzeros! test xdrop = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 7) xdrop.nzval[[2, 4, 6]] = 0.0 - Base.SparseArrays.dropzeros!(xdrop) + SparseArrays.dropzeros!(xdrop) @test exact_equal(xdrop, SparseVector(7, [1, 3, 5, 7], [3, -1., -2., 3.])) end end @@ -1083,7 +1084,7 @@ sv[1] = 0 # Compare stored zero semantics between SparseVector and SparseMatrixCSC let S = SparseMatrixCSC(10,1,[1,6],[1,3,5,6,7],[0,1,2,0,3]), x = SparseVector(10,[1,3,5,6,7],[0,1,2,0,3]) @test nnz(S) == nnz(x) == 5 - for I = (:, 1:10, collect(1:10)) + for I = (:, 1:10, Vector(1:10)) @test S[I,1] == S[I] == x[I] == x @test nnz(S[I,1]) == nnz(S[I]) == nnz(x[I]) == nnz(x) end @@ -1112,19 +1113,19 @@ end @testset "Issue 14589" begin # test vectors with no zero elements let x = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 7) - @test collect(sort(x)) == sort(collect(x)) + @test Vector(sort(x)) == sort(Vector(x)) end # test vectors with all zero elements let x = sparsevec(Int64[], Float64[], 7) - @test collect(sort(x)) == sort(collect(x)) + @test Vector(sort(x)) == sort(Vector(x)) end # test vector with sparsity approx 1/2 let x = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 15) - @test collect(sort(x)) == sort(collect(x)) + @test Vector(sort(x)) == sort(Vector(x)) # apply three distinct tranformations where zeros sort into start/middle/end - @test collect(sort(x, by=abs)) == sort(collect(x), by=abs) - @test collect(sort(x, by=sign)) == sort(collect(x), by=sign) - @test collect(sort(x, by=inv)) == sort(collect(x), by=inv) + @test Vector(sort(x, by=abs)) == sort(Vector(x), by=abs) + @test Vector(sort(x, by=sign)) == sort(Vector(x), by=sign) + @test Vector(sort(x, by=inv)) == sort(Vector(x), by=inv) end end @testset "fill!" begin @@ -1161,9 +1162,9 @@ mutable struct t20488 end @testset "show" begin io = IOBuffer() show(io, MIME"text/plain"(), sparsevec(Int64[1], [1.0])) - @test String(take!(io)) == "1-element SparseVector{Float64,Int64} with 1 stored entry:\n [1] = 1.0" + @test String(take!(io)) == "1-element SparseArrays.SparseVector{Float64,Int64} with 1 stored entry:\n [1] = 1.0" show(io, MIME"text/plain"(), spzeros(Float64, Int64, 2)) - @test String(take!(io)) == "2-element SparseVector{Float64,Int64} with 0 stored entries" + @test String(take!(io)) == "2-element SparseArrays.SparseVector{Float64,Int64} with 0 stored entries" show(io, similar(sparsevec(rand(3) .+ 0.1), t20488)) @test String(take!(io)) == " [1] = #undef\n [2] = #undef\n [3] = #undef" end diff --git a/stdlib/SuiteSparse/src/SuiteSparse.jl b/stdlib/SuiteSparse/src/SuiteSparse.jl index 6b7558310a1d0..a4b4ad8658f5d 100644 --- a/stdlib/SuiteSparse/src/SuiteSparse.jl +++ b/stdlib/SuiteSparse/src/SuiteSparse.jl @@ -5,7 +5,7 @@ __precompile__(true) module SuiteSparse import Base: \ -import Base.LinAlg: ldiv!, rdiv! +import Base.LinAlg: ldiv! ## Functions to switch to 0-based indexing to call external sparse solvers diff --git a/stdlib/SuiteSparse/src/cholmod.jl b/stdlib/SuiteSparse/src/cholmod.jl index b6b47080c7891..e7656798a5e87 100644 --- a/stdlib/SuiteSparse/src/cholmod.jl +++ b/stdlib/SuiteSparse/src/cholmod.jl @@ -7,18 +7,19 @@ import Base: (*), convert, copy, eltype, getindex, getproperty, show, size, import Base.LinAlg: (\), cholfact, cholfact!, det, diag, ishermitian, isposdef, - issuccess, issymmetric, ldltfact, ldltfact!, logdet, - Adjoint, Transpose + issuccess, issymmetric, ldltfact, ldltfact!, logdet -using ..SparseArrays +using SparseArrays using Base.Printf.@printf +import Libdl + export Dense, Factor, Sparse -import ..SparseArrays: AbstractSparseMatrix, SparseMatrixCSC, indtype, sparse, spzeros, nnz +import SparseArrays: AbstractSparseMatrix, SparseMatrixCSC, indtype, sparse, spzeros, nnz import ..increment, ..increment!, ..decrement, ..decrement! @@ -347,6 +348,9 @@ end Factor(ptr::Ptr{C_Factor{Tv}}) where {Tv<:VTypes} = Factor{Tv}(ptr) Factor(x::Factor) = x +Base.LinAlg.adjoint(F::Factor) = Adjoint(F) +Base.LinAlg.transpose(F::Factor) = Transpose(F) + # All pointer loads should be checked to make sure that SuiteSparse is not called with # a C_NULL pointer which could cause a segfault. Pointers are set to null # when serialized so this can happen when mutiple processes are in use. @@ -1163,7 +1167,7 @@ sparse(FC::FactorComponent{Tv,:LD}) where {Tv} = sparse(Sparse(Factor(FC))) # Calculate the offset into the stype field of the cholmod_sparse_struct and # change the value -let offset = fieldoffset(C_Sparse{Float64}, findfirst(name -> name === :stype, fieldnames(C_Sparse{Float64}))) +let offset = fieldoffset(C_Sparse{Float64}, findfirst(name -> name === :stype, fieldnames(C_Sparse{Float64}))::Int) global change_stype! function change_stype!(A::Sparse, i::Integer) unsafe_store!(convert(Ptr{Cint}, pointer(A)), i, div(offset, 4) + 1) @@ -1319,7 +1323,7 @@ function *(adjA::Adjoint{<:Any,<:Sparse}, B::Sparse) A = adjA.parent aa1 = transpose_(A, 2) if A === B - return *(aa1, Adjoint(aa1)) + return *(aa1, adjoint(aa1)) end ## result of ssmult will have stype==0, contain numerical values and be sorted return ssmult(aa1, B, 0, true, true) @@ -1328,7 +1332,7 @@ end *(adjA::Adjoint{<:Any,<:Sparse}, B::Dense) = (A = adjA.parent; sdmult!(A, true, 1., 0., B, zeros(size(A, 2), size(B, 2)))) *(adjA::Adjoint{<:Any,<:Sparse}, B::VecOrMat) = - (A = adjA.parent; *(Adjoint(A), Dense(B))) + (A = adjA.parent; *(adjoint(A), Dense(B))) ## Factorization methods @@ -1695,7 +1699,7 @@ end \(adjL::Adjoint{<:Any,<:Factor}, B::Dense) = (L = adjL.parent; solve(CHOLMOD_A, L, B)) \(adjL::Adjoint{<:Any,<:Factor}, B::VecOrMat) = (L = adjL.parent; Matrix(solve(CHOLMOD_A, L, Dense(B)))) \(adjL::Adjoint{<:Any,<:Factor}, B::Sparse) = (L = adjL.parent; spsolve(CHOLMOD_A, L, B)) -\(adjL::Adjoint{<:Any,<:Factor}, B::SparseVecOrMat) = (L = adjL.parent; \(Adjoint(L), Sparse(B))) +\(adjL::Adjoint{<:Any,<:Factor}, B::SparseVecOrMat) = (L = adjL.parent; \(adjoint(L), Sparse(B))) const RealHermSymComplexHermF64SSL = Union{ Symmetric{Float64,SparseMatrixCSC{Float64,SuiteSparse_long}}, @@ -1718,13 +1722,13 @@ function \(adjA::Adjoint{<:Any,<:RealHermSymComplexHermF64SSL}, B::StridedVecOrM A = adjA.parent F = cholfact(A) if issuccess(F) - return \(Adjoint(F), B) + return \(adjoint(F), B) else ldltfact!(F, A) if issuccess(F) - return \(Adjoint(F), B) + return \(adjoint(F), B) else - return \(Adjoint(lufact(SparseMatrixCSC{eltype(A), SuiteSparse_long}(A))), B) + return \(adjoint(lufact(SparseMatrixCSC{eltype(A), SuiteSparse_long}(A))), B) end end end diff --git a/stdlib/SuiteSparse/src/deprecated.jl b/stdlib/SuiteSparse/src/deprecated.jl index 974bb6ab5c119..7028d5dfc12f0 100644 --- a/stdlib/SuiteSparse/src/deprecated.jl +++ b/stdlib/SuiteSparse/src/deprecated.jl @@ -2,18 +2,17 @@ # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from src/cholmod.jl, to deprecate @eval SuiteSparse.CHOLMOD begin - using Base.LinAlg: Adjoint, Transpose - Base.Ac_ldiv_B(A::RealHermSymComplexHermF64SSL, B::StridedVecOrMat) = \(Adjoint(A), B) - Base.Ac_ldiv_B(L::Factor, B::Dense) = \(Adjoint(L), B) - Base.Ac_ldiv_B(L::Factor, B::VecOrMat) = \(Adjoint(L), B) - Base.Ac_ldiv_B(L::Factor, B::Sparse) = \(Adjoint(L), B) - Base.Ac_ldiv_B(L::Factor, B::SparseVecOrMat) = \(Adjoint(L), B) - Base.Ac_ldiv_B(L::FactorComponent, B) = \(Adjoint(L), B) - Base.Ac_ldiv_B(L::FactorComponent, B::RowVector) = \(Adjoint(L), B) - Base.Ac_mul_B(A::Sparse, B::Dense) = *(Adjoint(A), B) - Base.Ac_mul_B(A::Sparse, B::VecOrMat) = *(Adjoint(A), B) - Base.Ac_mul_B(A::Sparse, B::Sparse) = *(Adjoint(A), B) - Base.A_mul_Bc(A::Sparse{Tv}, B::Sparse{Tv}) where {Tv<:VRealTypes} = *(A, Adjoint(B)) + Base.Ac_ldiv_B(A::RealHermSymComplexHermF64SSL, B::StridedVecOrMat) = \(adjoint(A), B) + Base.Ac_ldiv_B(L::Factor, B::Dense) = \(adjoint(L), B) + Base.Ac_ldiv_B(L::Factor, B::VecOrMat) = \(adjoint(L), B) + Base.Ac_ldiv_B(L::Factor, B::Sparse) = \(adjoint(L), B) + Base.Ac_ldiv_B(L::Factor, B::SparseVecOrMat) = \(adjoint(L), B) + Base.Ac_ldiv_B(L::FactorComponent, B) = \(adjoint(L), B) + Base.Ac_ldiv_B(L::FactorComponent, B::RowVector) = \(adjoint(L), B) + Base.Ac_mul_B(A::Sparse, B::Dense) = *(adjoint(A), B) + Base.Ac_mul_B(A::Sparse, B::VecOrMat) = *(adjoint(A), B) + Base.Ac_mul_B(A::Sparse, B::Sparse) = *(adjoint(A), B) + Base.A_mul_Bc(A::Sparse{Tv}, B::Sparse{Tv}) where {Tv<:VRealTypes} = *(A, adjoint(B)) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from src/umfpack.jl, to deprecate @@ -22,28 +21,28 @@ end Base.A_ldiv_B!(X::StridedVecOrMat{T}, lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = Base.LinAlg.ldiv!(X, lu, B) Base.At_ldiv_B!(X::StridedVecOrMat{T}, lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = - Base.LinAlg.ldiv!(X, Transpose(lu), B) + Base.LinAlg.ldiv!(X, transpose(lu), B) Base.Ac_ldiv_B!(X::StridedVecOrMat{T}, lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = - Base.LinAlg.ldiv!(X, Adjoint(lu), B) + Base.LinAlg.ldiv!(X, adjoint(lu), B) Base.A_ldiv_B!(X::StridedVecOrMat{Tb}, lu::UmfpackLU{Float64}, B::StridedVecOrMat{Tb}) where {Tb<:Complex} = Base.LinAlg.ldiv!(X, lu, B) Base.At_ldiv_B!(X::StridedVecOrMat{Tb}, lu::UmfpackLU{Float64}, B::StridedVecOrMat{Tb}) where {Tb<:Complex} = - Base.LinAlg.ldiv!(X, Transpose(lu), B) + Base.LinAlg.ldiv!(X, transpose(lu), B) Base.Ac_ldiv_B!(X::StridedVecOrMat{Tb}, lu::UmfpackLU{Float64}, B::StridedVecOrMat{Tb}) where {Tb<:Complex} = - Base.LinAlg.ldiv!(X, Adjoint(lu), B) - Base.A_ldiv_B!(lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = Base.LinAlg.ldiv!(lu, B) - Base.At_ldiv_B!(lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = Base.LinAlg.ldiv!(Transpose(lu), B) - Base.Ac_ldiv_B!(lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = Base.LinAlg.ldiv!(Adjoint(lu), B) - Base.A_ldiv_B!(lu::UmfpackLU{Float64}, B::StridedVecOrMat{<:Complex}) = Base.LinAlg.ldiv!(lu, B) - Base.At_ldiv_B!(lu::UmfpackLU{Float64}, B::StridedVecOrMat{<:Complex}) = Base.LinAlg.ldiv!(Transpose(lu), B) - Base.Ac_ldiv_B!(lu::UmfpackLU{Float64}, B::StridedVecOrMat{<:Complex}) = Base.LinAlg.ldiv!(Adjoint(lu), B) + Base.LinAlg.ldiv!(X, adjoint(lu), B) + Base.A_ldiv_B!(lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = Base.LinAlg.ldiv!(B, lu, copy(B)) + Base.At_ldiv_B!(lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = Base.LinAlg.ldiv!(B, transpose(lu), copy(B)) + Base.Ac_ldiv_B!(lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = Base.LinAlg.ldiv!(B, adjoint(lu), copy(B)) + Base.A_ldiv_B!(lu::UmfpackLU{Float64}, B::StridedVecOrMat{<:Complex}) = Base.LinAlg.ldiv!(B, lu, copy(B)) + Base.At_ldiv_B!(lu::UmfpackLU{Float64}, B::StridedVecOrMat{<:Complex}) = Base.LinAlg.ldiv!(B, transpose(lu), copy(B)) + Base.Ac_ldiv_B!(lu::UmfpackLU{Float64}, B::StridedVecOrMat{<:Complex}) = Base.LinAlg.ldiv!(B, adjoint(lu), copy(B)) end # A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from src/spqr.jl, to deprecate @eval SuiteSparse.SPQR begin using Base.LinAlg: Adjoint, Transpose - Base.A_mul_Bc!(A::StridedMatrix, Q::QRSparseQ) = Base.LinAlg.mul!(A, Adjoint(Q)) - Base.Ac_mul_B!(Q::QRSparseQ, A::StridedVecOrMat) = Base.LinAlg.mul!(Adjoint(Q), A) + Base.A_mul_Bc!(A::StridedMatrix, Q::QRSparseQ) = Base.LinAlg.mul!(A, adjoint(Q)) + Base.Ac_mul_B!(Q::QRSparseQ, A::StridedVecOrMat) = Base.LinAlg.mul!(adjoint(Q), A) Base.A_mul_B!(A::StridedMatrix, Q::QRSparseQ) = Base.LinAlg.mul!(A, Q) Base.A_mul_B!(Q::QRSparseQ, A::StridedVecOrMat) = Base.LinAlg.mul!(Q, A) end diff --git a/stdlib/SuiteSparse/src/spqr.jl b/stdlib/SuiteSparse/src/spqr.jl index 20716c2780561..a2f828659276e 100644 --- a/stdlib/SuiteSparse/src/spqr.jl +++ b/stdlib/SuiteSparse/src/spqr.jl @@ -3,7 +3,6 @@ module SPQR import Base: \ -using Base.LinAlg: Adjoint, Transpose # ordering options */ const ORDERING_FIXED = Int32(0) @@ -22,7 +21,7 @@ const ORDERING_BESTAMD = Int32(9) # try COLAMD and AMD; pick best# # tried. If there is a high fill-in with AMD then try METIS(A'A) and take # the best of AMD and METIS. METIS is not tried if it isn't installed. -using ..SparseArrays: SparseMatrixCSC +using SparseArrays: SparseMatrixCSC using ..SuiteSparse.CHOLMOD using ..SuiteSparse.CHOLMOD: change_stype!, free! @@ -198,7 +197,7 @@ Base.LinAlg.qrfact(A::SparseMatrixCSC; tol = _default_tol(A)) = qrfact(A, Val{tr Base.LinAlg.qr(A::SparseMatrixCSC; tol = _default_tol(A)) = qr(A, Val{true}, tol = tol) -function Base.LinAlg.mul!(Q::QRSparseQ, A::StridedVecOrMat) +function Base.LinAlg.mul2!(Q::QRSparseQ, A::StridedVecOrMat) if size(A, 1) != size(Q, 1) throw(DimensionMismatch("size(Q) = $(size(Q)) but size(A) = $(size(A))")) end @@ -213,7 +212,7 @@ function Base.LinAlg.mul!(Q::QRSparseQ, A::StridedVecOrMat) return A end -function Base.LinAlg.mul!(A::StridedMatrix, Q::QRSparseQ) +function Base.LinAlg.mul1!(A::StridedMatrix, Q::QRSparseQ) if size(A, 2) != size(Q, 1) throw(DimensionMismatch("size(Q) = $(size(Q)) but size(A) = $(size(A))")) end @@ -227,7 +226,7 @@ function Base.LinAlg.mul!(A::StridedMatrix, Q::QRSparseQ) return A end -function Base.LinAlg.mul!(adjQ::Adjoint{<:Any,<:QRSparseQ}, A::StridedVecOrMat) +function Base.LinAlg.mul2!(adjQ::Adjoint{<:Any,<:QRSparseQ}, A::StridedVecOrMat) Q = adjQ.parent if size(A, 1) != size(Q, 1) throw(DimensionMismatch("size(Q) = $(size(Q)) but size(A) = $(size(A))")) @@ -243,7 +242,7 @@ function Base.LinAlg.mul!(adjQ::Adjoint{<:Any,<:QRSparseQ}, A::StridedVecOrMat) return A end -function Base.LinAlg.mul!(A::StridedMatrix, adjQ::Adjoint{<:Any,<:QRSparseQ}) +function Base.LinAlg.mul1!(A::StridedMatrix, adjQ::Adjoint{<:Any,<:QRSparseQ}) Q = adjQ.parent if size(A, 2) != size(Q, 1) throw(DimensionMismatch("size(Q) = $(size(Q)) but size(A) = $(size(A))")) @@ -340,14 +339,14 @@ function (\)(F::QRSparse{Float64}, B::VecOrMat{Complex{Float64}}) # |z2|z4| -> |y1|y2|y3|y4| -> |x2|y2| -> |x2|y2|x4|y4| # |x3|y3| # |x4|y4| - c2r = reshape(transpose(reinterpret(Float64, reshape(B, (1, length(B))))), size(B, 1), 2*size(B, 2)) + c2r = reshape(copy(transpose(reinterpret(Float64, reshape(B, (1, length(B)))))), size(B, 1), 2*size(B, 2)) x = F\c2r # |z1|z3| reinterpret |x1|x2|x3|x4| transpose |x1|y1| reshape |x1|y1|x3|y3| # |z2|z4| <- |y1|y2|y3|y4| <- |x2|y2| <- |x2|y2|x4|y4| # |x3|y3| # |x4|y4| - return collect(reshape(reinterpret(Complex{Float64}, transpose(reshape(x, (length(x) >> 1), 2))), _ret_size(F, B))) + return collect(reshape(reinterpret(Complex{Float64}, copy(transpose(reshape(x, (length(x) >> 1), 2)))), _ret_size(F, B))) end function _ldiv_basic(F::QRSparse, B::StridedVecOrMat) @@ -375,8 +374,8 @@ function _ldiv_basic(F::QRSparse, B::StridedVecOrMat) X0 = view(X, 1:size(B, 1), :) # Apply Q' to B - Base.LinAlg.mul!(Adjoint(F.Q), X0) - + Base.LinAlg.mul2!(adjoint(F.Q), X0) + # Zero out to get basic solution X[rnk + 1:end, :] = 0 diff --git a/stdlib/SuiteSparse/src/umfpack.jl b/stdlib/SuiteSparse/src/umfpack.jl index 5c6ef5b7d3494..02db880d8caaa 100644 --- a/stdlib/SuiteSparse/src/umfpack.jl +++ b/stdlib/SuiteSparse/src/umfpack.jl @@ -6,10 +6,9 @@ export UmfpackLU import Base: (\), findnz, getproperty, show, size import Base.LinAlg: Factorization, det, lufact, ldiv! -using Base.LinAlg: Adjoint, Transpose -using ..SparseArrays -import ..SparseArrays: nnz +using SparseArrays +import SparseArrays: nnz import ..increment, ..increment!, ..decrement, ..decrement! @@ -104,6 +103,9 @@ mutable struct UmfpackLU{Tv<:UMFVTypes,Ti<:UMFITypes} <: Factorization{Tv} nzval::Vector{Tv} end +Base.LinAlg.adjoint(F::UmfpackLU) = Adjoint(F) +Base.LinAlg.transpose(F::UmfpackLU) = Transpose(F) + """ lufact(A::SparseMatrixCSC) -> F::UmfpackLU @@ -345,7 +347,7 @@ for itype in UmfpackIndexTypes Up,Ui,Ux, P, Q, C_NULL, 0, Rs, lu.numeric) - (transpose(SparseMatrixCSC(min(n_row, n_col), n_row, increment!(Lp), increment!(Lj), Lx)), + (copy(transpose(SparseMatrixCSC(min(n_row, n_col), n_row, increment!(Lp), increment!(Lj), Lx))), SparseMatrixCSC(min(n_row, n_col), n_col, increment!(Up), increment!(Ui), Ux), increment!(P), increment!(Q), Rs) end @@ -372,7 +374,7 @@ for itype in UmfpackIndexTypes Up,Ui,Ux,Uz, P, Q, C_NULL, C_NULL, 0, Rs, lu.numeric) - (transpose(SparseMatrixCSC(min(n_row, n_col), n_row, increment!(Lp), increment!(Lj), complex.(Lx, Lz))), + (copy(transpose(SparseMatrixCSC(min(n_row, n_col), n_row, increment!(Lp), increment!(Lj), complex.(Lx, Lz)))), SparseMatrixCSC(min(n_row, n_col), n_col, increment!(Up), increment!(Ui), complex.(Ux, Uz)), increment!(P), increment!(Q), Rs) end @@ -385,18 +387,7 @@ function nnz(lu::UmfpackLU) end ### Solve with Factorization -ldiv!(lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = - ldiv!(B, lu, copy(B)) -ldiv!(translu::Transpose{T,<:UmfpackLU{T}}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = - (lu = translu.parent; ldiv!(B, Transpose(lu), copy(B))) -ldiv!(adjlu::Adjoint{T,<:UmfpackLU{T}}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = - (lu = adjlu.parent; ldiv!(B, Adjoint(lu), copy(B))) -ldiv!(lu::UmfpackLU{Float64}, B::StridedVecOrMat{<:Complex}) = - ldiv!(B, lu, copy(B)) -ldiv!(translu::Transpose{Float64,<:UmfpackLU{Float64}}, B::StridedVecOrMat{<:Complex}) = - (lu = translu.parent; ldiv!(B, Transpose(lu), copy(B))) -ldiv!(adjlu::Adjoint{Float64,<:UmfpackLU{Float64}}, B::StridedVecOrMat{<:Complex}) = - (lu = adjlu.parent; ldiv!(B, Adjoint(lu), copy(B))) +import Base.LinAlg.ldiv! ldiv!(X::StridedVecOrMat{T}, lu::UmfpackLU{T}, B::StridedVecOrMat{T}) where {T<:UMFVTypes} = _Aq_ldiv_B!(X, lu, B, UMFPACK_A) diff --git a/stdlib/SuiteSparse/src/umfpack_h.jl b/stdlib/SuiteSparse/src/umfpack_h.jl index 5d228959cc49c..985f9387fcc75 100644 --- a/stdlib/SuiteSparse/src/umfpack_h.jl +++ b/stdlib/SuiteSparse/src/umfpack_h.jl @@ -4,20 +4,20 @@ ## Type of solve const UMFPACK_A = 0 # Ax=b -const UMFPACK_At = 1 # Adjoint(A)x=b -const UMFPACK_Aat = 2 # Transpose(A)x=b -const UMFPACK_Pt_L = 3 # Adjoint(P)Lx=b +const UMFPACK_At = 1 # adjoint(A)x=b +const UMFPACK_Aat = 2 # transpose(A)x=b +const UMFPACK_Pt_L = 3 # adjoint(P)Lx=b const UMFPACK_L = 4 # Lx=b -const UMFPACK_Lt_P = 5 # Adjoint(L)Px=b -const UMFPACK_Lat_P = 6 # Transpose(L)Px=b -const UMFPACK_Lt = 7 # Adjoint(L)x=b -const UMFPACK_Lat = 8 # Transpose(L)x=b -const UMFPACK_U_Qt = 9 # U*Adjoint(Q)x=b +const UMFPACK_Lt_P = 5 # adjoint(L)Px=b +const UMFPACK_Lat_P = 6 # transpose(L)Px=b +const UMFPACK_Lt = 7 # adjoint(L)x=b +const UMFPACK_Lat = 8 # transpose(L)x=b +const UMFPACK_U_Qt = 9 # U*adjoint(Q)x=b const UMFPACK_U = 10 # Ux=b -const UMFPACK_Q_Ut = 11 # Q*Adjoint(U)x=b -const UMFPACK_Q_Uat = 12 # Q*Transpose(U)x=b -const UMFPACK_Ut = 13 # Adjoint(U)x=b -const UMFPACK_Uat = 14 # Transpose(U)x=b +const UMFPACK_Q_Ut = 11 # Q*adjoint(U)x=b +const UMFPACK_Q_Uat = 12 # Q*transpose(U)x=b +const UMFPACK_Ut = 13 # adjoint(U)x=b +const UMFPACK_Uat = 14 # transpose(U)x=b ## Sizes of Control and Info arrays for returning information from solver const UMFPACK_INFO = 90 diff --git a/stdlib/SuiteSparse/test/cholmod.jl b/stdlib/SuiteSparse/test/cholmod.jl index db792b945ebde..14fd2f4d5c7d4 100644 --- a/stdlib/SuiteSparse/test/cholmod.jl +++ b/stdlib/SuiteSparse/test/cholmod.jl @@ -183,7 +183,7 @@ end @test sparse(cmA'*cmA) ≈ A'*A # A_mul_Ac for symmetric A - A = 0.5*(A + adjoint(A)) + A = 0.5*(A + copy(A')) cmA = CHOLMOD.Sparse(A) @test sparse(cmA*cmA') ≈ A*A' end @@ -374,7 +374,7 @@ end @test_throws ArgumentError cholfact(A1, shift=1.0) @test_throws ArgumentError ldltfact(A1) @test_throws ArgumentError ldltfact(A1, shift=1.0) - C = A1 + adjoint(A1) + C = A1 + copy(adjoint(A1)) λmaxC = eigmax(Array(C)) b = fill(1., size(A1, 1)) @test_throws LinAlg.PosDefException cholfact(C - 2λmaxC*I)\b @@ -396,7 +396,7 @@ end bT = fill(elty(1), 5) @test F'\bT ≈ Array(A1pd)'\b @test F'\sparse(bT) ≈ Array(A1pd)'\b - @test Transpose(F)\bT ≈ conj(A1pd)'\bT + @test transpose(F)\bT ≈ conj(A1pd)'\bT @test F\CHOLMOD.Sparse(sparse(bT)) ≈ A1pd\b @test logdet(F) ≈ logdet(Array(A1pd)) @test det(F) == exp(logdet(F)) @@ -408,7 +408,7 @@ end @test logdet(ldltfact(A1pd)) ≈ logdet(Array(A1pd)) @test isposdef(A1pd) @test !isposdef(A1) - @test !isposdef(A1 + adjoint(A1) |> t -> t - 2eigmax(Array(t))*I) + @test !isposdef(A1 + copy(A1') |> t -> t - 2eigmax(Array(t))*I) if elty <: Real @test CHOLMOD.issymmetric(Sparse(A1pd, 0)) @@ -692,7 +692,7 @@ end @testset "Make sure that ldltfact performs an LDLt (Issue #19032)" begin m, n = 400, 500 A = sprandn(m, n, .2) - M = [I adjoint(A); A -I] + M = [I copy(A'); A -I] b = M * fill(1., m+n) F = ldltfact(M) s = unsafe_load(pointer(F)) @@ -713,8 +713,8 @@ end @test Fs\fill(1., 4) ≈ Fd\fill(1., 4) end -@testset "\\ '\\ and Transpose(...)\\" begin - # Test that \ and '\ and Transpose(...)\ work for Symmetric and Hermitian. This is just +@testset "\\ '\\ and transpose(...)\\" begin + # Test that \ and '\ and transpose(...)\ work for Symmetric and Hermitian. This is just # a dispatch exercise so it doesn't matter that the complex matrix has # zero imaginary parts Apre = sprandn(10, 10, 0.2) - I @@ -725,7 +725,7 @@ end x = fill(1., 10) b = A*x @test x ≈ A\b - @test Transpose(A)\b ≈ A'\b + @test transpose(A)\b ≈ A'\b end end diff --git a/stdlib/SuiteSparse/test/runtests.jl b/stdlib/SuiteSparse/test/runtests.jl index f27f76068991a..861dbb4a00246 100644 --- a/stdlib/SuiteSparse/test/runtests.jl +++ b/stdlib/SuiteSparse/test/runtests.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test -using SuiteSparse +using Test, Random +using SuiteSparse, SparseArrays if Base.USE_GPL_LIBS include("umfpack.jl") diff --git a/stdlib/SuiteSparse/test/spqr.jl b/stdlib/SuiteSparse/test/spqr.jl index 704be55becac1..59ebeff528bbc 100644 --- a/stdlib/SuiteSparse/test/spqr.jl +++ b/stdlib/SuiteSparse/test/spqr.jl @@ -2,7 +2,7 @@ using SuiteSparse.SPQR using SuiteSparse.CHOLMOD -using Base.LinAlg: mul!, Adjoint, Transpose +using Base.LinAlg: mul1!, mul2!, Adjoint, Transpose @testset "Sparse QR" begin m, n = 100, 10 @@ -43,10 +43,10 @@ nn = 100 @test norm(R0[n + 1:end, :], 1) < 1e-12 offsizeA = Matrix{Float64}(I, m+1, m+1) - @test_throws DimensionMismatch mul!(Q, offsizeA) - @test_throws DimensionMismatch mul!(Adjoint(Q), offsizeA) - @test_throws DimensionMismatch mul!(offsizeA, Q) - @test_throws DimensionMismatch mul!(offsizeA, Adjoint(Q)) + @test_throws DimensionMismatch mul2!(Q, offsizeA) + @test_throws DimensionMismatch mul2!(adjoint(Q), offsizeA) + @test_throws DimensionMismatch mul1!(offsizeA, Q) + @test_throws DimensionMismatch mul1!(offsizeA, adjoint(Q)) end @testset "element type of B: $eltyB" for eltyB in (Int, Float64, Complex{Float64}) diff --git a/stdlib/SuiteSparse/test/umfpack.jl b/stdlib/SuiteSparse/test/umfpack.jl index 0f8b9fcfd59a1..e2901cbce3a80 100644 --- a/stdlib/SuiteSparse/test/umfpack.jl +++ b/stdlib/SuiteSparse/test/umfpack.jl @@ -32,7 +32,7 @@ @test A*x ≈ b z = complex.(b) - x = SuiteSparse.ldiv!(lua, z) + x = Base.LinAlg.ldiv!(lua, z) @test x ≈ float([1:5;]) @test z === x y = similar(z) @@ -47,25 +47,25 @@ @test A'*x ≈ b z = complex.(b) - x = SuiteSparse.ldiv!(Adjoint(lua), z) + x = Base.LinAlg.ldiv!(adjoint(lua), z) @test x ≈ float([1:5;]) @test x === z y = similar(x) - SuiteSparse.ldiv!(y, Adjoint(lua), complex.(b)) + Base.LinAlg.ldiv!(y, adjoint(lua), complex.(b)) @test y ≈ x @test A'*x ≈ b - x = Transpose(lua) \ b + x = transpose(lua) \ b @test x ≈ float([1:5;]) - @test Transpose(A) * x ≈ b - x = SuiteSparse.ldiv!(Transpose(lua), complex.(b)) + @test transpose(A) * x ≈ b + x = Base.LinAlg.ldiv!(transpose(lua), complex.(b)) @test x ≈ float([1:5;]) y = similar(x) - SuiteSparse.ldiv!(y, Transpose(lua), complex.(b)) + Base.LinAlg.ldiv!(y, transpose(lua), complex.(b)) @test y ≈ x - @test Transpose(A) * x ≈ b + @test transpose(A) * x ≈ b # Element promotion and type inference @inferred lua\fill(1, size(A, 2)) @@ -84,8 +84,8 @@ @test Ac\b ≈ x b = Ac'*x @test Ac'\b ≈ x - b = Transpose(Ac)*x - @test Transpose(Ac)\b ≈ x + b = transpose(Ac)*x + @test transpose(Ac)\b ≈ x end end @@ -163,8 +163,8 @@ B = complex.(rand(N, N), rand(N, N)) luA, lufA = lufact(A), lufact(Array(A)) @test Base.LinAlg.ldiv!(copy(X), luA, B) ≈ Base.LinAlg.ldiv!(copy(X), lufA, B) - @test Base.LinAlg.ldiv!(copy(X), Adjoint(luA), B) ≈ Base.LinAlg.ldiv!(copy(X), Adjoint(lufA), B) - @test Base.LinAlg.ldiv!(copy(X), Transpose(luA), B) ≈ Base.LinAlg.ldiv!(copy(X), Transpose(lufA), B) + @test Base.LinAlg.ldiv!(copy(X), adjoint(luA), B) ≈ Base.LinAlg.ldiv!(copy(X), adjoint(lufA), B) + @test Base.LinAlg.ldiv!(copy(X), transpose(luA), B) ≈ Base.LinAlg.ldiv!(copy(X), transpose(lufA), B) end end diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 3e0fe0d7c5a5d..6cbdb195d037a 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -18,6 +18,7 @@ module Test export @test, @test_throws, @test_broken, @test_skip, @test_warn, @test_nowarn, @test_logs, @test_deprecated + export @testset # Legacy approximate testing functions, yet to be included export @inferred @@ -27,6 +28,8 @@ export guardsrand, TestSetException import Distributed: myid +using Random: srand, AbstractRNG, GLOBAL_RNG + #----------------------------------------------------------------------- # Backtrace utility functions @@ -36,11 +39,11 @@ end function scrub_backtrace(bt) do_test_ind = findfirst(ip -> ip_has_file_and_func(ip, @__FILE__, (:do_test, :do_test_throws)), bt) - if do_test_ind != 0 && length(bt) > do_test_ind + if do_test_ind !== nothing && length(bt) > do_test_ind bt = bt[do_test_ind + 1:end] end name_ind = findfirst(ip -> ip_has_file_and_func(ip, @__FILE__, (Symbol("macro expansion"),)), bt) - if name_ind != 0 && length(bt) != 0 + if name_ind !== nothing && length(bt) != 0 bt = bt[1:name_ind] end return bt @@ -130,6 +133,10 @@ mutable struct Error <: Result source::LineNumberNode end function Base.show(io::IO, t::Error) + if t.test_type == :test_interrupted + print_with_color(Base.error_color(), io, "Interrupted") + return + end print_with_color(Base.error_color(), io, "Error During Test"; bold = true) print(io, " at ") print_with_color(:default, io, t.source.file, ":", t.source.line, "\n"; bold = true) @@ -666,13 +673,16 @@ record(ts::DefaultTestSet, t::Pass) = (ts.n_passed += 1; t) function record(ts::DefaultTestSet, t::Union{Fail, Error}) if myid() == 1 print_with_color(:white, ts.description, ": ") - print(t) - # don't print the backtrace for Errors because it gets printed in the show - # method - if !isa(t, Error) - Base.show_backtrace(STDOUT, scrub_backtrace(backtrace())) + # don't print for interrupted tests + if !(t isa Error) || t.test_type != :test_interrupted + print(t) + # don't print the backtrace for Errors because it gets printed in the show + # method + if !isa(t, Error) + Base.show_backtrace(STDOUT, scrub_backtrace(backtrace())) + end + println() end - println() end push!(ts.results, t) t, isa(t, Error) || backtrace() @@ -895,6 +905,22 @@ end #----------------------------------------------------------------------- +function _check_testset(testsettype, testsetname) + if !(testsettype isa Type && testsettype <: AbstractTestSet) + error("Expected `$testsetname` to be an AbstractTestSet, it is a ", + typeof(testsettype), ". ", + typeof(testsettype) == String ? + """ + To use `$testsetname` as a testset name, interpolate it into a string, e.g: + @testset "\$$testsetname" begin + ... + end""" + : + "" + ) + end +end + """ @testset [CustomTestSet] [option=val ...] ["description"] begin ... end @testset [CustomTestSet] [option=val ...] ["description \$v"] for v in (...) ... end @@ -965,6 +991,7 @@ function testset_beginend(args, tests, source) # finally removing the testset and giving it a chance to take # action (such as reporting the results) ex = quote + _check_testset($testsettype, $(QuoteNode(testsettype.args[1]))) ts = $(testsettype)($desc; $options...) # this empty loop is here to force the block to be compiled, # which is needed for backtrace scrubbing to work correctly. @@ -973,17 +1000,17 @@ function testset_beginend(args, tests, source) # we reproduce the logic of guardsrand, but this function # cannot be used as it changes slightly the semantic of @testset, # by wrapping the body in a function - oldrng = copy(Base.GLOBAL_RNG) + oldrng = copy(GLOBAL_RNG) try # GLOBAL_RNG is re-seeded with its own seed to ease reproduce a failed test - srand(Base.GLOBAL_RNG.seed) + srand(GLOBAL_RNG.seed) $(esc(tests)) catch err # something in the test block threw an error. Count that as an # error in this test set record(ts, Error(:nontest_error, :(), err, catch_backtrace(), $(QuoteNode(source)))) finally - copy!(Base.GLOBAL_RNG, oldrng) + copy!(GLOBAL_RNG, oldrng) end pop_testset() finish(ts) @@ -1035,13 +1062,14 @@ function testset_forloop(args, testloop, source) # wrapped in the outer loop provided by the user tests = testloop.args[2] blk = quote + _check_testset($testsettype, $(QuoteNode(testsettype.args[1]))) # Trick to handle `break` and `continue` in the test code before # they can be handled properly by `finally` lowering. if !first_iteration pop_testset() push!(arr, finish(ts)) # it's 1000 times faster to copy from tmprng rather than calling srand - copy!(Base.GLOBAL_RNG, tmprng) + copy!(GLOBAL_RNG, tmprng) end ts = $(testsettype)($desc; $options...) @@ -1059,9 +1087,9 @@ function testset_forloop(args, testloop, source) arr = Vector{Any}() local first_iteration = true local ts - local oldrng = copy(Base.GLOBAL_RNG) - srand(Base.GLOBAL_RNG.seed) - local tmprng = copy(Base.GLOBAL_RNG) + local oldrng = copy(GLOBAL_RNG) + srand(GLOBAL_RNG.seed) + local tmprng = copy(GLOBAL_RNG) try $(Expr(:for, Expr(:block, [esc(v) for v in loopvars]...), blk)) finally @@ -1070,7 +1098,7 @@ function testset_forloop(args, testloop, source) pop_testset() push!(arr, finish(ts)) end - copy!(Base.GLOBAL_RNG, oldrng) + copy!(GLOBAL_RNG, oldrng) end arr end @@ -1269,12 +1297,7 @@ want to set this to `false`. See [`Base.isambiguous`](@ref). function detect_ambiguities(mods...; imported::Bool = false, recursive::Bool = false, - ambiguous_bottom::Bool = false, - allow_bottom::Union{Bool,Nothing} = nothing) - if allow_bottom !== nothing - Base.depwarn("the `allow_bottom` keyword to detect_ambiguities has been renamed to `ambiguous_bottom`", :detect_ambiguities) - ambiguous_bottom = allow_bottom - end + ambiguous_bottom::Bool = false) function sortdefs(m1, m2) ord12 = m1.file < m2.file if !ord12 && (m1.file == m2.file) @@ -1486,7 +1509,7 @@ Base.similar(A::GenericArray, s::Integer...) = GenericArray(similar(A.a, s...)) "`guardsrand(f)` runs the function `f()` and then restores the state of the global RNG as it was before." -function guardsrand(f::Function, r::AbstractRNG=Base.GLOBAL_RNG) +function guardsrand(f::Function, r::AbstractRNG=GLOBAL_RNG) old = copy(r) try f() diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 40cc539dd6a43..56ba8e8a15fd7 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test, Distributed +using Test, Distributed, Random import Logging: Debug, Info, Warn @@ -614,7 +614,7 @@ end @testset "test guarded srand" begin seed = rand(UInt) - orig = copy(Base.GLOBAL_RNG) + orig = copy(Random.GLOBAL_RNG) @test guardsrand(()->rand(), seed) == guardsrand(()->rand(), seed) @test guardsrand(()->rand(Int), seed) == guardsrand(()->rand(Int), seed) r1, r2 = MersenneTwister(0), MersenneTwister(0) @@ -628,7 +628,7 @@ end end::Tuple{Float64,Int} @test a == c == rand(r1) == rand(r2) @test b == d == rand(r1, Int) == rand(r2, Int) - @test orig == Base.GLOBAL_RNG + @test orig == Random.GLOBAL_RNG @test rand(orig) == rand() end @@ -756,3 +756,19 @@ end @test a == rand() @test b == rand() end + +@testset "non AbstractTestSet as testset" begin + local f, err = tempname(), tempname() + write(f, + """ + using Test + desc = "description" + @testset desc begin + @test 1==1 + end + """) + run(pipeline(ignorestatus(`$(Base.julia_cmd()) --startup-file=no --color=no $f`), stderr=err)) + msg = read(err, String) + @test contains(msg, "Expected `desc` to be an AbstractTestSet, it is a String") + rm(f; force=true) +end diff --git a/stdlib/Unicode/docs/src/index.md b/stdlib/Unicode/docs/src/index.md index 4f519aa0bc05e..aba9d80c3e8b5 100644 --- a/stdlib/Unicode/docs/src/index.md +++ b/stdlib/Unicode/docs/src/index.md @@ -4,22 +4,4 @@ Unicode.isassigned Unicode.normalize Unicode.graphemes -Unicode.uppercase -Unicode.lowercase -Unicode.titlecase -Unicode.ucfirst -Unicode.lcfirst -Unicode.textwidth -Unicode.isalnum -Unicode.isalpha -Unicode.iscntrl -Unicode.isdigit -Unicode.isgraph -Unicode.islower -Unicode.isnumeric -Unicode.isprint -Unicode.ispunct -Unicode.isspace -Unicode.isupper -Unicode.isxdigit ``` diff --git a/stdlib/Unicode/src/Unicode.jl b/stdlib/Unicode/src/Unicode.jl index 59077acb6a79c..9a1ce248dc95a 100644 --- a/stdlib/Unicode/src/Unicode.jl +++ b/stdlib/Unicode/src/Unicode.jl @@ -4,19 +4,12 @@ __precompile__(true) module Unicode -using Base.Unicode: normalize, graphemes, isassigned, textwidth, isvalid, - islower, isupper, isalpha, isdigit, isxdigit, isnumeric, isalnum, - iscntrl, ispunct, isspace, isprint, isgraph, - lowercase, uppercase, titlecase, lcfirst, ucfirst +using Base.Unicode: normalize, graphemes, isassigned, iscased -export graphemes, textwidth, isvalid, - islower, isupper, isalpha, isdigit, isxdigit, isnumeric, isalnum, - iscntrl, ispunct, isspace, isprint, isgraph, - lowercase, uppercase, titlecase, lcfirst, ucfirst +export graphemes # BEGIN 0.7 deprecations -@deprecate isnumber(c::Char) Unicode.isnumeric(c) @deprecate is_assigned_char(c::Char) Unicode.isassigned(c) @deprecate normalize_string(s::AbstractString, nf::Symbol; kwargs...) Unicode.normalize(s, nf; kwargs...) @deprecate normalize_string(s::AbstractString; kwargs...) Unicode.normalize(s; kwargs...) diff --git a/stdlib/Unicode/test/runtests.jl b/stdlib/Unicode/test/runtests.jl index dacf266ccbaef..e28f03cb7c941 100644 --- a/stdlib/Unicode/test/runtests.jl +++ b/stdlib/Unicode/test/runtests.jl @@ -2,7 +2,7 @@ using Test using Unicode -using Unicode: normalize, isassigned +using Unicode: normalize, isassigned, iscased @testset "string normalization" begin # normalize (Unicode normalization etc.): @@ -131,7 +131,7 @@ end alnums=vcat(alphas,anumber,unumber) for c in alnums - @test isalnum(c) == true + @test isalpha(c) || isnumeric(c) @test ispunct(c) == false end @@ -143,12 +143,11 @@ end for c in vcat(apunct,upunct) @test ispunct(c) == true - @test isalnum(c) == false + @test !isalpha(c) && !isnumeric(c) end for c in vcat(alnums,asymbol,usymbol,apunct,upunct) @test isprint(c) == true - @test isgraph(c) == true @test isspace(c) == false @test iscntrl(c) == false end @@ -165,13 +164,11 @@ end for c in vcat(aspace,uspace) @test isspace(c) == true @test isprint(c) == true - @test isgraph(c) == false end for c in vcat(acntrl_space) @test isspace(c) == true @test isprint(c) == false - @test isgraph(c) == false end @test isspace(ZWSPACE) == false # zero-width space @@ -182,23 +179,20 @@ end for c in vcat(acontrol, acntrl_space, latincontrol) @test iscntrl(c) == true - @test isalnum(c) == false + @test !isalpha(c) && !isnumeric(c) @test isprint(c) == false - @test isgraph(c) == false end for c in ucontrol #non-latin1 controls if c!=Char(0x0085) @test iscntrl(c) == false @test isspace(c) == false - @test isalnum(c) == false + @test !isalpha(c) && !isnumeric(c) @test isprint(c) == false - @test isgraph(c) == false end end @test all(isspace," \t \n \r ") - @test !all(isgraph," \t \n \r ") @test !all(isprint," \t \n \r ") @test !all(isalpha," \t \n \r ") @test !all(isnumeric," \t \n \r ") @@ -206,7 +200,6 @@ end @test !all(isspace,"ΣβΣβ") @test all(isalpha,"ΣβΣβ") - @test all(isgraph,"ΣβΣβ") @test all(isprint,"ΣβΣβ") @test !all(isupper,"ΣβΣβ") @test !all(islower,"ΣβΣβ") @@ -216,7 +209,6 @@ end @test all(isnumeric,"23435") @test all(isdigit,"23435") - @test all(isalnum,"23435") @test !all(isalpha,"23435") @test all(iscntrl,string(Char(0x0080))) @test all(ispunct, "‡؟჻") @@ -293,11 +285,16 @@ end @test_throws ArgumentError normalize("\u006e\u0303", compose=false, stripmark=true) end -@testset "fastplus" begin - @test lowercase('A') == 'a' - @test uppercase('a') == 'A' - +@testset "isassigned" begin + @test isassigned('\x00') @test isassigned('A') + @test isassigned('α') + @test isassigned('柒') + @test !isassigned('\ufffe') + @test !isassigned('\uffff') + @test !isassigned("\xf4\x90\x80\x80"[1]) + @test !isassigned("\xf7\xbf\xbf\xbf"[1]) + @test !isassigned("\xff"[1]) end @testset "isspace" begin @@ -366,8 +363,14 @@ end @testset "titlecase" begin @test titlecase('lj') == 'Lj' @test titlecase("ljubljana") == "Ljubljana" - @test titlecase("aBc ABC") == "ABc ABC" - @test titlecase("abcD EFG\n\thij") == "AbcD EFG\n\tHij" + @test titlecase("aBc ABC") == "Abc Abc" + @test titlecase("aBc ABC", strict=true) == "Abc Abc" + @test titlecase("aBc ABC", strict=false) == "ABc ABC" + @test titlecase("abcD EFG\n\thij", strict=true) == "Abcd Efg\n\tHij" + @test titlecase("abcD EFG\n\thij", strict=false) == "AbcD EFG\n\tHij" + @test titlecase("abc-def") == "Abc-Def" + @test titlecase("abc-def", wordsep = !iscased) == "Abc-Def" + @test titlecase("abc-def", wordsep = isspace) == "Abc-def" end end diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 910372bf4a077..c30f702536a78 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random, SparseArrays + A = rand(5,4,3) @testset "Bounds checking" begin @test checkbounds(Bool, A, 1, 1, 1) == true @@ -117,6 +119,8 @@ end @test LinearIndices()[1] == 1 @test_throws BoundsError LinearIndices()[2] @test LinearIndices()[1,1] == 1 + @test LinearIndices()[] == 1 + @test size(LinearIndices()) == () @test CartesianIndices()[1] == CartesianIndex() @test_throws BoundsError CartesianIndices()[2] end @@ -127,6 +131,8 @@ end @test CartesianIndices((3,))[i] == CartesianIndex(i,) end @test LinearIndices((3,))[2,1] == 2 + @test LinearIndices((3,))[[1]] == [1] + @test size(LinearIndices((3,))) == (3,) @test_throws BoundsError CartesianIndices((3,))[2,2] # ambiguity btw cartesian indexing and linear indexing in 1d when # indices may be nontraditional @@ -138,26 +144,43 @@ end k = 0 cartesian = CartesianIndices((4,3)) linear = LinearIndices(cartesian) + @test size(cartesian) == size(linear) == (4, 3) for j = 1:3, i = 1:4 - @test linear[i,j] == (k+=1) + k += 1 + @test linear[i,j] == linear[k] == k @test cartesian[k] == CartesianIndex(i,j) @test LinearIndices(0:3,3:5)[i-1,j+2] == k @test CartesianIndices(0:3,3:5)[k] == CartesianIndex(i-1,j+2) end + @test linear[linear] == linear + @test linear[vec(linear)] == vec(linear) + @test linear[cartesian] == linear + @test linear[vec(cartesian)] == vec(linear) + @test cartesian[linear] == cartesian + @test cartesian[vec(linear)] == vec(cartesian) + @test cartesian[cartesian] == cartesian + @test cartesian[vec(cartesian)] == vec(cartesian) end @testset "3-dimensional" begin l = 0 for k = 1:2, j = 1:3, i = 1:4 - @test LinearIndices((4,3,2))[i,j,k] == (l+=1) + l += 1 + @test LinearIndices((4,3,2))[i,j,k] == l + @test LinearIndices((4,3,2))[l] == l + @test CartesianIndices((4,3,2))[i,j,k] == CartesianIndex(i,j,k) @test CartesianIndices((4,3,2))[l] == CartesianIndex(i,j,k) @test LinearIndices(1:4,1:3,1:2)[i,j,k] == l + @test LinearIndices(1:4,1:3,1:2)[l] == l + @test CartesianIndices(1:4,1:3,1:2)[i,j,k] == CartesianIndex(i,j,k) @test CartesianIndices(1:4,1:3,1:2)[l] == CartesianIndex(i,j,k) @test LinearIndices(0:3,3:5,-101:-100)[i-1,j+2,k-102] == l + @test LinearIndices(0:3,3:5,-101:-100)[l] == l + @test CartesianIndices(0:3,3:5,-101:-100)[i,j,k] == CartesianIndex(i-1, j+2, k-102) @test CartesianIndices(0:3,3:5,-101:-100)[l] == CartesianIndex(i-1, j+2, k-102) end - local A = reshape(collect(1:9), (3,3)) + local A = reshape(Vector(1:9), (3,3)) @test CartesianIndices(size(A))[6] == CartesianIndex(3,2) @test LinearIndices(size(A))[3, 2] == 6 @test CartesianIndices(A)[6] == CartesianIndex(3,2) @@ -256,7 +279,7 @@ Base.setindex!(A::TSlow{T,5}, v, i1::Int, i2::Int, i3::Int, i4::Int, i5::Int) wh const can_inline = Base.JLOptions().can_inline != 0 function test_scalar_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where T N = prod(shape) - A = reshape(collect(1:N), shape) + A = reshape(Vector(1:N), shape) B = T(A) @test A == B # Test indexing up to 5 dimensions @@ -379,7 +402,7 @@ end function test_vector_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where T @testset "test_vector_indexing{$(T)}" begin N = prod(shape) - A = reshape(collect(1:N), shape) + A = reshape(Vector(1:N), shape) B = T(A) trailing5 = CartesianIndex(ntuple(x->1, max(ndims(B)-5, 0))) trailing4 = CartesianIndex(ntuple(x->1, max(ndims(B)-4, 0))) @@ -413,19 +436,20 @@ function test_vector_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where mask = bitrand(shape) @testset "test logical indexing" begin - @test B[mask] == A[mask] == B[find(mask)] == A[find(mask)] == find(mask) - @test B[vec(mask)] == A[vec(mask)] == find(mask) + @test B[mask] == A[mask] == B[find(mask)] == A[find(mask)] == LinearIndices(mask)[find(mask)] + @test B[vec(mask)] == A[vec(mask)] == LinearIndices(mask)[find(mask)] mask1 = bitrand(size(A, 1)) mask2 = bitrand(size(A, 2)) - @test B[mask1, mask2, trailing2] == A[mask1, mask2, trailing2] == B[find(mask1), find(mask2), trailing2] - @test B[mask1, 1, trailing2] == A[mask1, 1, trailing2] == find(mask1) + @test B[mask1, mask2, trailing2] == A[mask1, mask2, trailing2] == + B[LinearIndices(mask1)[find(mask1)], LinearIndices(mask2)[find(mask2)], trailing2] + @test B[mask1, 1, trailing2] == A[mask1, 1, trailing2] == LinearIndices(mask)[find(mask1)] end end end function test_primitives(::Type{T}, shape, ::Type{TestAbstractArray}) where T N = prod(shape) - A = reshape(collect(1:N), shape) + A = reshape(Vector(1:N), shape) B = T(A) # last(a) @@ -489,7 +513,7 @@ mutable struct UnimplementedArray{T, N} <: AbstractArray{T, N} end function test_getindex_internals(::Type{T}, shape, ::Type{TestAbstractArray}) where T N = prod(shape) - A = reshape(collect(1:N), shape) + A = reshape(Vector(1:N), shape) B = T(A) @test getindex(A, 1) == 1 @@ -509,7 +533,7 @@ end function test_setindex!_internals(::Type{T}, shape, ::Type{TestAbstractArray}) where T N = prod(shape) - A = reshape(collect(1:N), shape) + A = reshape(Vector(1:N), shape) B = T(A) Base.unsafe_setindex!(B, 2, 1) @@ -576,8 +600,7 @@ function test_cat(::Type{TestAbstractArray}) # hvcat for nbc in (1, 2, 3, 4, 5, 6) - @test hvcat(nbc, 1:120...) == - transpose(reshape([1:120...], nbc, round(Int, 120 / nbc))) + @test hvcat(nbc, 1:120...) == reshape([1:120...], nbc, round(Int, 120 / nbc))' end @test_throws ArgumentError hvcat(7, 1:20...) @@ -610,7 +633,7 @@ function test_ind2sub(::Type{TestAbstractArray}) n = rand(2:5) dims = tuple(rand(1:5, n)...) len = prod(dims) - A = reshape(collect(1:len), dims...) + A = reshape(Vector(1:len), dims...) I = CartesianIndices(dims) for i in 1:len @test A[I[i]] == A[i] @@ -791,7 +814,7 @@ for A in (rand(2), rand(2,3)) for (i, v) in pairs(A) @test A[i] == v end - @test collect(values(A)) == collect(A) + @test Array(values(A)) == A end # nextind @@ -807,7 +830,7 @@ end @testset "zero-dimensional copy" begin Z = Array{Int,0}(uninitialized); Z[] = 17 - @test Z == collect(Z) == copy(Z) + @test Z == Array(Z) == copy(Z) end @testset "empty" begin diff --git a/test/ambiguous.jl b/test/ambiguous.jl index b9532891ca558..1654f88360215 100644 --- a/test/ambiguous.jl +++ b/test/ambiguous.jl @@ -9,6 +9,8 @@ ambig(x::Int, y::Int) = 4 ambig(x::Number, y) = 5 # END OF LINE NUMBER SENSITIVITY +using SparseArrays + # For curmod_* include("testenv.jl") @@ -255,6 +257,12 @@ end @test length(detect_ambiguities(Ambig9, ambiguous_bottom=true)) == 1 @test length(detect_ambiguities(Ambig9)) == 0 +# issue #25341 +module M25341 +_totuple(::Type{Tuple{Vararg{E}}}, itr, s...) where {E} = E +end +@test length(detect_unbound_args(M25341; recursive=true)) == 1 + # Test that Core and Base are free of UndefVarErrors # not using isempty so this prints more information when it fails @testset "detect_unbound_args in Base and Core" begin @@ -278,9 +286,7 @@ end pop!(need_to_handle_undef_sparam, which(Base.LinAlg.promote_leaf_eltypes, (Union{AbstractArray{T}, Tuple{Vararg{T}}} where T<:Number,))) pop!(need_to_handle_undef_sparam, which(Base.LinAlg.promote_leaf_eltypes, (Union{AbstractArray{T}, Tuple{Vararg{T}}} where T<:(AbstractArray{<:Number}),))) - pop!(need_to_handle_undef_sparam, which(Base.SparseArrays._absspvec_vcat, (AbstractSparseArray{Tv, Ti, 1} where {Tv, Ti},))) - pop!(need_to_handle_undef_sparam, which(Base.SparseArrays._absspvec_hcat, (AbstractSparseArray{Tv, Ti, 1} where {Tv, Ti},))) - pop!(need_to_handle_undef_sparam, which(Base.cat, (Any, Base.SparseArrays._TypedDenseConcatGroup{T} where T))) + pop!(need_to_handle_undef_sparam, which(Base.cat, (Any, SparseArrays._TypedDenseConcatGroup{T} where T))) pop!(need_to_handle_undef_sparam, which(Base.float, Tuple{AbstractArray{Union{Missing, T},N} where {T, N}})) pop!(need_to_handle_undef_sparam, which(Base.convert, Tuple{Type{Union{Missing, T}} where T, Any})) pop!(need_to_handle_undef_sparam, which(Base.promote_rule, Tuple{Type{Union{Missing, S}} where S, Type{T} where T})) diff --git a/test/arrayops.jl b/test/arrayops.jl index 402ae878e062a..6dac579200b76 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -3,6 +3,9 @@ # Array test isdefined(Main, :TestHelpers) || @eval Main include("TestHelpers.jl") using Main.TestHelpers.OAs +using SparseArrays + +using Random @testset "basics" begin @test length([1, 2, 3]) == 3 @@ -48,7 +51,7 @@ using Main.TestHelpers.OAs a[1,2] = 2 a[2,1] = 3 a[2,2] = 4 - b = adjoint(a) + b = copy(a') @test a[1,1] == 1. && a[1,2] == 2. && a[2,1] == 3. && a[2,2] == 4. @test b[1,1] == 1. && b[2,1] == 2. && b[1,2] == 3. && b[2,2] == 4. a[[1 2 3 4]] = 0 @@ -86,6 +89,8 @@ using Main.TestHelpers.OAs @test a[2,1,2,2,1] == b[14] @test a[2,2,2,2,2] == b[end] + @test_throws DimensionMismatch reshape(1:3, 4) + # issue #23107 a = [1,2,3] @test typeof(a)(a) !== a @@ -94,7 +99,7 @@ using Main.TestHelpers.OAs @test Vector(a) !== a end @testset "reshaping SubArrays" begin - a = collect(reshape(1:5, 1, 5)) + a = Array(reshape(1:5, 1, 5)) @testset "linearfast" begin s = view(a, :, 2:4) r = reshape(s, (length(s),)) @@ -195,7 +200,7 @@ end end @testset "operations with IndexLinear ReshapedArray" begin - b = collect(1:12) + b = Vector(1:12) a = Base.ReshapedArray(b, (4,3), ()) @test a[3,2] == 7 @test a[6] == 6 @@ -276,8 +281,8 @@ end @test find(occursin(Int[]), a) == Int[] @test find(occursin(a), Int[]) == Int[] - a = collect(1:3:15) - b = collect(2:4:10) + a = Vector(1:3:15) + b = Vector(2:4:10) @test find(occursin(b), a) == [4] @test find(occursin(b), [a[1:4]; a[4:end]]) == [4,5] @@ -308,16 +313,8 @@ end @test size(Matrix{Int}(uninitialized, 2,3)) == (2,3) @test size(Matrix(uninitialized, 2,3)) == (2,3) - # TODO: will throw MethodError after 0.6 deprecations are deleted - dw = Base.JLOptions().depwarn - if dw == 2 - # FIXME: Remove this special case after deperror cleanup - @test_throws ErrorException Matrix{Int}() - @test_throws ErrorException Matrix() - else - @test size(@test_deprecated Matrix{Int}()) == (0,0) - @test size(@test_deprecated Matrix()) == (0,0) - end + @test_throws MethodError Matrix() + @test_throws MethodError Matrix{Int}() @test_throws MethodError Array{Int,3}() end @testset "get" begin @@ -435,57 +432,46 @@ end @test find(isodd,a) == [2,4,6,8] @test findfirst(!iszero, a) == 2 @test findfirst(a.==0) == 1 - @test findfirst(a.==5) == 0 + @test findfirst(a.==5) == nothing @test findfirst(equalto(3), [1,2,4,1,2,3,4]) == 6 @test findfirst(!equalto(1), [1,2,4,1,2,3,4]) == 2 @test findfirst(isodd, [2,4,6,3,9,2,0]) == 4 - @test findfirst(isodd, [2,4,6,2,0]) == 0 + @test findfirst(isodd, [2,4,6,2,0]) == nothing @test findnext(!iszero,a,4) == 4 @test findnext(!iszero,a,5) == 6 @test findnext(!iszero,a,1) == 2 @test findnext(equalto(1),a,4) == 6 - @test findnext(equalto(5),a,4) == 0 + @test findnext(equalto(5),a,4) == nothing @test findlast(!iszero, a) == 8 @test findlast(a.==0) == 5 - @test findlast(a.==5) == 0 + @test findlast(a.==5) == nothing @test findlast(equalto(3), [1,2,4,1,2,3,4]) == 6 @test findlast(isodd, [2,4,6,3,9,2,0]) == 5 - @test findlast(isodd, [2,4,6,2,0]) == 0 + @test findlast(isodd, [2,4,6,2,0]) == nothing @test findprev(!iszero,a,4) == 4 @test findprev(!iszero,a,5) == 4 - @test findprev(!iszero,a,1) == 0 + @test findprev(!iszero,a,1) == nothing @test findprev(equalto(1),a,4) == 2 @test findprev(equalto(1),a,8) == 6 @test findprev(isodd, [2,4,5,3,9,2,0], 7) == 5 - @test findprev(isodd, [2,4,5,3,9,2,0], 2) == 0 + @test findprev(isodd, [2,4,5,3,9,2,0], 2) == nothing @test findfirst(equalto(0x00), [0x01, 0x00]) == 2 @test findlast(equalto(0x00), [0x01, 0x00]) == 2 @test findnext(equalto(0x00), [0x00, 0x01, 0x00], 2) == 3 @test findprev(equalto(0x00), [0x00, 0x01, 0x00], 2) == 1 end +@testset "find with Matrix" begin + A = [1 2 0; 3 4 0] + @test find(isodd, A) == [CartesianIndex(1, 1), CartesianIndex(2, 1)] + @test find(!iszero, A) == [CartesianIndex(1, 1), CartesianIndex(2, 1), + CartesianIndex(1, 2), CartesianIndex(2, 2)] +end @testset "find with general iterables" begin s = "julia" @test find(c -> c == 'l', s) == [3] g = Base.Unicode.graphemes("日本語") @test find(isascii, g) == Int[] - @test find(!iszero, (i % 2 for i in 1:10)) == collect(1:2:9) -end -@testset "findn" begin - b = findn(fill(1,2,2,2,2)) - @test (length(b[1]) == 16) - @test (length(b[2]) == 16) - @test (length(b[3]) == 16) - @test (length(b[4]) == 16) - - #hand made case - a = ([2,1,2],[1,2,2],[2,2,2]) - z = zeros(2,2,2) - for i = 1:3 - z[a[1][i],a[2][i],a[3][i]] = 10 - end - @test isequal(a,findn(z)) - - @test findn([1, 0, 2]) == ([1, 3], ) + @test find(!iszero, (i % 2 for i in 1:10)) == 1:2:9 end @testset "findmin findmax indmin indmax" begin @@ -570,7 +556,7 @@ end @test pointer(cp) == pointer(c) @test_throws ArgumentError pointer(cp, 2) @test strides(cp) == (9,3,1) - ap = PermutedDimsArray(collect(a), (2,1,3)) + ap = PermutedDimsArray(Array(a), (2,1,3)) @test strides(ap) == (3,1,12) for A in [rand(1,2,3,4),rand(2,2,2,2),rand(5,6,5,6),rand(1,1,1,1)] @@ -615,7 +601,7 @@ let A, B, C, D C = unique(B, 1) @test sortrows(C) == sortrows(A) @test unique(B, 2) == B - @test transpose(unique(transpose(B), 2)) == C + @test unique(B', 2)' == C # Along third dimension D = cat(3, B, B) @@ -629,7 +615,7 @@ end @testset "large matrices transpose" begin for i = 1 : 3 a = rand(200, 300) - @test isequal(adjoint(a), permutedims(a, [2, 1])) + @test isequal(copy(a'), permutedims(a, [2, 1])) end end @@ -1137,7 +1123,7 @@ end @testset "filter!" begin # base case w/ Vector - a = collect(1:10) + a = Vector(1:10) filter!(x -> x > 5, a) @test a == 6:10 @@ -1153,9 +1139,9 @@ end @test isempty(ea) # non-1-indexed array - oa = OffsetArray(collect(1:10), -5) + oa = OffsetArray(Vector(1:10), -5) filter!(x -> x > 5, oa) - @test oa == OffsetArray(collect(6:10), -5) + @test oa == OffsetArray(Vector(6:10), -5) # empty non-1-indexed array eoa = OffsetArray([], -5) @@ -1227,7 +1213,7 @@ end A14 = [11 13; 12 14] R = CartesianIndices(axes(A14)) @test [a for (a,b) in pairs(IndexLinear(), A14)] == [1,2,3,4] - @test [a for (a,b) in pairs(IndexCartesian(), A14)] == vec(collect(R)) + @test [a for (a,b) in pairs(IndexCartesian(), A14)] == vec(Array(R)) @test [b for (a,b) in pairs(IndexLinear(), A14)] == [11,12,13,14] @test [b for (a,b) in pairs(IndexCartesian(), A14)] == [11,12,13,14] end @@ -1356,14 +1342,14 @@ end @test size([]') == (1,0) # issue #6996 -@test adjoint(Any[ 1 2; 3 4 ]) == transpose(Any[ 1 2; 3 4 ]) +@test copy(adjoint(Any[ 1 2; 3 4 ])) == copy(transpose(Any[ 1 2; 3 4 ])) # map with promotion (issue #6541) @test map(join, ["z", "я"]) == ["z", "я"] # Handle block matrices let A = [randn(2, 2) for i = 1:2, j = 1:2] - @test issymmetric(Transpose(A)*A) + @test issymmetric(A'A) end let A = [complex.(randn(2, 2), randn(2, 2)) for i = 1:2, j = 1:2] @test ishermitian(A'A) @@ -1591,7 +1577,7 @@ end @test eltype(R) <: CartesianIndex{2} @test eltype(typeof(R)) <: CartesianIndex{2} @test eltype(CartesianIndices{2}) <: CartesianIndex{2} - indices = collect(R) + indices = Array(R) @test indices[1] == CartesianIndex{2}(2,3) @test indices[2] == CartesianIndex{2}(3,3) @test indices[4] == CartesianIndex{2}(5,3) @@ -1631,7 +1617,7 @@ end val, state = next(itr, state) @test done(itr, state) @test r[val] == 3 - r = sparse(collect(2:3:8)) + r = sparse(2:3:8) itr = eachindex(r) state = start(itr) @test !done(itr, state) @@ -1770,7 +1756,7 @@ end @test (1:5) + (1.5:5.5) == 2.5:2.0:10.5 @testset "slicedim" begin - for A in (reshape(collect(1:20), 4, 5), + for A in (reshape(Vector(1:20), 4, 5), reshape(1:20, 4, 5)) local A @test slicedim(A, 1, 2) == 2:4:20 @@ -1778,7 +1764,7 @@ end @test_throws ArgumentError slicedim(A,0,1) @test slicedim(A, 3, 1) == A @test_throws BoundsError slicedim(A, 3, 2) - @test @inferred(slicedim(A, 1, 2:2)) == collect(2:4:20)' + @test @inferred(slicedim(A, 1, 2:2)) == Vector(2:4:20)' end end @@ -1851,16 +1837,6 @@ end fill!(B, 2) @test all(x->x==2, B) -iall = repmat(1:size(A,1), 1, size(A,2)) -jall = repmat((1:size(A,2))', size(A,1), 1) -i,j = findn(B) -@test vec(i) == vec(iall) -@test vec(j) == vec(jall) -fill!(S, 2) -i,j = findn(S) -@test vec(i) == vec(iall) -@test vec(j) == vec(jall) - copyto!(B, A) copyto!(S, A) @@ -2178,11 +2154,11 @@ end @test accumulate(op, [10 20 30], 2) == [10 op(10, 20) op(op(10, 20), 30)] == [10 40 110] end -struct F21666{T <: Base.TypeArithmetic} +struct F21666{T <: Base.ArithmeticStyle} x::Float32 end -Base.TypeArithmetic(::Type{F21666{T}}) where {T} = T() +Base.ArithmeticStyle(::Type{F21666{T}}) where {T} = T() Base.:+(x::F, y::F) where {F <: F21666} = F(x.x + y.x) Float64(x::F21666) = Float64(x.x) @testset "Exactness of cumsum # 21666" begin @@ -2220,7 +2196,7 @@ end test_zeros(zeros(Int, (2, 3)), Matrix{Int}, (2,3)) # #19265" - @test_throws ErrorException zeros(Float64, [1.]) # TODO change to MethodError, when v0.6 deprecations are done + @test_throws MethodError zeros(Float64, [1.]) end # issue #11053 @@ -2272,3 +2248,7 @@ end @testset "issue 24707" begin @test eltype(Vector{Tuple{V}} where V<:Integer) >: Tuple{Integer} end + +@testset "inference hash array 22740" begin + @inferred hash([1,2,3]) +end diff --git a/test/asyncmap.jl b/test/asyncmap.jl index c8b514f2bc890..1a23290679f2b 100644 --- a/test/asyncmap.jl +++ b/test/asyncmap.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + # Test asyncmap @test allunique(asyncmap(x->(sleep(1.0);object_id(current_task())), 1:10)) @@ -44,7 +46,7 @@ b=asyncmap(identity, c) # check with an iterator that has only implements length() len_only_iterable = (1,2,3,4,5) -@test Base.iteratorsize(len_only_iterable) == Base.HasLength() +@test Base.IteratorSize(len_only_iterable) == Base.HasLength() @test asyncmap(identity, len_only_iterable) == map(identity, len_only_iterable) # Error conditions diff --git a/test/bigint.jl b/test/bigint.jl index dddcc66c467fd..0c29a8a961aa9 100644 --- a/test/bigint.jl +++ b/test/bigint.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + a = parse(BigInt,"123456789012345678901234567890") b = parse(BigInt,"123456789012345678901234567891") c = parse(BigInt,"246913578024691357802469135780") diff --git a/test/bitarray.jl b/test/bitarray.jl index 549891e1966f6..0d468b8ac7923 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base: findprevnot, findnextnot +using Random tc(r1::NTuple{N,Any}, r2::NTuple{N,Any}) where {N} = all(x->tc(x...), [zip(r1,r2)...]) tc(r1::BitArray{N}, r2::Union{BitArray{N},Array{Bool,N}}) where {N} = true @@ -1078,16 +1079,16 @@ timesofar("datamove") for m = 0:v1, b1 in Any[bitrand(m), trues(m), falses(m)] @check_bit_operation count(b1) Int - @check_bit_operation findfirst(b1) Int + @check_bit_operation findfirst(b1) Union{Int,Nothing} - @check_bit_operation findfirst(!iszero, b1) Int - @check_bit_operation findfirst(iszero, b1) Int - @check_bit_operation findfirst(equalto(3), b1) Int + @check_bit_operation findfirst(!iszero, b1) Union{Int,Nothing} + @check_bit_operation findfirst(iszero, b1) Union{Int,Nothing} + @check_bit_operation findfirst(equalto(3), b1) Union{Int,Nothing} - @check_bit_operation findfirst(x->x, b1) Int - @check_bit_operation findfirst(x->!x, b1) Int - @check_bit_operation findfirst(x->true, b1) Int - @check_bit_operation findfirst(x->false, b1) Int + @check_bit_operation findfirst(x->x, b1) Union{Int,Nothing} + @check_bit_operation findfirst(x->!x, b1) Union{Int,Nothing} + @check_bit_operation findfirst(x->true, b1) Union{Int,Nothing} + @check_bit_operation findfirst(x->false, b1) Union{Int,Nothing} @check_bit_operation find(b1) Vector{Int} end @@ -1105,6 +1106,8 @@ timesofar("datamove") end b1 = bitrand(n1, n2) + @check_bit_operation find(b1) Vector{CartesianIndex{2}} + @check_bit_operation find(!iszero, b1) Vector{CartesianIndex{2}} @check_bit_operation findnz(b1) Tuple{Vector{Int}, Vector{Int}, BitArray} end @@ -1114,7 +1117,7 @@ timesofar("nnz&find") b1 = trues(v1) b2 = falses(v1) for i = 1:v1 - @test findprev(b1, i) == findprev(b1, true, i) == findprev(identity, b1, i) + @test findprev(b1, i) == findprev(equalto(true), b1, i) == findprev(identity, b1, i) @test findprevnot(b2, i) == findprev(!, b2, i) == i end @@ -1125,14 +1128,14 @@ timesofar("nnz&find") for i = 1:2:2000 @test findprev(odds,i) == findprevnot(evens,i) == i @test findnext(odds,i) == findnextnot(evens,i) == i - @test findprev(evens,i) == findprevnot(odds,i) == i-1 - @test findnext(evens,i) == findnextnot(odds,i) == (i < 2000 ? i+1 : 0) + @test findprev(evens,i) == findprevnot(odds,i) == (i > 1 ? i-1 : nothing) + @test findnext(evens,i) == findnextnot(odds,i) == (i < 2000 ? i+1 : nothing) end for i = 2:2:2000 @test findprev(odds,i) == findprevnot(evens,i) == i-1 @test findprev(evens,i) == findprevnot(odds,i) == i @test findnext(evens,i) == findnextnot(odds,i) == i - @test findnext(odds,i) == findnextnot(evens,i) == (i < 2000 ? i+1 : 0) + @test findnext(odds,i) == findnextnot(evens,i) == (i < 2000 ? i+1 : nothing) end elts = (1:64:(64*64+1)) .+ (0:64) @@ -1162,9 +1165,9 @@ timesofar("nnz&find") @test findprev(b1, 777) == findprevnot(b2, 777) == findprev(!, b2, 777) == 777 @test findprev(b1, 776) == findprevnot(b2, 776) == findprev(!, b2, 776) == 77 @test findprev(b1, 77) == findprevnot(b2, 77) == findprev(!, b2, 77) == 77 - @test findprev(b1, 76) == findprevnot(b2, 76) == findprev(!, b2, 76) == 0 - @test findprev(b1, -1) == findprevnot(b2, -1) == findprev(!, b2, -1) == 0 - @test findprev(identity, b1, -1) == findprev(x->false, b1, -1) == findprev(x->true, b1, -1) == 0 + @test findprev(b1, 76) == findprevnot(b2, 76) == findprev(!, b2, 76) == nothing + @test findprev(b1, -1) == findprevnot(b2, -1) == findprev(!, b2, -1) == nothing + @test findprev(identity, b1, -1) == findprev(x->false, b1, -1) == findprev(x->true, b1, -1) == nothing @test_throws BoundsError findnext(b1, -1) @test_throws BoundsError findnextnot(b2, -1) @test_throws BoundsError findnext(!, b2, -1) @@ -1175,41 +1178,41 @@ timesofar("nnz&find") @test findnext(b1, 77) == findnextnot(b2, 77) == findnext(!, b2, 77) == 77 @test findnext(b1, 78) == findnextnot(b2, 78) == findnext(!, b2, 78) == 777 @test findnext(b1, 777) == findnextnot(b2, 777) == findnext(!, b2, 777) == 777 - @test findnext(b1, 778) == findnextnot(b2, 778) == findnext(!, b2, 778) == 0 - @test findnext(b1, 1001) == findnextnot(b2, 1001) == findnext(!, b2, 1001) == 0 - @test findnext(identity, b1, 1001) == findnext(x->false, b1, 1001) == findnext(x->true, b1, 1001) == 0 + @test findnext(b1, 778) == findnextnot(b2, 778) == findnext(!, b2, 778) == nothing + @test findnext(b1, 1001) == findnextnot(b2, 1001) == findnext(!, b2, 1001) == nothing + @test findnext(identity, b1, 1001) == findnext(x->false, b1, 1001) == findnext(x->true, b1, 1001) == nothing @test findlast(b1) == Base.findlastnot(b2) == 777 @test findfirst(b1) == Base.findfirstnot(b2) == 77 b0 = BitVector() - @test findprev(x->true, b0, -1) == 0 + @test findprev(x->true, b0, -1) == nothing @test_throws BoundsError findprev(x->true, b0, 1) @test_throws BoundsError findnext(x->true, b0, -1) - @test findnext(x->true, b0, 1) == 0 + @test findnext(x->true, b0, 1) == nothing b1 = falses(10) @test findprev(x->true, b1, 5) == 5 @test findnext(x->true, b1, 5) == 5 - @test findprev(x->true, b1, -1) == 0 - @test findnext(x->true, b1, 11) == 0 - @test findprev(x->false, b1, 5) == 0 - @test findnext(x->false, b1, 5) == 0 - @test findprev(x->false, b1, -1) == 0 - @test findnext(x->false, b1, 11) == 0 + @test findprev(x->true, b1, -1) == nothing + @test findnext(x->true, b1, 11) == nothing + @test findprev(x->false, b1, 5) == nothing + @test findnext(x->false, b1, 5) == nothing + @test findprev(x->false, b1, -1) == nothing + @test findnext(x->false, b1, 11) == nothing @test_throws BoundsError findprev(x->true, b1, 11) @test_throws BoundsError findnext(x->true, b1, -1) for l = [1, 63, 64, 65, 127, 128, 129] f = falses(l) t = trues(l) - @test findprev(f, l) == findprevnot(t, l) == 0 + @test findprev(f, l) == findprevnot(t, l) == nothing @test findprev(t, l) == findprevnot(f, l) == l b1 = falses(l) b1[end] = true b2 = .~b1 @test findprev(b1, l) == findprevnot(b2, l) == l - @test findprevnot(b1, l) == findprev(b2, l) == l-1 + @test findprevnot(b1, l) == findprev(b2, l) == (l == 1 ? nothing : l-1) if l > 1 b1 = falses(l) b1[end-1] = true @@ -1306,13 +1309,13 @@ end # TODO -@testset "Transpose" begin +@testset "transpose" begin b1 = bitrand(v1) @check_bit_operation transpose(b1) Transpose{Bool,BitVector} for m1 = 0:n1, m2 = 0:n2 b1 = bitrand(m1, m2) - @check_bit_operation transpose(b1) BitMatrix + @check_bit_operation copy(b1') BitMatrix end end @@ -1390,7 +1393,7 @@ timesofar("cat") end b1 = bitrand(n1,n1) - b1 .|= transpose(b1) + b1 .|= copy(b1') @check_bit_operation issymmetric(b1) Bool @check_bit_operation ishermitian(b1) Bool @@ -1406,7 +1409,8 @@ timesofar("cat") @check_bit_operation diff(b1) Vector{Int} b1 = bitrand(n1, n2) - @check_bit_operation diff(b1) Matrix{Int} + @check_bit_operation diff(b1, 1) Matrix{Int} + @check_bit_operation diff(b1, 2) Matrix{Int} b1 = bitrand(n1, n1) @check_bit_operation svd(b1) diff --git a/test/bitset.jl b/test/bitset.jl index c6ab52adc52c1..b62ea9bacc1c8 100644 --- a/test/bitset.jl +++ b/test/bitset.jl @@ -2,6 +2,8 @@ # Test functionality of BitSet +using Random + @testset "Construction, collect" begin data_in = (1,5,100) s = BitSet(data_in) diff --git a/test/boundscheck_exec.jl b/test/boundscheck_exec.jl index ee8413bd4e5b9..138059d8fcb8a 100644 --- a/test/boundscheck_exec.jl +++ b/test/boundscheck_exec.jl @@ -2,7 +2,7 @@ module TestBoundsCheck -using Test +using Test, Random @enum BCOption bc_default bc_on bc_off bc_opt = BCOption(Base.JLOptions().check_bounds) diff --git a/test/broadcast.jl b/test/broadcast.jl index e8c17fda643b7..df176eacde2c1 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -4,7 +4,7 @@ module TestBroadcastInternals using Base.Broadcast: check_broadcast_indices, check_broadcast_shape, newindex, _bcs using Base: OneTo -using Test +using Test, Random @test @inferred(_bcs((3,5), (3,5))) == (3,5) @test @inferred(_bcs((3,1), (3,5))) == (3,5) diff --git a/test/ccall.jl b/test/ccall.jl index b6d30cdae817d..4250591b2ac4f 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -1,6 +1,9 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license import Base.copy, Base.== +using Random + +import Libdl const libccalltest = "libccalltest" diff --git a/test/channels.jl b/test/channels.jl index 8fe69c10f1c64..10301bd3e804a 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + # Test various constructors let c = Channel(1) @test eltype(c) == Any diff --git a/test/choosetests.jl b/test/choosetests.jl index 21b8585bcbbd2..2c9ec6a42d640 100644 --- a/test/choosetests.jl +++ b/test/choosetests.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + const STDLIB_DIR = joinpath(Sys.BINDIR, "..", "share", "julia", "site", "v$(VERSION.major).$(VERSION.minor)") const STDLIBS = readdir(STDLIB_DIR) @@ -35,8 +37,8 @@ function choosetests(choices = []) "keywordargs", "numbers", "subtype", "char", "strings", "triplequote", "unicode", "intrinsics", "dict", "hashing", "iobuffer", "staged", "offsetarray", - "arrayops", "tuple", "reduce", "reducedim", "random", "abstractarray", - "intfuncs", "simdloop", "vecelement", "sparse", + "arrayops", "tuple", "reduce", "reducedim", "abstractarray", + "intfuncs", "simdloop", "vecelement", "bitarray", "copy", "math", "fastmath", "functional", "iterators", "operators", "path", "ccall", "parse", "loading", "bigint", "bigfloat", "sorting", "statistics", "spawn", "backtrace", @@ -48,7 +50,7 @@ function choosetests(choices = []) "replutil", "sets", "goto", "llvmcall", "llvmcall2", "grisu", "some", "meta", "stacktraces", "libgit2", "docs", "markdown", "serialize", "misc", "threads", - "enums", "cmdlineargs", "i18n", "libdl", "int", + "enums", "cmdlineargs", "i18n", "int", "checked", "bitset", "floatfuncs", "compile", "inline", "boundscheck", "error", "ambiguous", "cartesian", "asmvariant", "osutils", "channels", "iostream", "specificity", "codegen", "codevalidation", @@ -101,15 +103,6 @@ function choosetests(choices = []) prepend!(tests, stringtests) end - sparsetests = ["sparse/sparse", "sparse/sparsevector", "sparse/higherorderfns"] - if "sparse" in skip_tests - filter!(x -> (x != "sparse" && !(x in sparsetests)), tests) - elseif "sparse" in tests - # specifically selected case - filter!(x -> x != "sparse", tests) - prepend!(tests, sparsetests) - end - # do subarray before sparse but after linalg if "subarray" in skip_tests filter!(x -> x != "subarray", tests) diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 75b0fe401dd13..fb375c242bab0 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +import Libdl + catcmd = `cat` if Sys.iswindows() busybox = joinpath(Sys.BINDIR, "busybox.exe") diff --git a/test/codegen.jl b/test/codegen.jl index 73ed5ed3d9697..0f5909b32d665 100644 --- a/test/codegen.jl +++ b/test/codegen.jl @@ -2,6 +2,8 @@ # tests for codegen and optimizations +using Random + const opt_level = Base.JLOptions().opt_level const coverage = (Base.JLOptions().code_coverage > 0) || (Base.JLOptions().malloc_log > 0) const Iptr = sizeof(Int) == 8 ? "i64" : "i32" @@ -322,3 +324,14 @@ end # the semi-boxed union on the if-branch of the `isa` is not annotated !nonnull @test contains(get_llvm_noopt(foo24632, (Bool,), false), "!dereferenceable_or_null") @test !contains(get_llvm_noopt(foo24632, (Bool,), false), "!nonnull") + +str_22330 = """ +Base.convert(::Type{Array{T,n}}, a::Array) where {T<:Number,n} = + copyto!(Array{T,n}(uninitialized, size(a)), a) + +empty(Dict(), Pair{Union{},Union{}}) +""" +f_22330 = tempname() +write(f_22330, str_22330) +@test success(`$(Base.julia_cmd()) --startup-file=no $f_22330`) + diff --git a/test/combinatorics.jl b/test/combinatorics.jl index 11a5a3d96c6d4..5d1aa0af564f5 100644 --- a/test/combinatorics.jl +++ b/test/combinatorics.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random: randcycle + @testset "binomial" begin @test binomial(5,-1) == 0 @test binomial(5,10) == 0 @@ -13,7 +15,7 @@ @test binomial(Int32(34), Int32(15)) == binomial(BigInt(34), BigInt(15)) == 1855967520 @test binomial(Int64(67), Int64(29)) == binomial(BigInt(67), BigInt(29)) == 7886597962249166160 @test binomial(Int128(131), Int128(62)) == binomial(BigInt(131), BigInt(62)) == 157311720980559117816198361912717812000 - @test_throws InexactError binomial(Int64(67), Int64(30)) + @test_throws OverflowError binomial(Int64(67), Int64(30)) end @testset "permutations" begin diff --git a/test/compile.jl b/test/compile.jl index 2fc3702c2885e..392f7988d0bd0 100644 --- a/test/compile.jl +++ b/test/compile.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test, Distributed +using Test, Distributed, Random import Base: root_module @@ -218,9 +218,9 @@ try [:Base, :Core, Foo2_module, FooBase_module, :Main]), # plus modules included in the system image Dict(s => Base.module_uuid(Base.root_module(s)) for s in - [:Base64, :CRC32c, :Dates, :DelimitedFiles, :FileWatching, :Future, - :IterativeEigensolvers, :Logging, :Mmap, :Printf, :Profile, :SharedArrays, - :SuiteSparse, :Test, :Unicode, :Distributed])) + [:Base64, :CRC32c, :Dates, :DelimitedFiles, :Distributed, :FileWatching, + :Future, :IterativeEigensolvers, :Libdl, :Logging, :Mmap, :Printf, + :Profile, :Random, :SharedArrays, :SparseArrays, :SuiteSparse, :Test, :Unicode])) @test discard_module.(deps) == deps1 @test current_task()(0x01, 0x4000, 0x30031234) == 2 diff --git a/test/copy.jl b/test/copy.jl index d4c8ba2f2ea42..80052a1cc6465 100644 --- a/test/copy.jl +++ b/test/copy.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + mainres = ([4, 5, 3], [1, 5, 3]) bitres = ([true, true, false], diff --git a/test/core.jl b/test/core.jl index 7b470ec4113a0..61218c91c3f29 100644 --- a/test/core.jl +++ b/test/core.jl @@ -1,8 +1,13 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license # test core language features + +using Random + const Bottom = Union{} +using SparseArrays + # For curmod_* include("testenv.jl") @@ -2340,6 +2345,16 @@ f9520c(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, args...) = 46 @test invoke(f9520c, Tuple{Any, Any, Any, Any, Any, Any}, 1, 2, 3, 4, 5, 6) == 46 @test invoke(f9520c, Tuple{Any, Any, Any, Any, Any, Any, Any}, 1, 2, 3, 4, 5, 6, 7) == 46 +# issue #24460 +f24460(x, y) = 1 +f24460(x::T, y::T) where {T} = 2.0 +f24460(x::Int, y::Int) = "3" +@test f24460(1, 2) === "3" +@test invoke(f24460, Tuple{T,T} where T, 1, 2) === 2.0 +const T24460 = Tuple{T,T} where T +g24460() = invoke(f24460, T24460, 1, 2) +@test @inferred(g24460()) === 2.0 + call_lambda1() = (()->x)(1) call_lambda2() = ((x)->x)() call_lambda3() = ((x)->x)(1,2) @@ -4180,7 +4195,7 @@ end # issue #14113 module A14113 - using Test + using Test, Random # show that making several thousand methods (and lots of AST constants) # doesn't cause any serious issues (for example, for the serializer) # although to keep runtime on the order of several seconds for this test, @@ -5524,6 +5539,7 @@ module UnionOptimizations using Test using Dates +using Random const boxedunions = [Union{}, Union{String, Nothing}] const unboxedunions = [Union{Int8, Nothing}, diff --git a/test/dict.jl b/test/dict.jl index d3df55dab77a1..8b3cd568c1dd6 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + @testset "Pair" begin p = Pair(10,20) @test p == (10=>20) @@ -282,7 +284,7 @@ end Base.show(io, MIME("text/plain"), d) out = split(String(take!(s)),'\n') for line in out[2:end] - @test Base.Unicode.textwidth(line) <= cols + @test textwidth(line) <= cols end @test length(out) <= rows @@ -292,7 +294,7 @@ end Base.show(io, MIME("text/plain"), f(d)) out = split(String(take!(s)),'\n') for line in out[2:end] - @test Base.Unicode.textwidth(line) <= cols + @test textwidth(line) <= cols end @test length(out) <= rows end @@ -757,3 +759,10 @@ end end @test map(string, keys(d)) == Set(["1","3"]) end + +@testset "find" begin + @test @inferred find(equalto(1), Dict(:a=>1, :b=>2)) == [:a] + @test @inferred sort(find(equalto(1), Dict(:a=>1, :b=>1))) == [:a, :b] + @test @inferred isempty(find(equalto(1), Dict())) + @test @inferred isempty(find(equalto(1), Dict(:a=>2, :b=>3))) +end \ No newline at end of file diff --git a/test/docs.jl b/test/docs.jl index 295d116216576..ed143bd6f2b35 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -953,7 +953,7 @@ for (line, expr) in Pair[ "\"...\"" => "...", "r\"...\"" => Expr(:macrocall, Symbol("@r_str"), LineNumberNode(1, :none), "...") ] - @test Docs.helpmode(line) == Expr(:macrocall, Expr(:., Expr(:., :Base, QuoteNode(:Docs)), QuoteNode(Symbol("@repl"))), LineNumberNode(116, doc_util_path), STDOUT, expr) + @test Docs.helpmode(line) == Expr(:macrocall, Expr(:., Expr(:., :Base, QuoteNode(:Docs)), QuoteNode(Symbol("@repl"))), LineNumberNode(115, doc_util_path), STDOUT, expr) buf = IOBuffer() @test eval(Base, Docs.helpmode(buf, line)) isa Union{Base.Markdown.MD,Nothing} end @@ -985,8 +985,8 @@ dynamic_test.x = "test 2" @test @doc(dynamic_test) == "test 2 Union{}" @test @doc(dynamic_test(::String)) == "test 2 Tuple{String}" -@test Docs._repl(:(dynamic_test(1.0))) == Expr(:escape, Expr(:macrocall, Symbol("@doc"), LineNumberNode(197, doc_util_path), :(dynamic_test(::typeof(1.0))))) -@test Docs._repl(:(dynamic_test(::String))) == Expr(:escape, Expr(:macrocall, Symbol("@doc"), LineNumberNode(197, doc_util_path), :(dynamic_test(::String)))) +@test Docs._repl(:(dynamic_test(1.0))) == Expr(:escape, Expr(:macrocall, Symbol("@doc"), LineNumberNode(196, doc_util_path), :(dynamic_test(::typeof(1.0))))) +@test Docs._repl(:(dynamic_test(::String))) == Expr(:escape, Expr(:macrocall, Symbol("@doc"), LineNumberNode(196, doc_util_path), :(dynamic_test(::String)))) diff --git a/test/download.jl b/test/download.jl index e982dbfbcc53f..5fa3eef9597b3 100644 --- a/test/download.jl +++ b/test/download.jl @@ -19,6 +19,13 @@ mktempdir() do temp_dir @test_throws ErrorException download("http://httpbin.org/status/404", missing_file) @test !isfile(missing_file) + # Make sure we properly handle metachar ' + metachar_file = joinpath(temp_dir, "metachar") + download("https://httpbin.org/get?test='^'", metachar_file) + metachar_string = read(metachar_file, String) + m = match(r"\"url\"\s*:\s*\"(.*)\"", metachar_string) + @test m.captures[1] == "https://httpbin.org/get?test='^'" + # Use a TEST-NET (192.0.2.0/24) address which shouldn't be bound invalid_host_file = joinpath(temp_dir, "invalid_host") @test_throws ErrorException download("http://192.0.2.1", invalid_host_file) diff --git a/test/enums.jl b/test/enums.jl index 068aafff29e49..97f83810920bf 100644 --- a/test/enums.jl +++ b/test/enums.jl @@ -148,3 +148,11 @@ let b = IOBuffer() seekstart(b) @test deserialize(b) === apple end + +# test block form +@enum BritishFood begin + blackpudding = 1 + scotchegg = 2 + haggis = 4 +end +@test Int(haggis) == 4 diff --git a/test/env.jl b/test/env.jl index ea24759aa5941..2ea6eedafd67c 100644 --- a/test/env.jl +++ b/test/env.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + @test !("f=a=k=e=n=a=m=e" ∈ keys(ENV)) @testset "issue #10994" begin diff --git a/test/examples.jl b/test/examples.jl index a3002e3240171..a695dfd585433 100644 --- a/test/examples.jl +++ b/test/examples.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + dir = joinpath(Sys.BINDIR, Base.DOCDIR, "examples") include(joinpath(dir, "bubblesort.jl")) @@ -24,9 +26,9 @@ include(joinpath(dir, "ndgrid.jl")) r = repmat(1:10,1,10) r1, r2 = ndgrid(1:10, 1:10) @test r1 == r -@test r2 == adjoint(r) +@test r2 == r' r3, r4 = meshgrid(1:10,1:10) -@test r3 == adjoint(r) +@test r3 == r' @test r4 == r include(joinpath(dir, "queens.jl")) diff --git a/test/file.jl b/test/file.jl index 4c51cf2616b55..ceae11b6f3996 100644 --- a/test/file.jl +++ b/test/file.jl @@ -218,10 +218,10 @@ close(s) my_tempdir = tempdir() @test isdir(my_tempdir) == true -path = tempname() -# Issue #9053. -@test ispath(path) == Sys.iswindows() -ispath(path) && rm(path) +let path = tempname() + # issue #9053 + @test !ispath(path) +end (p, f) = mktemp() print(f, "Here is some text") diff --git a/test/floatfuncs.jl b/test/floatfuncs.jl index f5f0f7472935a..b686c45b4186c 100644 --- a/test/floatfuncs.jl +++ b/test/floatfuncs.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random # test the basic floating point functions diff --git a/test/functional.jl b/test/functional.jl index d7b9026ea61cb..cf1ed62776449 100644 --- a/test/functional.jl +++ b/test/functional.jl @@ -36,6 +36,9 @@ end @test isa(map(Integer, Any[1, 2]), Vector{Int}) @test isa(map(Integer, Any[]), Vector{Integer}) +# issue #25433 +@test @inferred(collect(v for v in [1] if v > 0)) isa Vector{Int} + # filter -- array.jl @test isequal(filter(x->(x>1), [0 1 2 3 2 1 0]), [2, 3, 2]) # TODO: @test_throws isequal(filter(x->x+1, [0 1 2 3 2 1 0]), [2, 3, 2]) @@ -111,7 +114,7 @@ let gen = (x for x in 1:10) end let gen = (x * y for x in 1:10, y in 1:10) - @test collect(gen) == collect(1:10) .* collect(1:10)' + @test collect(gen) == Vector(1:10) .* Vector(1:10)' @test first(gen) == 1 @test collect(gen)[1:10] == 1:10 end diff --git a/test/generic_map_tests.jl b/test/generic_map_tests.jl index fb2444134f072..5c79ea08f909b 100644 --- a/test/generic_map_tests.jl +++ b/test/generic_map_tests.jl @@ -4,7 +4,7 @@ mutable struct GenericIterator{N} end Base.start(::GenericIterator{N}) where {N} = 1 Base.next(::GenericIterator{N}, i) where {N} = (i, i + 1) Base.done(::GenericIterator{N}, i) where {N} = i > N ? true : false -Base.iteratorsize(::Type{GenericIterator{N}}) where {N} = Base.SizeUnknown() +Base.IteratorSize(::Type{GenericIterator{N}}) where {N} = Base.SizeUnknown() function generic_map_tests(mapf, inplace_mapf=nothing) for typ in (Float16, Float32, Float64, @@ -61,7 +61,7 @@ function testmap_equivalence(mapf, f, c...) x1 = mapf(f,c...) x2 = map(f,c...) - if Base.iteratorsize == Base.HasShape() + if Base.IteratorSize == Base.HasShape() @test size(x1) == size(x2) else @test length(x1) == length(x2) @@ -76,7 +76,6 @@ end function run_map_equivalence_tests(mapf) testmap_equivalence(mapf, identity, (1,2,3,4)) - testmap_equivalence(mapf, x->x>0 ? 1.0 : 0.0, sparse(sparse(1.0I, 5, 5))) testmap_equivalence(mapf, (x,y,z)->x+y+z, 1,2,3) testmap_equivalence(mapf, x->x ? false : true, BitMatrix(uninitialized, 10,10)) testmap_equivalence(mapf, x->"foobar", BitMatrix(uninitialized, 10,10)) diff --git a/test/hashing.jl b/test/hashing.jl index b414c05c52ceb..4de1b7d988631 100644 --- a/test/hashing.jl +++ b/test/hashing.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random, SparseArrays + types = Any[ Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float32, Float64, @@ -96,7 +98,7 @@ vals = Any[ for a in vals, b in vals @test isequal(a,b) == (hash(a)==hash(b)) if a isa AbstractArray - @test hash(a) == hash(collect(a)) == hash(collect(Any, a)) + @test hash(a) == hash(Array(a)) == hash(Array{Any}(a)) end end @@ -166,7 +168,7 @@ vals = Any[ ] for a in vals - @test hash(collect(a)) == hash(a) + @test hash(Array(a)) == hash(a) end @test hash(SubString("--hello--",3,7)) == hash("hello") diff --git a/test/inference.jl b/test/inference.jl index 6e8a36a8114c0..ffdede50d5b90 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -4,6 +4,8 @@ import Core.Inference: Const, Conditional, ⊑ const isleaftype = Core.Inference._isleaftype +using Random + # demonstrate some of the type-size limits @test Core.Inference.limit_type_size(Ref{Complex{T} where T}, Ref, Ref, 0) == Ref @test Core.Inference.limit_type_size(Ref{Complex{T} where T}, Ref{Complex{T} where T}, Ref, 0) == Ref{Complex{T} where T} @@ -1305,3 +1307,89 @@ f_pure_add() = (1 + 1 == 2) ? true : "FAIL" @test Core.Inference.getfield_tfunc(Const(Int), Const(:mutable)) == Const(false) @test Core.Inference.getfield_tfunc(Const(Vector{Int}), Const(:mutable)) == Const(true) @test Core.Inference.getfield_tfunc(DataType, Const(:mutable)) == Bool + +struct Foo_22708 + x::Ptr{Foo_22708} +end + +f_22708(x::Int) = f_22708(Foo_22708, x) +f_22708(::Type{Foo_22708}, x) = bar_22708("x") +f_22708(x) = x +bar_22708(x) = f_22708(x) + +@test bar_22708(1) == "x" + +# mechanism for spoofing work-limiting heuristics and early generator expansion (#24852) +function _generated_stub(gen::Symbol, args::Vector{Any}, params::Vector{Any}, line, file, expand_early) + stub = Expr(:new, Core.GeneratedFunctionStub, gen, args, params, line, file, expand_early) + return Expr(:meta, :generated, stub) +end + +f24852_kernel(x, y) = x * y + +function f24852_kernel_cinfo(x, y) + sig, spvals, method = Base._methods_by_ftype(Tuple{typeof(f24852_kernel),x,y}, -1, typemax(UInt))[1] + code_info = Base.uncompressed_ast(method) + body = Expr(:block, code_info.code...) + Base.Core.Inference.substitute!(body, 0, Any[], sig, Any[spvals...], 0, :propagate) + return method, code_info +end + +function f24852_gen_cinfo_uninflated(X, Y, f, x, y) + _, code_info = f24852_kernel_cinfo(x, y) + return code_info +end + +function f24852_gen_cinfo_inflated(X, Y, f, x, y) + method, code_info = f24852_kernel_cinfo(x, y) + code_info.signature_for_inference_heuristics = Core.Inference.svec(f, (x, y), typemax(UInt)) + return code_info +end + +function f24852_gen_expr(X, Y, f, x, y) + return :(f24852_kernel(x::$X, y::$Y)) +end + +@eval begin + function f24852_late_expr(x::X, y::Y) where {X, Y} + $(_generated_stub(:f24852_gen_expr, Any[:f24852_late_expr, :x, :y], + Any[:X, :Y], @__LINE__, QuoteNode(Symbol(@__FILE__)), false)) + end + function f24852_late_inflated(x::X, y::Y) where {X, Y} + $(_generated_stub(:f24852_gen_cinfo_inflated, Any[:f24852_late_inflated, :x, :y], + Any[:X, :Y], @__LINE__, QuoteNode(Symbol(@__FILE__)), false)) + end + function f24852_late_uninflated(x::X, y::Y) where {X, Y} + $(_generated_stub(:f24852_gen_cinfo_uninflated, Any[:f24852_late_uninflated, :x, :y], + Any[:X, :Y], @__LINE__, QuoteNode(Symbol(@__FILE__)), false)) + end +end + +@eval begin + function f24852_early_expr(x::X, y::Y) where {X, Y} + $(_generated_stub(:f24852_gen_expr, Any[:f24852_early_expr, :x, :y], + Any[:X, :Y], @__LINE__, QuoteNode(Symbol(@__FILE__)), true)) + end + function f24852_early_inflated(x::X, y::Y) where {X, Y} + $(_generated_stub(:f24852_gen_cinfo_inflated, Any[:f24852_early_inflated, :x, :y], + Any[:X, :Y], @__LINE__, QuoteNode(Symbol(@__FILE__)), true)) + end + function f24852_early_uninflated(x::X, y::Y) where {X, Y} + $(_generated_stub(:f24852_gen_cinfo_uninflated, Any[:f24852_early_uninflated, :x, :y], + Any[:X, :Y], @__LINE__, QuoteNode(Symbol(@__FILE__)), true)) + end +end + +x, y = rand(), rand() +result = f24852_kernel(x, y) + +@test result === f24852_late_expr(x, y) +@test result === f24852_late_uninflated(x, y) +@test result === f24852_late_inflated(x, y) + +@test result === f24852_early_expr(x, y) +@test result === f24852_early_uninflated(x, y) +@test result === f24852_early_inflated(x, y) + +# TODO: test that `expand_early = true` + inflated `signature_for_inference_heuristics` +# can be used to tighten up some inference result. diff --git a/test/int.jl b/test/int.jl index ba4c998bdc4bb..48d59ccb504d4 100644 --- a/test/int.jl +++ b/test/int.jl @@ -2,6 +2,7 @@ # Test integer conversion routines from int.jl +using Random for y in (-4, Float32(-4), -4.0, big(-4.0)) @test flipsign(3, y) == -3 diff --git a/test/intfuncs.jl b/test/intfuncs.jl index 918febfde41ca..82c67f30e745e 100644 --- a/test/intfuncs.jl +++ b/test/intfuncs.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + @testset "gcd/lcm" begin # Int32 and Int64 take different code paths -- test both for T in (Int32, Int64) diff --git a/test/iobuffer.jl b/test/iobuffer.jl index 6f6e18f36ab8e..7b0ad7fb2224d 100644 --- a/test/iobuffer.jl +++ b/test/iobuffer.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + ioslength(io::IOBuffer) = (io.seekable ? io.size : nb_available(io)) bufcontents(io::Base.GenericIOBuffer) = unsafe_string(pointer(io.data), io.size) @@ -190,7 +192,7 @@ end # pr #11554 let a, io = IOBuffer(SubString("***αhelloworldω***", 4, 16)), - io2 = IOBuffer(b"goodnightmoon", true, true) + io2 = IOBuffer(Vector{UInt8}(b"goodnightmoon"), true, true) @test read(io, Char) == 'α' @test_throws ArgumentError write(io,"!") @@ -258,7 +260,6 @@ let io = IOBuffer() end # skipchars -using Base.Unicode: isspace let io = IOBuffer("") @test eof(skipchars(io, isspace)) @@ -279,7 +280,7 @@ let for char in ['@','߷','࿊','𐋺'] io = IOBuffer("alphabeticalstuff$char") - @test !eof(skipchars(io, Base.Unicode.isalpha)) + @test !eof(skipchars(io, isalpha)) @test read(io, Char) == char end end diff --git a/test/iostream.jl b/test/iostream.jl index 67a0e7d90af0a..31026b753d173 100644 --- a/test/iostream.jl +++ b/test/iostream.jl @@ -1,7 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license # Test skipchars for IOStreams -using Base.Unicode: isspace mktemp() do path, file function append_to_file(str) mark(file) @@ -35,7 +34,7 @@ mktemp() do path, file for (byte,char) in zip(1:4, ('@','߷','࿊','𐋺')) append_to_file("abcdef$char") @test Base.codelen(char) == byte - @test !eof(skipchars(file, Base.Unicode.isalpha)) + @test !eof(skipchars(file, isalpha)) @test read(file, Char) == char end end diff --git a/test/iterators.jl b/test/iterators.jl index e5d8b998884ae..ed8f046240739 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base.Iterators +using Random # zip and filter iterators # issue #4718 @@ -115,7 +116,7 @@ let i = 0 end @test length(drop(1:3,typemax(Int))) == 0 -@test Base.iteratorsize(drop(countfrom(1),3)) == Base.IsInfinite() +@test Base.IteratorSize(drop(countfrom(1),3)) == Base.IsInfinite() @test_throws MethodError length(drop(countfrom(1), 3)) # double take @@ -160,11 +161,11 @@ let i = 0 end @test eltype(repeated(0)) == Int @test eltype(repeated(0, 5)) == Int -@test Base.iteratorsize(repeated(0)) == Base.IsInfinite() -@test Base.iteratorsize(repeated(0, 5)) == Base.HasLength() -@test Base.iteratoreltype(repeated(0)) == Base.HasEltype() -@test Base.iteratoreltype(repeated(0, 5)) == Base.HasEltype() -@test Base.iteratorsize(zip(repeated(0), repeated(0))) == Base.IsInfinite() +@test Base.IteratorSize(repeated(0)) == Base.IsInfinite() +@test Base.IteratorSize(repeated(0, 5)) == Base.HasLength() +@test Base.IteratorEltype(repeated(0)) == Base.HasEltype() +@test Base.IteratorEltype(repeated(0, 5)) == Base.HasEltype() +@test Base.IteratorSize(zip(repeated(0), repeated(0))) == Base.IsInfinite() # product @@ -305,45 +306,45 @@ let a = 1:2, end end -# iteratorsize trait business +# IteratorSize trait business let f1 = Iterators.filter(i->i>0, 1:10) - @test Base.iteratorsize(product(f1)) == Base.SizeUnknown() - @test Base.iteratorsize(product(1:2, f1)) == Base.SizeUnknown() - @test Base.iteratorsize(product(f1, 1:2)) == Base.SizeUnknown() - @test Base.iteratorsize(product(f1, f1)) == Base.SizeUnknown() - @test Base.iteratorsize(product(f1, countfrom(1))) == Base.IsInfinite() - @test Base.iteratorsize(product(countfrom(1), f1)) == Base.IsInfinite() -end -@test Base.iteratorsize(product(1:2, countfrom(1))) == Base.IsInfinite() -@test Base.iteratorsize(product(countfrom(2), countfrom(1))) == Base.IsInfinite() -@test Base.iteratorsize(product(countfrom(1), 1:2)) == Base.IsInfinite() -@test Base.iteratorsize(product(1:2)) == Base.HasShape() -@test Base.iteratorsize(product(1:2, 1:2)) == Base.HasShape() -@test Base.iteratorsize(product(take(1:2, 1), take(1:2, 1))) == Base.HasShape() -@test Base.iteratorsize(product(take(1:2, 2))) == Base.HasShape() -@test Base.iteratorsize(product([1 2; 3 4])) == Base.HasShape() - -# iteratoreltype trait business + @test Base.IteratorSize(product(f1)) == Base.SizeUnknown() + @test Base.IteratorSize(product(1:2, f1)) == Base.SizeUnknown() + @test Base.IteratorSize(product(f1, 1:2)) == Base.SizeUnknown() + @test Base.IteratorSize(product(f1, f1)) == Base.SizeUnknown() + @test Base.IteratorSize(product(f1, countfrom(1))) == Base.IsInfinite() + @test Base.IteratorSize(product(countfrom(1), f1)) == Base.IsInfinite() +end +@test Base.IteratorSize(product(1:2, countfrom(1))) == Base.IsInfinite() +@test Base.IteratorSize(product(countfrom(2), countfrom(1))) == Base.IsInfinite() +@test Base.IteratorSize(product(countfrom(1), 1:2)) == Base.IsInfinite() +@test Base.IteratorSize(product(1:2)) == Base.HasShape() +@test Base.IteratorSize(product(1:2, 1:2)) == Base.HasShape() +@test Base.IteratorSize(product(take(1:2, 1), take(1:2, 1))) == Base.HasShape() +@test Base.IteratorSize(product(take(1:2, 2))) == Base.HasShape() +@test Base.IteratorSize(product([1 2; 3 4])) == Base.HasShape() + +# IteratorEltype trait business let f1 = Iterators.filter(i->i>0, 1:10) - @test Base.iteratoreltype(product(f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.iteratoreltype(product(1:2, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.iteratoreltype(product(f1, 1:2)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.iteratoreltype(product(f1, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.iteratoreltype(product(f1, countfrom(1))) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.iteratoreltype(product(countfrom(1), f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any -end -@test Base.iteratoreltype(product(1:2, countfrom(1))) == Base.HasEltype() -@test Base.iteratoreltype(product(countfrom(1), 1:2)) == Base.HasEltype() -@test Base.iteratoreltype(product(1:2)) == Base.HasEltype() -@test Base.iteratoreltype(product(1:2, 1:2)) == Base.HasEltype() -@test Base.iteratoreltype(product(take(1:2, 1), take(1:2, 1))) == Base.HasEltype() -@test Base.iteratoreltype(product(take(1:2, 2))) == Base.HasEltype() -@test Base.iteratoreltype(product([1 2; 3 4])) == Base.HasEltype() + @test Base.IteratorEltype(product(f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test Base.IteratorEltype(product(1:2, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test Base.IteratorEltype(product(f1, 1:2)) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test Base.IteratorEltype(product(f1, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test Base.IteratorEltype(product(f1, countfrom(1))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test Base.IteratorEltype(product(countfrom(1), f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any +end +@test Base.IteratorEltype(product(1:2, countfrom(1))) == Base.HasEltype() +@test Base.IteratorEltype(product(countfrom(1), 1:2)) == Base.HasEltype() +@test Base.IteratorEltype(product(1:2)) == Base.HasEltype() +@test Base.IteratorEltype(product(1:2, 1:2)) == Base.HasEltype() +@test Base.IteratorEltype(product(take(1:2, 1), take(1:2, 1))) == Base.HasEltype() +@test Base.IteratorEltype(product(take(1:2, 2))) == Base.HasEltype() +@test Base.IteratorEltype(product([1 2; 3 4])) == Base.HasEltype() @test collect(product(1:2,3:4)) == [(1,3) (1,4); (2,3) (2,4)] @test isempty(collect(product(1:0,1:2))) @test length(product(1:2,1:10,4:6)) == 60 -@test Base.iteratorsize(product(1:2, countfrom(1))) == Base.IsInfinite() +@test Base.IteratorSize(product(1:2, countfrom(1))) == Base.IsInfinite() # flatten # ------- @@ -359,7 +360,7 @@ end @test_throws ArgumentError length(flatten(NTuple[(1,), ()])) # #16680 @test_throws ArgumentError length(flatten([[1], [1]])) -@test Base.iteratoreltype(Base.Flatten((i for i=1:2) for j=1:1)) == Base.EltypeUnknown() +@test Base.IteratorEltype(Base.Flatten((i for i=1:2) for j=1:1)) == Base.EltypeUnknown() # partition(c, n) let v = collect(partition([1,2,3,4,5], 1)) @@ -444,8 +445,8 @@ end @test length(d) == length(A) @test keys(d) == keys(A) @test values(d) == A - @test Base.iteratorsize(d) == Base.HasLength() - @test Base.iteratoreltype(d) == Base.HasEltype() + @test Base.IteratorSize(d) == Base.HasLength() + @test Base.IteratorEltype(d) == Base.HasEltype() @test isempty(d) || haskey(d, first(keys(d))) @test collect(v for (k, v) in d) == vec(collect(A)) if A isa NamedTuple @@ -475,6 +476,7 @@ end end @testset "reverse iterators" begin + squash(x::Number) = x squash(A) = reshape(A, length(A)) Z = Array{Int,0}(uninitialized); Z[] = 17 # zero-dimensional test case for itr in (2:10, "∀ϵ>0", 1:0, "", (2,3,5,7,11), [2,3,5,7,11], rand(5,6), Z, 3, true, 'x', 4=>5, diff --git a/test/libgit2-online.jl b/test/libgit2-online.jl index 27dcd76374f85..16f7b18779e42 100644 --- a/test/libgit2-online.jl +++ b/test/libgit2-online.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + ######### # TESTS # ######### diff --git a/test/libgit2.jl b/test/libgit2.jl index c1251ac28d008..7d66638add955 100644 --- a/test/libgit2.jl +++ b/test/libgit2.jl @@ -2,7 +2,8 @@ isdefined(Main, :TestHelpers) || @eval Main include(joinpath(@__DIR__, "TestHelpers.jl")) import Main.TestHelpers: challenge_prompt -using Base.Unicode: lowercase + +using Random const LIBGIT2_MIN_VER = v"0.23.0" const LIBGIT2_HELPER_PATH = joinpath(@__DIR__, "libgit2-helpers.jl") diff --git a/test/linalg/adjtrans.jl b/test/linalg/adjtrans.jl index cad11f67a3de6..dedcdce6cfa74 100644 --- a/test/linalg/adjtrans.jl +++ b/test/linalg/adjtrans.jl @@ -4,6 +4,7 @@ using Test using Base.LinAlg: Adjoint, Transpose +using SparseArrays @testset "Adjoint and Transpose inner constructor basics" begin intvec, intmat = [1, 2], [1 2; 3 4] @@ -62,23 +63,12 @@ end # the tests for the inner constructors exercise abstract scalar and concrete array eltype, forgoing here end -@testset "Adjoint and Transpose of Numbers" begin - @test Adjoint(1) == 1 - @test Adjoint(1.0) == 1.0 - @test Adjoint(1im) == -1im - @test Adjoint(1.0im) == -1.0im - @test Transpose(1) == 1 - @test Transpose(1.0) == 1.0 - @test Transpose(1im) == 1im - @test Transpose(1.0im) == 1.0im -end - -@testset "Adjoint and Transpose unwrapping" begin +@testset "Adjoint and Transpose add additional layers to already-wrapped objects" begin intvec, intmat = [1, 2], [1 2; 3 4] - @test Adjoint(Adjoint(intvec)) === intvec - @test Adjoint(Adjoint(intmat)) === intmat - @test Transpose(Transpose(intvec)) === intvec - @test Transpose(Transpose(intmat)) === intmat + @test (A = Adjoint(Adjoint(intvec))::Adjoint{Int,Adjoint{Int,Vector{Int}}}; A.parent.parent === intvec) + @test (A = Adjoint(Adjoint(intmat))::Adjoint{Int,Adjoint{Int,Matrix{Int}}}; A.parent.parent === intmat) + @test (A = Transpose(Transpose(intvec))::Transpose{Int,Transpose{Int,Vector{Int}}}; A.parent.parent === intvec) + @test (A = Transpose(Transpose(intmat))::Transpose{Int,Transpose{Int,Matrix{Int}}}; A.parent.parent === intmat) end @testset "Adjoint and Transpose basic AbstractArray functionality" begin @@ -365,13 +355,13 @@ end @test complexvec * Transpose(complexvec) == broadcast(*, complexvec, reshape(complexvec, (1, 3))) # Adjoint/Transpose-vector * matrix @test (Adjoint(realvec) * realmat)::Adjoint{Int,Vector{Int}} == - reshape(adjoint(realmat) * realvec, (1, 3)) + reshape(copy(Adjoint(realmat)) * realvec, (1, 3)) @test (Transpose(realvec) * realmat)::Transpose{Int,Vector{Int}} == - reshape(transpose(realmat) * realvec, (1, 3)) + reshape(copy(Transpose(realmat)) * realvec, (1, 3)) @test (Adjoint(complexvec) * complexmat)::Adjoint{Complex{Int},Vector{Complex{Int}}} == - reshape(conj(adjoint(complexmat) * complexvec), (1, 3)) + reshape(conj(copy(Adjoint(complexmat)) * complexvec), (1, 3)) @test (Transpose(complexvec) * complexmat)::Transpose{Complex{Int},Vector{Complex{Int}}} == - reshape(transpose(complexmat) * complexvec, (1, 3)) + reshape(copy(Transpose(complexmat)) * complexvec, (1, 3)) # Adjoint/Transpose-vector * Adjoint/Transpose-matrix @test (Adjoint(realvec) * Adjoint(realmat))::Adjoint{Int,Vector{Int}} == reshape(realmat * realvec, (1, 3)) @@ -414,15 +404,15 @@ end @test (Transpose(realvec) / realmat)::Transpose ≈ rowrealvec / realmat @test (Transpose(complexvec) / complexmat)::Transpose ≈ rowcomplexvec / complexmat # /(Adjoint/Transpose-vector, Adjoint matrix) - @test (Adjoint(realvec) / Adjoint(realmat))::Adjoint ≈ rowrealvec / adjoint(realmat) - @test (Adjoint(complexvec) / Adjoint(complexmat))::Adjoint ≈ conj(rowcomplexvec) / adjoint(complexmat) - @test (Transpose(realvec) / Adjoint(realmat))::Transpose ≈ rowrealvec / adjoint(realmat) - @test (Transpose(complexvec) / Adjoint(complexmat))::Transpose ≈ rowcomplexvec / adjoint(complexmat) + @test (Adjoint(realvec) / Adjoint(realmat))::Adjoint ≈ rowrealvec / copy(Adjoint(realmat)) + @test (Adjoint(complexvec) / Adjoint(complexmat))::Adjoint ≈ conj(rowcomplexvec) / copy(Adjoint(complexmat)) + @test (Transpose(realvec) / Adjoint(realmat))::Transpose ≈ rowrealvec / copy(Adjoint(realmat)) + @test (Transpose(complexvec) / Adjoint(complexmat))::Transpose ≈ rowcomplexvec / copy(Adjoint(complexmat)) # /(Adjoint/Transpose-vector, Transpose matrix) - @test (Adjoint(realvec) / Transpose(realmat))::Adjoint ≈ rowrealvec / transpose(realmat) - @test (Adjoint(complexvec) / Transpose(complexmat))::Adjoint ≈ conj(rowcomplexvec) / transpose(complexmat) - @test (Transpose(realvec) / Transpose(realmat))::Transpose ≈ rowrealvec / transpose(realmat) - @test (Transpose(complexvec) / Transpose(complexmat))::Transpose ≈ rowcomplexvec / transpose(complexmat) + @test (Adjoint(realvec) / Transpose(realmat))::Adjoint ≈ rowrealvec / copy(Transpose(realmat)) + @test (Adjoint(complexvec) / Transpose(complexmat))::Adjoint ≈ conj(rowcomplexvec) / copy(Transpose(complexmat)) + @test (Transpose(realvec) / Transpose(realmat))::Transpose ≈ rowrealvec / copy(Transpose(realmat)) + @test (Transpose(complexvec) / Transpose(complexmat))::Transpose ≈ rowcomplexvec / copy(Transpose(complexmat)) end @testset "norm of Adjoint/Transpose-wrapped vectors" begin @@ -441,6 +431,17 @@ end end end +@testset "adjoint and transpose of Numbers" begin + @test adjoint(1) == 1 + @test adjoint(1.0) == 1.0 + @test adjoint(1im) == -1im + @test adjoint(1.0im) == -1.0im + @test transpose(1) == 1 + @test transpose(1.0) == 1.0 + @test transpose(1im) == 1im + @test transpose(1.0im) == 1.0im +end + @testset "adjoint!(a, b) return a" begin a = fill(1.0+im, 5) b = fill(1.0+im, 1, 5) diff --git a/test/linalg/bidiag.jl b/test/linalg/bidiag.jl index d48d55cb10554..11fa8dfdf5732 100644 --- a/test/linalg/bidiag.jl +++ b/test/linalg/bidiag.jl @@ -1,8 +1,9 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test -using Base.LinAlg: mul!, Adjoint, Transpose +using Test, Random +using Base.LinAlg: mul! import Base.LinAlg: BlasReal, BlasFloat +using SparseArrays n = 10 #Size of test matrix srand(1) @@ -163,22 +164,22 @@ srand(1) condT = cond(map(ComplexF64,Tfull)) promty = typeof((zero(relty)*zero(relty) + zero(relty)*zero(relty))/one(relty)) if relty != BigFloat - x = Transpose(T)\Transpose(c) - tx = Transpose(Tfull) \ Transpose(c) + x = transpose(T)\transpose(c) + tx = transpose(Tfull) \ transpose(c) elty <: AbstractFloat && @test norm(x-tx,Inf) <= 4*condT*max(eps()*norm(tx,Inf), eps(promty)*norm(x,Inf)) - @test_throws DimensionMismatch Transpose(T)\Transpose(b) - x = T'\transpose(c) - tx = Tfull'\transpose(c) + @test_throws DimensionMismatch transpose(T)\transpose(b) + x = T'\copy(transpose(c)) + tx = Tfull'\copy(transpose(c)) @test norm(x-tx,Inf) <= 4*condT*max(eps()*norm(tx,Inf), eps(promty)*norm(x,Inf)) - @test_throws DimensionMismatch T'\transpose(b) - x = T\Transpose(c) - tx = Tfull\Transpose(c) + @test_throws DimensionMismatch T'\copy(transpose(b)) + x = T\transpose(c) + tx = Tfull\transpose(c) @test norm(x-tx,Inf) <= 4*condT*max(eps()*norm(tx,Inf), eps(promty)*norm(x,Inf)) - @test_throws DimensionMismatch T\Transpose(b) + @test_throws DimensionMismatch T\transpose(b) end offsizemat = Matrix{elty}(uninitialized, n+1, 2) @test_throws DimensionMismatch T \ offsizemat - @test_throws DimensionMismatch Transpose(T) \ offsizemat + @test_throws DimensionMismatch transpose(T) \ offsizemat @test_throws DimensionMismatch T' \ offsizemat let bb = b, cc = c diff --git a/test/linalg/blas.jl b/test/linalg/blas.jl index 7bea5dea57cea..02379415ce630 100644 --- a/test/linalg/blas.jl +++ b/test/linalg/blas.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + import Base.LinAlg, Base.LinAlg.BlasReal, Base.LinAlg.BlasComplex srand(100) @@ -14,10 +16,10 @@ srand(100) end U = convert(Array{elty, 2}, U) V = convert(Array{elty, 2}, V) - @test tril(LinAlg.BLAS.syr2k('L','N',U,V)) ≈ tril(U*Transpose(V) + V*Transpose(U)) - @test triu(LinAlg.BLAS.syr2k('U','N',U,V)) ≈ triu(U*Transpose(V) + V*Transpose(U)) - @test tril(LinAlg.BLAS.syr2k('L','T',U,V)) ≈ tril(Transpose(U)*V + Transpose(V)*U) - @test triu(LinAlg.BLAS.syr2k('U','T',U,V)) ≈ triu(Transpose(U)*V + Transpose(V)*U) + @test tril(LinAlg.BLAS.syr2k('L','N',U,V)) ≈ tril(U*transpose(V) + V*transpose(U)) + @test triu(LinAlg.BLAS.syr2k('U','N',U,V)) ≈ triu(U*transpose(V) + V*transpose(U)) + @test tril(LinAlg.BLAS.syr2k('L','T',U,V)) ≈ tril(transpose(U)*V + transpose(V)*U) + @test triu(LinAlg.BLAS.syr2k('U','T',U,V)) ≈ triu(transpose(U)*V + transpose(V)*U) end if elty in (ComplexF32, ComplexF64) @@ -136,12 +138,12 @@ srand(100) A = rand(elty,n,n) A = A + transpose(A) @test issymmetric(A) - @test triu(BLAS.syr!('U',α,x,copy(A))) ≈ triu(A + α*x*Transpose(x)) + @test triu(BLAS.syr!('U',α,x,copy(A))) ≈ triu(A + α*x*transpose(x)) @test_throws DimensionMismatch BLAS.syr!('U',α,Vector{elty}(uninitialized,n+1),copy(A)) if elty <: Complex A = rand(elty,n,n) - A = A + adjoint(A) + A = A + A' α = real(α) @test triu(BLAS.her!('U',α,x,copy(A))) ≈ triu(A + α*x*x') @test_throws DimensionMismatch BLAS.her!('U',α,Vector{elty}(uninitialized,n+1),copy(A)) @@ -163,7 +165,7 @@ srand(100) @testset "symmetric/Hermitian multiplication" begin x = rand(elty,n) A = rand(elty,n,n) - Aherm = A + adjoint(A) + Aherm = A + A' Asymm = A + transpose(A) @testset "symv and hemv" begin @test BLAS.symv('U',Asymm,x) ≈ Asymm*x @@ -281,7 +283,7 @@ srand(100) @test_throws DimensionMismatch BLAS.gemm!('N','N', one(elty), I43, I4, elm1, I4) @test_throws DimensionMismatch BLAS.gemm!('T','N', one(elty), I43, I4, elm1, I43) @test_throws DimensionMismatch BLAS.gemm!('N','T', one(elty), I43, I43, elm1, I43) - @test_throws DimensionMismatch BLAS.gemm!('T','T', one(elty), I43, I43, elm1, adjoint(I43)) + @test_throws DimensionMismatch BLAS.gemm!('T','T', one(elty), I43, I43, elm1, Matrix{elty}(I, 3, 4)) end @testset "gemm compared to (sy)(he)rk" begin if eltype(elm1) <: Complex @@ -316,10 +318,10 @@ end @testset "syr for eltype $elty" for elty in (Float32, Float64, Complex{Float32}, Complex{Float64}) A = rand(elty, 5, 5) - @test triu(A[1,:] * Transpose(A[1,:])) ≈ BLAS.syr!('U', one(elty), A[1,:], zeros(elty, 5, 5)) - @test tril(A[1,:] * Transpose(A[1,:])) ≈ BLAS.syr!('L', one(elty), A[1,:], zeros(elty, 5, 5)) - @test triu(A[1,:] * Transpose(A[1,:])) ≈ BLAS.syr!('U', one(elty), view(A, 1, :), zeros(elty, 5, 5)) - @test tril(A[1,:] * Transpose(A[1,:])) ≈ BLAS.syr!('L', one(elty), view(A, 1, :), zeros(elty, 5, 5)) + @test triu(A[1,:] * transpose(A[1,:])) ≈ BLAS.syr!('U', one(elty), A[1,:], zeros(elty, 5, 5)) + @test tril(A[1,:] * transpose(A[1,:])) ≈ BLAS.syr!('L', one(elty), A[1,:], zeros(elty, 5, 5)) + @test triu(A[1,:] * transpose(A[1,:])) ≈ BLAS.syr!('U', one(elty), view(A, 1, :), zeros(elty, 5, 5)) + @test tril(A[1,:] * transpose(A[1,:])) ≈ BLAS.syr!('L', one(elty), view(A, 1, :), zeros(elty, 5, 5)) end @testset "her for eltype $elty" for elty in (Complex{Float32}, Complex{Float64}) diff --git a/test/linalg/bunchkaufman.jl b/test/linalg/bunchkaufman.jl index 41395fcaaf4c1..8189023bd2b4a 100644 --- a/test/linalg/bunchkaufman.jl +++ b/test/linalg/bunchkaufman.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random using Base: getproperty using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted @@ -24,8 +24,8 @@ bimg = randn(n,2)/2 a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real) asym = transpose(a) + a # symmetric indefinite - aher = adjoint(a) + a # Hermitian indefinite - apd = adjoint(a) * a # Positive-definite + aher = a' + a # Hermitian indefinite + apd = a' * a # Positive-definite for (a, a2, aher, apd) in ((a, a2, aher, apd), (view(a, 1:n, 1:n), view(a2, 1:n, 1:n), @@ -66,8 +66,8 @@ bimg = randn(n,2)/2 end bc1 = bkfact(Symmetric(asym, uplo)) - @test getproperty(bc1, uplo)*bc1.D*Transpose(getproperty(bc1, uplo)) ≈ asym[bc1.p, bc1.p] - @test getproperty(bc1, uplo)*bc1.D*Transpose(getproperty(bc1, uplo)) ≈ bc1.P*asym*Transpose(bc1.P) + @test getproperty(bc1, uplo)*bc1.D*transpose(getproperty(bc1, uplo)) ≈ asym[bc1.p, bc1.p] + @test getproperty(bc1, uplo)*bc1.D*transpose(getproperty(bc1, uplo)) ≈ bc1.P*asym*transpose(bc1.P) @test_throws ErrorException bc1.Z @test_throws ArgumentError uplo == :L ? bc1.U : bc1.L end diff --git a/test/linalg/cholesky.jl b/test/linalg/cholesky.jl index b95c54ea85a1a..5db4042b4cc89 100644 --- a/test/linalg/cholesky.jl +++ b/test/linalg/cholesky.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted, PosDefException @@ -217,7 +217,7 @@ end for uplo in (:U, :L) AcA = A'*A BcB = AcA + v*v' - BcB = (BcB + adjoint(BcB))/2 + BcB = (BcB + BcB')/2 F = cholfact(Hermitian(AcA, uplo)) G = cholfact(Hermitian(BcB, uplo)) @test Base.getproperty(LinAlg.lowrankupdate(F, v), uplo) ≈ Base.getproperty(G, uplo) diff --git a/test/linalg/dense.jl b/test/linalg/dense.jl index 9b968c0f82fa3..88427bd0d4912 100644 --- a/test/linalg/dense.jl +++ b/test/linalg/dense.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random @testset "Check that non-floats are correctly promoted" begin @test [1 0 0; 0 1 0]\[1,1] ≈ [1;1;0] @@ -66,7 +66,7 @@ bimg = randn(n,2)/2 end @testset "Test nullspace" begin - a15null = nullspace(adjoint(a[:,1:n1])) + a15null = nullspace(copy(a[:,1:n1]')) @test rank([a[:,1:n1] a15null]) == 10 @test norm(a[:,1:n1]'a15null,Inf) ≈ zero(eltya) atol=300ε @test norm(a15null'a[:,1:n1],Inf) ≈ zero(eltya) atol=400ε @@ -95,7 +95,7 @@ bimg = randn(n,2)/2 @testset "Matrix square root" begin asq = sqrt(a) @test asq*asq ≈ a - asym = adjoint(a)+a # symmetric indefinite + asym = a + a' # symmetric indefinite asymsq = sqrt(asym) @test asymsq*asymsq ≈ asym end @@ -349,9 +349,9 @@ end @testset "Matrix exponential" begin @testset "Tests for $elty" for elty in (Float32, Float64, ComplexF32, ComplexF64) A1 = convert(Matrix{elty}, [4 2 0; 1 4 1; 1 1 4]) - eA1 = convert(Matrix{elty}, adjoint([147.866622446369 127.781085523181 127.781085523182; + eA1 = convert(Matrix{elty}, [147.866622446369 127.781085523181 127.781085523182; 183.765138646367 183.765138646366 163.679601723179; - 71.797032399996 91.8825693231832 111.968106246371])) + 71.797032399996 91.8825693231832 111.968106246371]') @test exp(A1) ≈ eA1 A2 = convert(Matrix{elty}, @@ -365,9 +365,9 @@ end @test exp(A2) ≈ eA2 A3 = convert(Matrix{elty}, [-131 19 18;-390 56 54;-387 57 52]) - eA3 = convert(Matrix{elty}, adjoint([-1.50964415879218 -5.6325707998812 -4.934938326092; - 0.367879439109187 1.47151775849686 1.10363831732856; - 0.135335281175235 0.406005843524598 0.541341126763207])) + eA3 = convert(Matrix{elty}, [-1.50964415879218 -5.6325707998812 -4.934938326092; + 0.367879439109187 1.47151775849686 1.10363831732856; + 0.135335281175235 0.406005843524598 0.541341126763207]') @test exp(A3) ≈ eA3 A4 = convert(Matrix{elty}, [0.25 0.25; 0 0]) @@ -790,7 +790,7 @@ end @testset "/ and \\ consistency with pinv for vectors" begin @testset "Tests for type $elty" for elty in (Float32, Float64, ComplexF32, ComplexF64) c = rand(elty, 5) - r = (elty <: Complex ? Adjoint : Transpose)(rand(elty, 5)) + r = (elty <: Complex ? adjoint : transpose)(rand(elty, 5)) cm = rand(elty, 5, 1) rm = rand(elty, 1, 5) @testset "inner prodcuts" begin diff --git a/test/linalg/diagonal.jl b/test/linalg/diagonal.jl index 2c8fb4cab6539..bab600a4c9d54 100644 --- a/test/linalg/diagonal.jl +++ b/test/linalg/diagonal.jl @@ -1,8 +1,9 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test -using Base.LinAlg: mul!, ldiv!, rdiv!, Adjoint, Transpose -import Base.LinAlg: BlasFloat, BlasComplex, SingularException +using Test, Random +using Base.LinAlg: mul!, mul1!, mul2!, ldiv!, rdiv!, + BlasFloat, BlasComplex, SingularException +using SparseArrays n=12 #Size of matrix problem to test srand(1) @@ -89,7 +90,7 @@ srand(1) @test D*v ≈ DM*v atol=n*eps(relty)*(1+(elty<:Complex)) @test D*U ≈ DM*U atol=n^2*eps(relty)*(1+(elty<:Complex)) - @test Transpose(U)*D ≈ Transpose(U)*Array(D) + @test transpose(U)*D ≈ transpose(U)*Array(D) @test U'*D ≈ U'*Array(D) if relty != BigFloat @@ -98,18 +99,18 @@ srand(1) @test D\v ≈ DM\v atol=atol_two @test D\U ≈ DM\U atol=atol_three @test ldiv!(D, copy(v)) ≈ DM\v atol=atol_two - @test ldiv!(Transpose(D), copy(v)) ≈ DM\v atol=atol_two - @test ldiv!(Adjoint(conj(D)), copy(v)) ≈ DM\v atol=atol_two + @test ldiv!(transpose(D), copy(v)) ≈ DM\v atol=atol_two + @test ldiv!(adjoint(conj(D)), copy(v)) ≈ DM\v atol=atol_two @test ldiv!(D, copy(U)) ≈ DM\U atol=atol_three - @test ldiv!(Transpose(D), copy(U)) ≈ DM\U atol=atol_three - @test ldiv!(Adjoint(conj(D)), copy(U)) ≈ DM\U atol=atol_three - Uc = adjoint(U) + @test ldiv!(transpose(D), copy(U)) ≈ DM\U atol=atol_three + @test ldiv!(adjoint(conj(D)), copy(U)) ≈ DM\U atol=atol_three + Uc = copy(U') target = scale!(Uc, inv.(D.diag)) @test rdiv!(Uc, D) ≈ target atol=atol_three @test_throws DimensionMismatch rdiv!(Matrix{elty}(I, n-1, n-1), D) @test_throws SingularException rdiv!(Uc, Diagonal(fill!(similar(D.diag), 0))) - @test rdiv!(Uc, Transpose(D)) ≈ target atol=atol_three - @test rdiv!(Uc, Adjoint(conj(D))) ≈ target atol=atol_three + @test rdiv!(Uc, transpose(D)) ≈ target atol=atol_three + @test rdiv!(Uc, adjoint(conj(D))) ≈ target atol=atol_three @test ldiv!(D, Matrix{eltype(D)}(I, size(D))) ≈ D \ Matrix{eltype(D)}(I, size(D)) atol=atol_three @test_throws DimensionMismatch ldiv!(D, fill(elty(1), n + 1)) @test_throws SingularException ldiv!(Diagonal(zeros(relty, n)), copy(v)) @@ -117,7 +118,7 @@ srand(1) b = sparse(b) @test ldiv!(D, copy(b)) ≈ Array(D)\Array(b) @test_throws SingularException ldiv!(Diagonal(zeros(elty, n)), copy(b)) - b = view(rand(elty, n), collect(1:n)) + b = view(rand(elty, n), Vector(1:n)) b2 = copy(b) c = ldiv!(D, b) d = Array(D)\b2 @@ -126,7 +127,7 @@ srand(1) b = rand(elty, n+1, n+1) b = sparse(b) @test_throws DimensionMismatch ldiv!(D, copy(b)) - b = view(rand(elty, n+1), collect(1:n+1)) + b = view(rand(elty, n+1), Vector(1:n+1)) @test_throws DimensionMismatch ldiv!(D, b) end end @@ -146,16 +147,16 @@ srand(1) if relty <: BlasFloat b = rand(elty,n,n) b = sparse(b) - @test mul!(copy(D), copy(b)) ≈ Array(D)*Array(b) - @test mul!(Transpose(copy(D)), copy(b)) ≈ Transpose(Array(D))*Array(b) - @test mul!(Adjoint(copy(D)), copy(b)) ≈ Array(D)'*Array(b) + @test mul2!(copy(D), copy(b)) ≈ Array(D)*Array(b) + @test mul2!(transpose(copy(D)), copy(b)) ≈ transpose(Array(D))*Array(b) + @test mul2!(adjoint(copy(D)), copy(b)) ≈ Array(D)'*Array(b) end end #a few missing mults bd = Bidiagonal(D2) - @test D*Transpose(D2) ≈ Array(D)*Transpose(Array(D2)) - @test D2*Transpose(D) ≈ Array(D2)*Transpose(Array(D)) + @test D*transpose(D2) ≈ Array(D)*transpose(Array(D2)) + @test D2*transpose(D) ≈ Array(D2)*transpose(Array(D)) @test D2*D' ≈ Array(D2)*Array(D)' #division of two Diagonals @@ -165,25 +166,25 @@ srand(1) # Performance specialisations for A*_mul_B! vvv = similar(vv) @test (r = Matrix(D) * vv ; mul!(vvv, D, vv) ≈ r ≈ vvv) - @test (r = Matrix(D)' * vv ; mul!(vvv, Adjoint(D), vv) ≈ r ≈ vvv) - @test (r = Transpose(Matrix(D)) * vv ; mul!(vvv, Transpose(D), vv) ≈ r ≈ vvv) + @test (r = Matrix(D)' * vv ; mul!(vvv, adjoint(D), vv) ≈ r ≈ vvv) + @test (r = transpose(Matrix(D)) * vv ; mul!(vvv, transpose(D), vv) ≈ r ≈ vvv) UUU = similar(UU) @test (r = Matrix(D) * UU ; mul!(UUU, D, UU) ≈ r ≈ UUU) - @test (r = Matrix(D)' * UU ; mul!(UUU, Adjoint(D), UU) ≈ r ≈ UUU) - @test (r = Transpose(Matrix(D)) * UU ; mul!(UUU, Transpose(D), UU) ≈ r ≈ UUU) + @test (r = Matrix(D)' * UU ; mul!(UUU, adjoint(D), UU) ≈ r ≈ UUU) + @test (r = transpose(Matrix(D)) * UU ; mul!(UUU, transpose(D), UU) ≈ r ≈ UUU) # make sure that mul!(A, {Adj|Trans}(B)) works with B as a Diagonal VV = Array(D) DD = copy(D) r = VV * Matrix(D) - @test Array(mul!(VV, DD)) ≈ r ≈ Array(D)*Array(D) + @test Array(mul1!(VV, DD)) ≈ r ≈ Array(D)*Array(D) DD = copy(D) - r = VV * Transpose(Array(D)) - @test Array(mul!(VV, Transpose(DD))) ≈ r + r = VV * transpose(Array(D)) + @test Array(mul1!(VV, transpose(DD))) ≈ r DD = copy(D) r = VV * Array(D)' - @test Array(mul!(VV, Adjoint(DD))) ≈ r + @test Array(mul1!(VV, adjoint(DD))) ≈ r end @testset "triu/tril" begin @test istriu(D) @@ -228,7 +229,7 @@ srand(1) end # Translates to Ac/t_mul_B, which is specialized after issue 21286 @test(D' * vv == conj(D) * vv) - @test(Transpose(D) * vv == D * vv) + @test(transpose(D) * vv == D * vv) end #logdet @@ -339,17 +340,20 @@ end D = Diagonal(randn(5)) @test T*D == Array(T)*Array(D) @test T'D == Array(T)'*Array(D) - @test Transpose(T)*D == Transpose(Array(T))*Array(D) + @test transpose(T)*D == transpose(Array(T))*Array(D) @test D*T' == Array(D)*Array(T)' - @test D*Transpose(T) == Array(D)*Transpose(Array(T)) + @test D*transpose(T) == Array(D)*transpose(Array(T)) @test D*T == Array(D)*Array(T) end end let D1 = Diagonal(rand(5)), D2 = Diagonal(rand(5)) - @test_throws MethodError mul!(D1,D2) - @test_throws MethodError mul!(Transpose(D1),D2) - @test_throws MethodError mul!(Adjoint(D1),D2) + @test LinAlg.mul1!(copy(D1),D2) == D1*D2 + @test LinAlg.mul2!(D1,copy(D2)) == D1*D2 + @test LinAlg.mul1!(copy(D1),transpose(D2)) == D1*transpose(D2) + @test LinAlg.mul2!(transpose(D1),copy(D2)) == transpose(D1)*D2 + @test LinAlg.mul1!(copy(D1),adjoint(D2)) == D1*adjoint(D2) + @test LinAlg.mul2!(adjoint(D1),copy(D2)) == adjoint(D1)*D2 end @testset "multiplication of QR Q-factor and Diagonal (#16615 spot test)" begin @@ -357,7 +361,7 @@ end Q = qrfact(randn(5, 5)).Q @test D * Q' == Array(D) * Q' Q = qrfact(randn(5, 5), Val(true)).Q - @test_throws MethodError mul!(Q, D) + @test_throws ArgumentError mul2!(Q, D) end @testset "block diagonal matrices" begin @@ -373,7 +377,7 @@ end v = [[1, 2], [3, 4]] @test Dherm' * v == Dherm * v - @test Transpose(D) * v == [[7, 10], [15, 22]] + @test transpose(D) * v == [[7, 10], [15, 22]] @test issymmetric(D) == false @test issymmetric(Dherm) == false @@ -395,8 +399,8 @@ end S = Symmetric(A) H = Hermitian(A) for (transform1, transform2) in ((identity, identity), - (identity, Adjoint ), (Adjoint, identity ), (Adjoint, Adjoint ), - (identity, Transpose), (Transpose, identity ), (Transpose, Transpose) ) + (identity, adjoint ), (adjoint, identity ), (adjoint, adjoint ), + (identity, transpose), (transpose, identity ), (transpose, transpose) ) @test *(transform1(D), transform2(S)) ≈ *(transform1(Matrix(D)), transform2(Matrix(S))) @test *(transform1(D), transform2(H)) ≈ *(transform1(Matrix(D)), transform2(Matrix(H))) @test *(transform1(S), transform2(D)) ≈ *(transform1(Matrix(S)), transform2(Matrix(D))) @@ -414,15 +418,15 @@ end fullDD = copyto!(Matrix{Matrix{T}}(uninitialized, 2, 2), DD) fullBB = copyto!(Matrix{Matrix{T}}(uninitialized, 2, 2), BB) for (transform1, transform2) in ((identity, identity), - (identity, Adjoint ), (Adjoint, identity ), (Adjoint, Adjoint ), - (identity, Transpose), (Transpose, identity ), (Transpose, Transpose) ) + (identity, adjoint ), (adjoint, identity ), (adjoint, adjoint ), + (identity, transpose), (transpose, identity ), (transpose, transpose) ) @test *(transform1(D), transform2(B))::typeof(D) ≈ *(transform1(Matrix(D)), transform2(Matrix(B))) atol=2 * eps() @test *(transform1(DD), transform2(BB))::typeof(DD) == *(transform1(fullDD), transform2(fullBB)) end end end -@testset "Diagonal of Adjoint/Transpose vectors (#23649)" begin - @test Diagonal(Adjoint([1, 2, 3])) == Diagonal([1 2 3]) - @test Diagonal(Transpose([1, 2, 3])) == Diagonal([1 2 3]) +@testset "Diagonal of adjoint/transpose vectors (#23649)" begin + @test Diagonal(adjoint([1, 2, 3])) == Diagonal([1 2 3]) + @test Diagonal(transpose([1, 2, 3])) == Diagonal([1 2 3]) end diff --git a/test/linalg/eigen.jl b/test/linalg/eigen.jl index 57940617e5961..9f41d92cec4be 100644 --- a/test/linalg/eigen.jl +++ b/test/linalg/eigen.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted @@ -17,8 +17,8 @@ aimg = randn(n,n)/2 @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64, Int) aa = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) - asym = adjoint(aa)+aa # symmetric indefinite - apd = aa'*aa # symmetric positive-definite + asym = aa' + aa # symmetric indefinite + apd = aa' * aa # symmetric positive-definite for (a, asym, apd) in ((aa, asym, apd), (view(aa, 1:n, 1:n), view(asym, 1:n, 1:n), @@ -49,8 +49,8 @@ aimg = randn(n,n)/2 h = asym @test minimum(eigvals(h)) ≈ eigmin(h) @test maximum(eigvals(h)) ≈ eigmax(h) - @test_throws DomainError eigmin(a - adjoint(a)) - @test_throws DomainError eigmax(a - adjoint(a)) + @test_throws DomainError eigmin(a - a') + @test_throws DomainError eigmax(a - a') end @testset "symmetric generalized eigenproblem" begin if isa(a, Array) diff --git a/test/linalg/generic.jl b/test/linalg/generic.jl index 6e3ed0f8a6a57..91768783cca17 100644 --- a/test/linalg/generic.jl +++ b/test/linalg/generic.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license import Base: -, *, /, \ -using Test +using Test, Random # A custom Quaternion type with minimal defined interface and methods. # Used to test scale and scale! methods to show non-commutativity. @@ -163,10 +163,10 @@ end α, β = 'f', 'g' @test_throws DimensionMismatch Base.LinAlg.axpy!(α,x,['g']) @test_throws DimensionMismatch Base.LinAlg.axpby!(α,x,β,['g']) - @test_throws BoundsError Base.LinAlg.axpy!(α,x,collect(-1:5),y,collect(1:7)) - @test_throws BoundsError Base.LinAlg.axpy!(α,x,collect(1:7),y,collect(-1:5)) - @test_throws BoundsError Base.LinAlg.axpy!(α,x,collect(1:7),y,collect(1:7)) - @test_throws DimensionMismatch Base.LinAlg.axpy!(α,x,collect(1:3),y,collect(1:5)) + @test_throws BoundsError Base.LinAlg.axpy!(α,x,Vector(-1:5),y,Vector(1:7)) + @test_throws BoundsError Base.LinAlg.axpy!(α,x,Vector(1:7),y,Vector(-1:5)) + @test_throws BoundsError Base.LinAlg.axpy!(α,x,Vector(1:7),y,Vector(1:7)) + @test_throws DimensionMismatch Base.LinAlg.axpy!(α,x,Vector(1:3),y,Vector(1:5)) end @test !issymmetric(fill(1,5,3)) diff --git a/test/linalg/givens.jl b/test/linalg/givens.jl index 8d12900a6bb9c..dcf79506b2062 100644 --- a/test/linalg/givens.jl +++ b/test/linalg/givens.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test -using Base.LinAlg: mul!, Adjoint, Transpose +using Test, Random +using Base.LinAlg: mul1!, mul2! # Test givens rotations @testset for elty in (Float32, Float64, ComplexF32, ComplexF64) @@ -16,15 +16,15 @@ using Base.LinAlg: mul!, Adjoint, Transpose for j = 1:8 for i = j+2:10 G, _ = givens(A, j+1, i, j) - mul!(G, A) - mul!(A, Adjoint(G)) - mul!(G, R) + mul2!(G, A) + mul1!(A, adjoint(G)) + mul2!(G, R) - @test mul!(G,Matrix{elty}(I, 10, 10)) == [G[i,j] for i=1:10,j=1:10] + @test mul2!(G,Matrix{elty}(I, 10, 10)) == [G[i,j] for i=1:10,j=1:10] @testset "transposes" begin - @test adjoint(G)*G*Matrix(elty(1)I, 10, 10) ≈ Matrix(I, 10, 10) - @test adjoint(R)*(R*Matrix(elty(1)I, 10, 10)) ≈ Matrix(I, 10, 10) + @test copy(G')*G*Matrix(elty(1)I, 10, 10) ≈ Matrix(I, 10, 10) + @test copy(R')*(R*Matrix(elty(1)I, 10, 10)) ≈ Matrix(I, 10, 10) @test_throws ErrorException transpose(G) @test_throws ErrorException transpose(R) end @@ -33,16 +33,16 @@ using Base.LinAlg: mul!, Adjoint, Transpose @test_throws ArgumentError givens(A, 3, 3, 2) @test_throws ArgumentError givens(one(elty),zero(elty),2,2) G, _ = givens(one(elty),zero(elty),11,12) - @test_throws DimensionMismatch mul!(G, A) - @test_throws DimensionMismatch mul!(A, Adjoint(G)) + @test_throws DimensionMismatch mul2!(G, A) + @test_throws DimensionMismatch mul1!(A, adjoint(G)) @test abs.(A) ≈ abs.(hessfact(Ac).H) @test norm(R*Matrix{elty}(I, 10, 10)) ≈ one(elty) I10 = Matrix{elty}(I, 10, 10) G, _ = givens(one(elty),zero(elty),9,10) - @test adjoint(G*I10) * (G*I10) ≈ I10 + @test (G*I10)' * (G*I10) ≈ I10 K, _ = givens(zero(elty),one(elty),9,10) - @test adjoint(K*I10) * (K*I10) ≈ I10 + @test (K*I10)' * (K*I10) ≈ I10 @testset "Givens * vectors" begin if isa(A, Array) diff --git a/test/linalg/hessenberg.jl b/test/linalg/hessenberg.jl index 48cfb3de877aa..6e155d46ef1f4 100644 --- a/test/linalg/hessenberg.jl +++ b/test/linalg/hessenberg.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted diff --git a/test/linalg/lapack.jl b/test/linalg/lapack.jl index 489896b291696..07c956d1a5c12 100644 --- a/test/linalg/lapack.jl +++ b/test/linalg/lapack.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random import Base.LinAlg.BlasInt @@ -148,7 +148,7 @@ end B = rand(elty, 10, 10) C, j = LAPACK.gelsd!(copy(A),copy(B)) D, k = LAPACK.gelsy!(copy(A),copy(B)) - @test C ≈ D rtol=eps(cond(A)) + @test C ≈ D rtol=4*eps(cond(A)) @test_throws DimensionMismatch LAPACK.gelsd!(A,rand(elty,12,10)) @test_throws DimensionMismatch LAPACK.gelsy!(A,rand(elty,12,10)) end @@ -170,7 +170,7 @@ end lU,lS,lVt = LAPACK.gesvd!('S','S',A) @test U ≈ lU @test S ≈ lS - @test adjoint(V) ≈ lVt + @test V' ≈ lVt B = rand(elty,10,10) # xggsvd3 replaced xggsvd in LAPACK 3.6.0 if LAPACK.version() < v"3.6.0" @@ -203,7 +203,7 @@ end Bvs = eigvecs(B) Avs = eigvecs(A) Bvs = LAPACK.gebak!('S','R',ilo,ihi,scale,Bvs) - @test norm(diff(Avs ./ Bvs)) < 100 * eps(abs(float(one(elty)))) + @test norm(diff(Avs ./ Bvs, 1)) < 100 * eps(abs(float(one(elty)))) end end @@ -396,7 +396,7 @@ end @testset "hetrf, hetrs" begin @testset for elty in (ComplexF32, ComplexF64) A = rand(elty,10,10) - A = A + adjoint(A) #hermitian! + A = A + A' #hermitian! B = copy(A) B,ipiv = LAPACK.hetrf!('U',B) @test_throws DimensionMismatch LAPACK.hetrs!('U',B,ipiv,rand(elty,11,5)) @@ -459,14 +459,14 @@ end @testset for elty in (ComplexF32, ComplexF64) srand(935) A = rand(elty,10,10) - A = A + adjoint(A) #hermitian! + A = A + A' #hermitian! b = rand(elty,10) c = A \ b b,A = LAPACK.hesv!('U',A,b) @test b ≈ c @test_throws DimensionMismatch LAPACK.hesv!('U',A,rand(elty,11)) A = rand(elty,10,10) - A = A + adjoint(A) #hermitian! + A = A + A' #hermitian! b = rand(elty,10) c = A \ b b,A = LAPACK.hesv_rook!('U',A,b) @@ -523,7 +523,7 @@ end A = rand(elty,n,n)/100 A += real(diagm(0 => n*real(rand(elty,n)))) if elty <: Complex - A = A + adjoint(A) + A = A + A' else A = A + transpose(A) end diff --git a/test/linalg/lq.jl b/test/linalg/lq.jl index 8bb610911812a..c201b7eb98728 100644 --- a/test/linalg/lq.jl +++ b/test/linalg/lq.jl @@ -1,8 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random -using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, mul!, Adjoint, Transpose +using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, mul1!, mul2! n = 10 @@ -21,14 +21,14 @@ breal = randn(n,2)/2 bimg = randn(n,2)/2 # helper functions to unambiguously recover explicit forms of an LQPackedQ -squareQ(Q::LinAlg.LQPackedQ) = (n = size(Q.factors, 2); mul!(Q, Matrix{eltype(Q)}(I, n, n))) +squareQ(Q::LinAlg.LQPackedQ) = (n = size(Q.factors, 2); mul2!(Q, Matrix{eltype(Q)}(I, n, n))) rectangularQ(Q::LinAlg.LQPackedQ) = convert(Array, Q) @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64) a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real) - asym = adjoint(a)+a # symmetric indefinite - apd = a'*a # symmetric positive-definite + asym = a' + a # symmetric indefinite + apd = a' * a # symmetric positive-definite ε = εa = eps(abs(float(one(eltya)))) @testset for eltyb in (Float32, Float64, ComplexF32, ComplexF64, Int) @@ -53,9 +53,7 @@ rectangularQ(Q::LinAlg.LQPackedQ) = convert(Array, Q) @test size(lqa,3) == 1 @test size(lqa.Q,3) == 1 @test_throws ErrorException lqa.Z - @test Array(adjoint(lqa)) ≈ a' - @test lqa * lqa' ≈ a * a' - @test lqa' * lqa ≈ a' * a + @test Array(copy(adjoint(lqa))) ≈ a' @test q*squareQ(q)' ≈ Matrix(I, n, n) @test l*q ≈ a @test Array(lqa) ≈ a @@ -67,27 +65,27 @@ rectangularQ(Q::LinAlg.LQPackedQ) = convert(Array, Q) @testset "Binary ops" begin @test a*(lqa\b) ≈ b atol=3000ε @test lqa*b ≈ qra.Q*qra.R*b atol=3000ε - @test (sq = size(q.factors, 2); *(Matrix{eltyb}(I, sq, sq), Adjoint(q))*squareQ(q)) ≈ Matrix(I, n, n) atol=5000ε + @test (sq = size(q.factors, 2); *(Matrix{eltyb}(I, sq, sq), adjoint(q))*squareQ(q)) ≈ Matrix(I, n, n) atol=5000ε if eltya != Int @test Matrix{eltyb}(I, n, n)*q ≈ convert(AbstractMatrix{tab},q) end @test q*b ≈ squareQ(q)*b atol=100ε - @test Transpose(q)*b ≈ Transpose(squareQ(q))*b atol=100ε + @test transpose(q)*b ≈ transpose(squareQ(q))*b atol=100ε @test q'*b ≈ squareQ(q)'*b atol=100ε @test a*q ≈ a*squareQ(q) atol=100ε - @test a*Transpose(q) ≈ a*Transpose(squareQ(q)) atol=100ε + @test a*transpose(q) ≈ a*transpose(squareQ(q)) atol=100ε @test a*q' ≈ a*squareQ(q)' atol=100ε @test a'*q ≈ a'*squareQ(q) atol=100ε @test a'*q' ≈ a'*squareQ(q)' atol=100ε @test_throws DimensionMismatch q*b[1:n1 + 1] - @test_throws DimensionMismatch Adjoint(q) * Matrix{eltya}(uninitialized,n+2,n+2) + @test_throws DimensionMismatch adjoint(q) * Matrix{eltya}(uninitialized,n+2,n+2) @test_throws DimensionMismatch Matrix{eltyb}(uninitialized,n+2,n+2)*q if isa(a, DenseArray) && isa(b, DenseArray) # use this to test 2nd branch in mult code pad_a = vcat(I, a) pad_b = hcat(I, b) @test pad_a*q ≈ pad_a*squareQ(q) atol=100ε - @test Transpose(q)*pad_b ≈ Transpose(squareQ(q))*pad_b atol=100ε + @test transpose(q)*pad_b ≈ transpose(squareQ(q))*pad_b atol=100ε @test q'*pad_b ≈ squareQ(q)'*pad_b atol=100ε end end @@ -99,9 +97,9 @@ rectangularQ(Q::LinAlg.LQPackedQ) = convert(Array, Q) l,q = lqa.L, lqa.Q @test rectangularQ(q)*rectangularQ(q)' ≈ Matrix(I, n1, n1) @test squareQ(q)'*squareQ(q) ≈ Matrix(I, n1, n1) - @test_throws DimensionMismatch mul!(Matrix{eltya}(I, n+1, n+1),q) - @test mul!(Adjoint(q), rectangularQ(q)) ≈ Matrix(I, n1, n1) - @test_throws DimensionMismatch mul!(Matrix{eltya}(I, n+1, n+1), Adjoint(q)) + @test_throws DimensionMismatch mul1!(Matrix{eltya}(I, n+1, n+1),q) + @test mul2!(adjoint(q), rectangularQ(q)) ≈ Matrix(I, n1, n1) + @test_throws DimensionMismatch mul1!(Matrix{eltya}(I, n+1, n+1), adjoint(q)) @test_throws BoundsError size(q,-1) end end @@ -149,7 +147,7 @@ end function getqs(F::Base.LinAlg.LQ) implicitQ = F.Q sq = size(implicitQ.factors, 2) - explicitQ = mul!(implicitQ, Matrix{eltype(implicitQ)}(I, sq, sq)) + explicitQ = mul2!(implicitQ, Matrix{eltype(implicitQ)}(I, sq, sq)) return implicitQ, explicitQ end @@ -190,7 +188,7 @@ end @testset "postmultiplication with / right-application of LQPackedQ (#23779)" begin function getqs(F::Base.LinAlg.LQ) implicitQ = F.Q - explicitQ = mul!(implicitQ, Matrix{eltype(implicitQ)}(I, size(implicitQ)...)) + explicitQ = mul2!(implicitQ, Matrix{eltype(implicitQ)}(I, size(implicitQ)...)) return implicitQ, explicitQ end # for any shape m-by-n of LQ-factored matrix, where Q is an LQPackedQ @@ -200,9 +198,9 @@ end implicitQ, explicitQ = getqs(lqfact(randn(mA, nA))) C = randn(nA, nA) @test *(C, implicitQ) ≈ *(C, explicitQ) - @test *(C, Adjoint(implicitQ)) ≈ *(C, Adjoint(explicitQ)) - @test *(Adjoint(C), implicitQ) ≈ *(Adjoint(C), explicitQ) - @test *(Adjoint(C), Adjoint(implicitQ)) ≈ *(Adjoint(C), Adjoint(explicitQ)) + @test *(C, adjoint(implicitQ)) ≈ *(C, adjoint(explicitQ)) + @test *(adjoint(C), implicitQ) ≈ *(adjoint(C), explicitQ) + @test *(adjoint(C), adjoint(implicitQ)) ≈ *(adjoint(C), adjoint(explicitQ)) end # where the LQ-factored matrix has at least as many rows m as columns n, # Q's full/square and reduced/rectangular forms have the same shape (n-by-n). hence we expect @@ -219,7 +217,7 @@ end zeroextCright = hcat(C, zeros(eltype(C), mA)) zeroextCdown = vcat(C, zeros(eltype(C), (1, mA))) @test *(C, implicitQ) ≈ *(zeroextCright, explicitQ) - @test *(Adjoint(C), implicitQ) ≈ *(Adjoint(zeroextCdown), explicitQ) - @test_throws DimensionMismatch C * Adjoint(implicitQ) - @test_throws DimensionMismatch Adjoint(C) * Adjoint(implicitQ) + @test *(adjoint(C), implicitQ) ≈ *(adjoint(zeroextCdown), explicitQ) + @test_throws DimensionMismatch C * adjoint(implicitQ) + @test_throws DimensionMismatch adjoint(C) * adjoint(implicitQ) end diff --git a/test/linalg/lu.jl b/test/linalg/lu.jl index 353e9b07dd5fd..e25fa73d4be64 100644 --- a/test/linalg/lu.jl +++ b/test/linalg/lu.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Test -using Base.LinAlg: ldiv!, Adjoint, Transpose +using Base.LinAlg: ldiv! import Base.LinAlg.BlasInt, Base.LinAlg.BlasFloat n = 10 @@ -106,12 +106,12 @@ dimg = randn(n)/2 for (bb, cc) in ((Bs, Cs), (view(Bs, 1:n, 1), view(Cs, 1:n))) @test norm(a*(lua\bb) - bb, 1) < ε*κ*n*2 # Two because the right hand side has two columns @test norm(a'*(lua'\bb) - bb, 1) < ε*κ*n*2 # Two because the right hand side has two columns - @test norm(a'*(lua'\a') - adjoint(a), 1) < ε*κ*n^2 + @test norm(a'*(lua'\a') - a', 1) < ε*κ*n^2 @test norm(a*(lua\cc) - cc, 1) < ε*κ*n # cc is a vector @test norm(a'*(lua'\cc) - cc, 1) < ε*κ*n # cc is a vector @test AbstractArray(lua) ≈ a - @test norm(Transpose(a)*(Transpose(lua)\bb) - bb,1) < ε*κ*n*2 # Two because the right hand side has two columns - @test norm(Transpose(a)*(Transpose(lua)\cc) - cc,1) < ε*κ*n + @test norm(transpose(a)*(transpose(lua)\bb) - bb,1) < ε*κ*n*2 # Two because the right hand side has two columns + @test norm(transpose(a)*(transpose(lua)\cc) - cc,1) < ε*κ*n end # Test whether Ax_ldiv_B!(y, LU, x) indeed overwrites y @@ -125,13 +125,13 @@ dimg = randn(n)/2 @test norm(b_dest - lua \ b, 1) < ε*κ*2n @test norm(c_dest - lua \ c, 1) < ε*κ*n - ldiv!(b_dest, Transpose(lua), b) - ldiv!(c_dest, Transpose(lua), c) - @test norm(b_dest - Transpose(lua) \ b, 1) < ε*κ*2n - @test norm(c_dest - Transpose(lua) \ c, 1) < ε*κ*n + ldiv!(b_dest, transpose(lua), b) + ldiv!(c_dest, transpose(lua), c) + @test norm(b_dest - transpose(lua) \ b, 1) < ε*κ*2n + @test norm(c_dest - transpose(lua) \ c, 1) < ε*κ*n - ldiv!(b_dest, Adjoint(lua), b) - ldiv!(c_dest, Adjoint(lua), c) + ldiv!(b_dest, adjoint(lua), b) + ldiv!(c_dest, adjoint(lua), c) @test norm(b_dest - lua' \ b, 1) < ε*κ*2n @test norm(c_dest - lua' \ c, 1) < ε*κ*n end @@ -144,16 +144,16 @@ dimg = randn(n)/2 lud = factorize(d) f = zeros(eltyb, n+1) @test_throws DimensionMismatch lud\f - @test_throws DimensionMismatch Transpose(lud)\f + @test_throws DimensionMismatch transpose(lud)\f @test_throws DimensionMismatch lud'\f - @test_throws DimensionMismatch Base.LinAlg.ldiv!(Transpose(lud), f) + @test_throws DimensionMismatch Base.LinAlg.ldiv!(transpose(lud), f) let Bs = copy(b) for bb in (Bs, view(Bs, 1:n, 1)) @test norm(d*(lud\bb) - bb, 1) < ε*κd*n*2 # Two because the right hand side has two columns if eltya <: Real - @test norm((Transpose(lud)\bb) - Array(transpose(d))\bb, 1) < ε*κd*n*2 # Two because the right hand side has two columns + @test norm((transpose(lud)\bb) - Array(transpose(d))\bb, 1) < ε*κd*n*2 # Two because the right hand side has two columns if eltya != Int && eltyb != Int - @test norm(Base.LinAlg.ldiv!(Transpose(lud), copy(bb)) - Array(transpose(d))\bb, 1) < ε*κd*n*2 + @test norm(Base.LinAlg.ldiv!(transpose(lud), copy(bb)) - Array(transpose(d))\bb, 1) < ε*κd*n*2 end end if eltya <: Complex @@ -164,7 +164,7 @@ dimg = randn(n)/2 if eltya <: BlasFloat && eltyb <: BlasFloat e = rand(eltyb,n,n) @test norm(e/lud - e/d,1) < ε*κ*n^2 - @test norm((Transpose(lud)\e') - Array(transpose(d))\e',1) < ε*κd*n^2 + @test norm((transpose(lud)\e') - Array(transpose(d))\e',1) < ε*κd*n^2 #test singular du = rand(eltya,n-1) dl = rand(eltya,n-1) diff --git a/test/linalg/matmul.jl b/test/linalg/matmul.jl index d47543da2072e..b51b436872270 100644 --- a/test/linalg/matmul.jl +++ b/test/linalg/matmul.jl @@ -1,8 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random -using Base.LinAlg: mul!, Adjoint, Transpose +using Base.LinAlg: mul! ## Test Julia fallbacks to BLAS routines @@ -29,15 +29,15 @@ end BBi = BB+(2.5*im).*AA[[2,1],[2,1]] for A in (copy(AA), view(AA, 1:2, 1:2)), B in (copy(BB), view(BB, 1:2, 1:2)) @test A*B == [19 22; 43 50] - @test *(Transpose(A), B) == [26 30; 38 44] - @test *(A, Transpose(B)) == [17 23; 39 53] - @test *(Transpose(A), Transpose(B)) == [23 31; 34 46] + @test *(transpose(A), B) == [26 30; 38 44] + @test *(A, transpose(B)) == [17 23; 39 53] + @test *(transpose(A), transpose(B)) == [23 31; 34 46] end for Ai in (copy(AAi), view(AAi, 1:2, 1:2)), Bi in (copy(BBi), view(BBi, 1:2, 1:2)) @test Ai*Bi == [-21+53.5im -4.25+51.5im; -12+95.5im 13.75+85.5im] - @test *(Adjoint(Ai), Bi) == [68.5-12im 57.5-28im; 88-3im 76.5-25im] - @test *(Ai, Adjoint(Bi)) == [64.5+5.5im 43+31.5im; 104-18.5im 80.5+31.5im] - @test *(Adjoint(Ai), Adjoint(Bi)) == [-28.25-66im 9.75-58im; -26-89im 21-73im] + @test *(adjoint(Ai), Bi) == [68.5-12im 57.5-28im; 88-3im 76.5-25im] + @test *(Ai, adjoint(Bi)) == [64.5+5.5im 43+31.5im; 104-18.5im 80.5+31.5im] + @test *(adjoint(Ai), adjoint(Bi)) == [-28.25-66im 9.75-58im; -26-89im 21-73im] @test_throws DimensionMismatch [1 2; 0 0; 0 0] * [1 2] end @test_throws DimensionMismatch mul!(Matrix{Float64}(uninitialized,3,3), AA, BB) @@ -49,15 +49,15 @@ end BBi = BB+(2.5*im).*AA[[2,1,3],[2,3,1]] for A in (copy(AA), view(AA, 1:3, 1:3)), B in (copy(BB), view(BB, 1:3, 1:3)) @test A*B == [-26 38 -27; 1 -4 -6; 28 -46 15] - @test *(Adjoint(A), B) == [-6 2 -25; 3 -12 -18; 12 -26 -11] - @test *(A, Adjoint(B)) == [-14 0 6; 4 -3 -3; 22 -6 -12] - @test *(Adjoint(A), Adjoint(B)) == [6 -8 -6; 12 -9 -9; 18 -10 -12] + @test *(adjoint(A), B) == [-6 2 -25; 3 -12 -18; 12 -26 -11] + @test *(A, adjoint(B)) == [-14 0 6; 4 -3 -3; 22 -6 -12] + @test *(adjoint(A), adjoint(B)) == [6 -8 -6; 12 -9 -9; 18 -10 -12] end for Ai in (copy(AAi), view(AAi, 1:3, 1:3)), Bi in (copy(BBi), view(BBi, 1:3, 1:3)) @test Ai*Bi == [-44.75+13im 11.75-25im -38.25+30im; -47.75-16.5im -51.5+51.5im -56+6im; 16.75-4.5im -53.5+52im -15.5im] - @test *(Adjoint(Ai), Bi) == [-21+2im -1.75+49im -51.25+19.5im; 25.5+56.5im -7-35.5im 22+35.5im; -3+12im -32.25+43im -34.75-2.5im] - @test *(Ai, Adjoint(Bi)) == [-20.25+15.5im -28.75-54.5im 22.25+68.5im; -12.25+13im -15.5+75im -23+27im; 18.25+im 1.5+94.5im -27-54.5im] - @test *(Adjoint(Ai), Adjoint(Bi)) == [1+2im 20.75+9im -44.75+42im; 19.5+17.5im -54-36.5im 51-14.5im; 13+7.5im 11.25+31.5im -43.25-14.5im] + @test *(adjoint(Ai), Bi) == [-21+2im -1.75+49im -51.25+19.5im; 25.5+56.5im -7-35.5im 22+35.5im; -3+12im -32.25+43im -34.75-2.5im] + @test *(Ai, adjoint(Bi)) == [-20.25+15.5im -28.75-54.5im 22.25+68.5im; -12.25+13im -15.5+75im -23+27im; 18.25+im 1.5+94.5im -27-54.5im] + @test *(adjoint(Ai), adjoint(Bi)) == [1+2im 20.75+9im -44.75+42im; 19.5+17.5im -54-36.5im 51-14.5im; 13+7.5im 11.25+31.5im -43.25-14.5im] @test_throws DimensionMismatch [1 2 3; 0 0 0; 0 0 0] * [1 2 3] end @test_throws DimensionMismatch mul!(Matrix{Float64}(uninitialized,4,4), AA, BB) @@ -65,7 +65,8 @@ end # Generic AbstractArrays module MyArray15367 - using Test + using Test, Random + struct MyArray{T,N} <: AbstractArray{T,N} data::Array{T,N} end @@ -83,7 +84,7 @@ end BB = [2 -2; 3 -5; -4 7] for A in (copy(AA), view(AA, 1:2, 1:3)), B in (copy(BB), view(BB, 1:3, 1:2)) @test A*B == [-7 9; -4 9] - @test *(Transpose(A), Transpose(B)) == [-6 -11 15; -6 -13 18; -6 -15 21] + @test *(transpose(A), transpose(B)) == [-6 -11 15; -6 -13 18; -6 -15 21] end AA = fill(1, 2, 100) BB = fill(1, 100, 3) @@ -94,23 +95,23 @@ end BB = rand(1:20, 5, 5) .- 10 CC = Matrix{Int}(uninitialized, size(AA, 1), size(BB, 2)) for A in (copy(AA), view(AA, 1:5, 1:5)), B in (copy(BB), view(BB, 1:5, 1:5)), C in (copy(CC), view(CC, 1:5, 1:5)) - @test *(Transpose(A), B) == A'*B - @test *(A, Transpose(B)) == A*B' + @test *(transpose(A), B) == A'*B + @test *(A, transpose(B)) == A*B' # Preallocated @test mul!(C, A, B) == A*B - @test mul!(C, Transpose(A), B) == A'*B - @test mul!(C, A, Transpose(B)) == A*B' - @test mul!(C, Transpose(A), Transpose(B)) == A'*B' - @test Base.LinAlg.mul!(C, Adjoint(A), Transpose(B)) == A'*Transpose(B) + @test mul!(C, transpose(A), B) == A'*B + @test mul!(C, A, transpose(B)) == A*B' + @test mul!(C, transpose(A), transpose(B)) == A'*B' + @test Base.LinAlg.mul!(C, adjoint(A), transpose(B)) == A'*transpose(B) #test DimensionMismatch for generic_matmatmul - @test_throws DimensionMismatch Base.LinAlg.mul!(C, Adjoint(A), Transpose(fill(1,4,4))) - @test_throws DimensionMismatch Base.LinAlg.mul!(C, Adjoint(fill(1,4,4)), Transpose(B)) + @test_throws DimensionMismatch Base.LinAlg.mul!(C, adjoint(A), transpose(fill(1,4,4))) + @test_throws DimensionMismatch Base.LinAlg.mul!(C, adjoint(fill(1,4,4)), transpose(B)) end vv = [1,2] CC = Matrix{Int}(uninitialized, 2, 2) for v in (copy(vv), view(vv, 1:2)), C in (copy(CC), view(CC, 1:2, 1:2)) - @test @inferred(mul!(C, v, Adjoint(v))) == [1 2; 2 4] + @test @inferred(mul!(C, v, adjoint(v))) == [1 2; 2 4] end end @@ -124,12 +125,12 @@ end vv = [1,2,3] CC = Matrix{Int}(uninitialized, 3, 3) for v in (copy(vv), view(vv, 1:3)), C in (copy(CC), view(CC, 1:3, 1:3)) - @test mul!(C, v, Transpose(v)) == v*v' + @test mul!(C, v, transpose(v)) == v*v' end vvf = map(Float64,vv) CC = Matrix{Float64}(uninitialized, 3, 3) for vf in (copy(vvf), view(vvf, 1:3)), C in (copy(CC), view(CC, 1:3, 1:3)) - @test mul!(C, vf, Transpose(vf)) == vf*vf' + @test mul!(C, vf, transpose(vf)) == vf*vf' end end @@ -138,9 +139,9 @@ end BB = rand(Float64,6,6) CC = zeros(Float64,6,6) for A in (copy(AA), view(AA, 1:6, 1:6)), B in (copy(BB), view(BB, 1:6, 1:6)), C in (copy(CC), view(CC, 1:6, 1:6)) - @test Base.LinAlg.mul!(C, Transpose(A), Transpose(B)) == Transpose(A)*Transpose(B) - @test Base.LinAlg.mul!(C, A, Adjoint(B)) == A*Transpose(B) - @test Base.LinAlg.mul!(C, Adjoint(A), B) == Transpose(A)*B + @test Base.LinAlg.mul!(C, transpose(A), transpose(B)) == transpose(A)*transpose(B) + @test Base.LinAlg.mul!(C, A, adjoint(B)) == A*transpose(B) + @test Base.LinAlg.mul!(C, adjoint(A), B) == transpose(A)*B end end @@ -150,13 +151,13 @@ end Asub = view(A, 1:2:5, 1:2:4) b = [1.2,-2.5] @test (Aref*b) == (Asub*b) - @test *(Transpose(Asub), Asub) == *(Transpose(Aref), Aref) - @test *(Asub, Transpose(Asub)) == *(Aref, Transpose(Aref)) + @test *(transpose(Asub), Asub) == *(transpose(Aref), Aref) + @test *(Asub, transpose(Asub)) == *(Aref, transpose(Aref)) Ai = A .+ im Aref = Ai[1:2:end,1:2:end] Asub = view(Ai, 1:2:5, 1:2:4) - @test *(Adjoint(Asub), Asub) == *(Adjoint(Aref), Aref) - @test *(Asub, Adjoint(Asub)) == *(Aref, Adjoint(Aref)) + @test *(adjoint(Asub), Asub) == *(adjoint(Aref), Aref) + @test *(Asub, adjoint(Asub)) == *(Aref, adjoint(Aref)) end @testset "issue #15286" begin @@ -164,33 +165,33 @@ end C = zeros(8, 8) sC = view(C, 1:2:8, 1:2:8) B = reshape(map(Float64,-9:10),5,4) - @test mul!(sC, Transpose(A), A) == A'*A - @test mul!(sC, Transpose(A), B) == A'*B + @test mul!(sC, transpose(A), A) == A'*A + @test mul!(sC, transpose(A), B) == A'*B Aim = A .- im C = zeros(ComplexF64,8,8) sC = view(C, 1:2:8, 1:2:8) B = reshape(map(Float64,-9:10),5,4) .+ im - @test mul!(sC, Adjoint(Aim), Aim) == Aim'*Aim - @test mul!(sC, Adjoint(Aim), B) == Aim'*B + @test mul!(sC, adjoint(Aim), Aim) == Aim'*Aim + @test mul!(sC, adjoint(Aim), B) == Aim'*B end @testset "syrk & herk" begin AA = reshape(1:1503, 501, 3).-750.0 res = Float64[135228751 9979252 -115270247; 9979252 10481254 10983256; -115270247 10983256 137236759] for A in (copy(AA), view(AA, 1:501, 1:3)) - @test *(Transpose(A), A) == res - @test *(Adjoint(A), Transpose(adjoint(A))) == res + @test *(transpose(A), A) == res + @test *(adjoint(A), transpose(copy(A'))) == res end cutoff = 501 A = reshape(1:6*cutoff,2*cutoff,3).-(6*cutoff)/2 Asub = view(A, 1:2:2*cutoff, 1:3) Aref = A[1:2:2*cutoff, 1:3] - @test *(Transpose(Asub), Asub) == *(Transpose(Aref), Aref) + @test *(transpose(Asub), Asub) == *(transpose(Aref), Aref) Ai = A .- im Asub = view(Ai, 1:2:2*cutoff, 1:3) Aref = Ai[1:2:2*cutoff, 1:3] - @test *(Adjoint(Asub), Asub) == *(Adjoint(Aref), Aref) + @test *(adjoint(Asub), Asub) == *(adjoint(Aref), Aref) A5x5, A6x5 = Matrix{Float64}.(uninitialized, ((5, 5), (6, 5))) @test_throws DimensionMismatch Base.LinAlg.syrk_wrapper!(A5x5,'N',A6x5) @@ -222,7 +223,7 @@ end @test_throws BoundsError dot(x, 1:4, y, 1:4) @test_throws BoundsError dot(x, 1:3, y, 2:4) @test dot(x, 1:2,y, 1:2) == convert(elty, 12.5) - @test Transpose(x)*y == convert(elty, 29.0) + @test transpose(x)*y == convert(elty, 29.0) @test_throws MethodError dot(rand(elty, 2, 2), randn(elty, 2, 2)) X = convert(Vector{Matrix{elty}},[reshape(1:4, 2, 2), fill(1, 2, 2)]) res = convert(Matrix{elty}, [7.0 13.0; 13.0 27.0]) @@ -297,18 +298,21 @@ end import Base: *, adjoint, transpose, Adjoint, Transpose (*)(x::RootInt, y::RootInt) = x.i*y.i adjoint(x::RootInt) = x -Adjoint(x::RootInt) = x transpose(x::RootInt) = x +Adjoint(x::RootInt) = x Transpose(x::RootInt) = x +# TODO once Adjoint/Transpose constructors call adjoint/transpose recursively +# rather than Adjoint/Transpose, the additional definitions should become unnecessary + @test Base.promote_op(*, RootInt, RootInt) === Int @testset "#14293" begin a = [RootInt(3)] C = [0] - mul!(C, a, Transpose(a)) + mul!(C, a, transpose(a)) @test C[1] == 9 a = [RootInt(2),RootInt(10)] - @test a*a' == [4 20; 20 100] + @test a*adjoint(a) == [4 20; 20 100] A = [RootInt(3) RootInt(5)] @test A*a == [56] end diff --git a/test/linalg/pinv.jl b/test/linalg/pinv.jl index de2d2ef11c6c8..398e0318171e1 100644 --- a/test/linalg/pinv.jl +++ b/test/linalg/pinv.jl @@ -4,7 +4,7 @@ # Test the pseudo-inverse # -using Test +using Test, Random srand(12345) diff --git a/test/linalg/qr.jl b/test/linalg/qr.jl index 5757c6f44b4eb..1b643e9f1ccff 100644 --- a/test/linalg/qr.jl +++ b/test/linalg/qr.jl @@ -1,8 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random -using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted, mul!, Adjoint, Transpose +using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted, mul1!, mul2! n = 10 @@ -20,13 +20,13 @@ breal = randn(n,2)/2 bimg = randn(n,2)/2 # helper functions to unambiguously recover explicit forms of an implicit QR Q -squareQ(Q::LinAlg.AbstractQ) = (sq = size(Q.factors, 1); mul!(Q, Matrix{eltype(Q)}(I, sq, sq))) +squareQ(Q::LinAlg.AbstractQ) = (sq = size(Q.factors, 1); mul2!(Q, Matrix{eltype(Q)}(I, sq, sq))) rectangularQ(Q::LinAlg.AbstractQ) = convert(Array, Q) @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64, BigFloat, Int) raw_a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) raw_a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real) - asym = adjoint(raw_a) + raw_a # symmetric indefinite + asym = raw_a' + raw_a # symmetric indefinite apd = raw_a' * raw_a # symmetric positive-definite ε = εa = eps(abs(float(one(eltya)))) @@ -53,14 +53,14 @@ rectangularQ(Q::LinAlg.AbstractQ) = convert(Array, Q) @test_throws ErrorException qra.Z @test q'*squareQ(q) ≈ Matrix(I, a_1, a_1) @test q*squareQ(q)' ≈ Matrix(I, a_1, a_1) - @test q'*Matrix(1.0I, a_1, a_1)' ≈ adjoint(squareQ(q)) + @test q'*Matrix(1.0I, a_1, a_1)' ≈ squareQ(q)' @test squareQ(q)'q ≈ Matrix(I, a_1, a_1) - @test Matrix(1.0I, a_1, a_1)'q' ≈ adjoint(squareQ(q)) + @test Matrix(1.0I, a_1, a_1)'q' ≈ squareQ(q)' @test q*r ≈ a @test a*(qra\b) ≈ b atol=3000ε @test Array(qra) ≈ a sq = size(q.factors, 2) - @test *(Matrix{eltyb}(I, sq, sq), Adjoint(q)) * squareQ(q) ≈ Matrix(I, sq, sq) atol=5000ε + @test *(Matrix{eltyb}(I, sq, sq), adjoint(q)) * squareQ(q) ≈ Matrix(I, sq, sq) atol=5000ε if eltya != Int @test Matrix{eltyb}(I, a_1, a_1)*q ≈ convert(AbstractMatrix{tab}, q) ac = copy(a) @@ -83,7 +83,7 @@ rectangularQ(Q::LinAlg.AbstractQ) = convert(Array, Q) @test_throws DimensionMismatch q*b[1:n1 + 1] @test_throws DimensionMismatch b[1:n1 + 1]*q' sq = size(q.factors, 2) - @test *(UpperTriangular(Matrix{eltyb}(I, sq, sq)), Adjoint(q))*squareQ(q) ≈ Matrix(I, n1, a_1) atol=5000ε + @test *(UpperTriangular(Matrix{eltyb}(I, sq, sq)), adjoint(q))*squareQ(q) ≈ Matrix(I, n1, a_1) atol=5000ε if eltya != Int @test Matrix{eltyb}(I, a_1, a_1)*q ≈ convert(AbstractMatrix{tab},q) end @@ -102,7 +102,7 @@ rectangularQ(Q::LinAlg.AbstractQ) = convert(Array, Q) @test (UpperTriangular(Matrix{eltya}(I, sq, sq))*q')*squareQ(q) ≈ Matrix(I, n1, n1) @test q*r ≈ (isa(qrpa,QRPivoted) ? a[1:n1,p] : a[1:n1,:]) @test q*r[:,invperm(p)] ≈ a[1:n1,:] - @test q*r*Transpose(qrpa.P) ≈ a[1:n1,:] + @test q*r*transpose(qrpa.P) ≈ a[1:n1,:] @test a[1:n1,:]*(qrpa\b[1:n1]) ≈ b[1:n1] atol=5000ε @test Array(qrpa) ≈ a[1:5,:] @test_throws DimensionMismatch q*b[1:n1+1] @@ -124,7 +124,7 @@ rectangularQ(Q::LinAlg.AbstractQ) = convert(Array, Q) @test_throws DimensionMismatch q*b[1:n1+1] @test_throws DimensionMismatch b[1:n1+1]*q' sq = size(q.factors, 2) - @test *(UpperTriangular(Matrix{eltyb}(I, sq, sq)), Adjoint(q))*squareQ(q) ≈ Matrix(I, n1, a_1) atol=5000ε + @test *(UpperTriangular(Matrix{eltyb}(I, sq, sq)), adjoint(q))*squareQ(q) ≈ Matrix(I, n1, a_1) atol=5000ε if eltya != Int @test Matrix{eltyb}(I, a_1, a_1)*q ≈ convert(AbstractMatrix{tab},q) end @@ -135,20 +135,20 @@ rectangularQ(Q::LinAlg.AbstractQ) = convert(Array, Q) a = raw_a qrpa = factorize(a[:,1:n1]) q, r = qrpa.Q, qrpa.R - @test mul!(adjoint(squareQ(q)), q) ≈ Matrix(I, n, n) - @test_throws DimensionMismatch mul!(Matrix{eltya}(I, n+1, n+1),q) - @test mul!(squareQ(q), Adjoint(q)) ≈ Matrix(I, n, n) - @test_throws DimensionMismatch mul!(Matrix{eltya}(I, n+1, n+1), Adjoint(q)) + @test mul1!(copy(squareQ(q)'), q) ≈ Matrix(I, n, n) + @test_throws DimensionMismatch mu1l!(Matrix{eltya}(I, n+1, n+1),q) + @test mul1!(squareQ(q), adjoint(q)) ≈ Matrix(I, n, n) + @test_throws DimensionMismatch mul1!(Matrix{eltya}(I, n+1, n+1), adjoint(q)) @test_throws BoundsError size(q,-1) - @test_throws DimensionMismatch Base.LinAlg.mul!(q,zeros(eltya,n1+1)) - @test_throws DimensionMismatch Base.LinAlg.mul!(Adjoint(q), zeros(eltya,n1+1)) + @test_throws DimensionMismatch Base.LinAlg.mul2!(q,zeros(eltya,n1+1)) + @test_throws DimensionMismatch Base.LinAlg.mul2!(adjoint(q), zeros(eltya,n1+1)) qra = qrfact(a[:,1:n1], Val(false)) q, r = qra.Q, qra.R - @test mul!(adjoint(squareQ(q)), q) ≈ Matrix(I, n, n) - @test_throws DimensionMismatch mul!(Matrix{eltya}(I, n+1, n+1),q) - @test mul!(squareQ(q), Adjoint(q)) ≈ Matrix(I, n, n) - @test_throws DimensionMismatch mul!(Matrix{eltya}(I, n+1, n+1),Adjoint(q)) + @test mul1!(copy(squareQ(q)'), q) ≈ Matrix(I, n, n) + @test_throws DimensionMismatch mul1!(Matrix{eltya}(I, n+1, n+1),q) + @test mul1!(squareQ(q), adjoint(q)) ≈ Matrix(I, n, n) + @test_throws DimensionMismatch mul1!(Matrix{eltya}(I, n+1, n+1),adjoint(q)) @test_throws BoundsError size(q,-1) @test_throws DimensionMismatch q * Matrix{Int8}(I, n+4, n+4) end @@ -188,7 +188,7 @@ end @test Base.LinAlg.qr!(Int[1]) == (Int[1],1) B = rand(7,2) - @test (1:7)\B ≈ collect(1:7)\B + @test (1:7)\B ≈ Vector(1:7)\B end @testset "Issue 16520" begin @@ -204,7 +204,7 @@ end @testset "Issue 24107" begin A = rand(200,2) - @test A \ linspace(0,1,200) == A \ collect(linspace(0,1,200)) + @test A \ linspace(0,1,200) == A \ Vector(linspace(0,1,200)) end @testset "Issue #24589. Promotion of rational matrices" begin diff --git a/test/linalg/schur.jl b/test/linalg/schur.jl index 10a7584b843cf..ea28b2f8fa74c 100644 --- a/test/linalg/schur.jl +++ b/test/linalg/schur.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted @@ -17,8 +17,8 @@ aimg = randn(n,n)/2 @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64, Int) a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) - asym = adjoint(a)+a # symmetric indefinite - apd = a'*a # symmetric positive-definite + asym = a' + a # symmetric indefinite + apd = a' * a # symmetric positive-definite for (a, asym, apd) in ((a, asym, apd), (view(a, 1:n, 1:n), view(asym, 1:n, 1:n), diff --git a/test/linalg/special.jl b/test/linalg/special.jl index 751b63c6e1de1..05092cb864c77 100644 --- a/test/linalg/special.jl +++ b/test/linalg/special.jl @@ -1,8 +1,9 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random +using SparseArrays -using Base.LinAlg: mul!, Adjoint, Transpose +using Base.LinAlg: mul1! n= 10 #Size of matrix to test srand(1) @@ -99,7 +100,7 @@ end end C = rand(n,n) - for TriType in [Base.LinAlg.UnitLowerTriangular, Base.LinAlg.UnitUpperTriangular, UpperTriangular, LowerTriangular] + for TriType in [LinAlg.UnitLowerTriangular, LinAlg.UnitUpperTriangular, UpperTriangular, LowerTriangular] D = TriType(C) for Spectype in [Diagonal, Bidiagonal, Tridiagonal, Matrix] @test Matrix(D + convert(Spectype,A)) ≈ Matrix(D + A) @@ -111,16 +112,16 @@ end end @testset "Triangular Types and QR" begin - for typ in [UpperTriangular,LowerTriangular,Base.LinAlg.UnitUpperTriangular,Base.LinAlg.UnitLowerTriangular] + for typ in [UpperTriangular,LowerTriangular,LinAlg.UnitUpperTriangular,LinAlg.UnitLowerTriangular] a = rand(n,n) atri = typ(a) b = rand(n,n) qrb = qrfact(b,Val(true)) - @test *(atri, Adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' - @test mul!(copy(atri), Adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' + @test *(atri, adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' + @test mul1!(copy(atri), adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' qrb = qrfact(b,Val(false)) - @test *(atri, Adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' - @test mul!(copy(atri), Adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' + @test *(atri, adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' + @test mul1!(copy(atri), adjoint(qrb.Q)) ≈ Matrix(atri) * qrb.Q' end end @@ -173,8 +174,8 @@ end N = 4 # The tested annotation types testfull = Bool(parse(Int,(get(ENV, "JULIA_TESTFULL", "0")))) - utriannotations = (UpperTriangular, Base.LinAlg.UnitUpperTriangular) - ltriannotations = (LowerTriangular, Base.LinAlg.UnitLowerTriangular) + utriannotations = (UpperTriangular, LinAlg.UnitUpperTriangular) + ltriannotations = (LowerTriangular, LinAlg.UnitLowerTriangular) triannotations = (utriannotations..., ltriannotations...) symannotations = (Symmetric, Hermitian) annotations = testfull ? (triannotations..., symannotations...) : (LowerTriangular, Symmetric) diff --git a/test/linalg/svd.jl b/test/linalg/svd.jl index ff56a00f939c3..be88caf62203c 100644 --- a/test/linalg/svd.jl +++ b/test/linalg/svd.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted @@ -46,8 +46,8 @@ a2img = randn(n,n)/2 @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64, Int) aa = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) aa2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real) - asym = adjoint(aa)+aa # symmetric indefinite - apd = aa'*aa # symmetric positive-definite + asym = aa' + aa # symmetric indefinite + apd = aa' * aa # symmetric positive-definite for (a, a2) in ((aa, aa2), (view(aa, 1:n, 1:n), view(aa2, 1:n, 1:n))) ε = εa = eps(abs(float(one(eltya)))) diff --git a/test/linalg/symmetric.jl b/test/linalg/symmetric.jl index d05e292591ca5..0943d92a0822f 100644 --- a/test/linalg/symmetric.jl +++ b/test/linalg/symmetric.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random +using SparseArrays srand(101) @@ -11,15 +12,15 @@ end @testset "Hermitian matrix exponential/log" begin A1 = randn(4,4) + im*randn(4,4) - A2 = A1 + adjoint(A1) + A2 = A1 + A1' @test exp(A2) ≈ exp(Hermitian(A2)) @test log(A2) ≈ log(Hermitian(A2)) - A3 = A1 * adjoint(A1) # posdef + A3 = A1 * A1' # posdef @test exp(A3) ≈ exp(Hermitian(A3)) @test log(A3) ≈ log(Hermitian(A3)) A1 = randn(4,4) - A3 = A1 * adjoint(A1) + A3 = A1 * A1' A4 = A1 + transpose(A1) @test exp(A4) ≈ exp(Symmetric(A4)) @test log(A3) ≈ log(Symmetric(A3)) @@ -32,9 +33,9 @@ end aimg = randn(n,n)/2 @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64, BigFloat, Int) a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) - asym = transpose(a)+a # symmetric indefinite - aherm = adjoint(a)+a # Hermitian indefinite - apos = a'*a # Hermitian positive definite + asym = transpose(a) + a # symmetric indefinite + aherm = a' + a # Hermitian indefinite + apos = a' * a # Hermitian positive definite aposs = apos + transpose(apos) # Symmetric positive definite ε = εa = eps(abs(float(one(eltya)))) @@ -121,7 +122,7 @@ end elseif eltya <: Complex # test that zero imaginary component is # handled properly - @test ishermitian(Symmetric(b + adjoint(b))) + @test ishermitian(Symmetric(b + b')) end end @@ -148,7 +149,7 @@ end @test transpose(H) === H == aherm else @test adjoint(S) == Symmetric(conj(asym)) - @test transpose(H) == Hermitian(transpose(aherm)) + @test transpose(H) == Hermitian(copy(transpose(aherm))) end end end @@ -218,7 +219,7 @@ end if eltya <: Real # the eigenvalues are only real and ordered for Hermitian matrices d, v = eig(asym) @test asym*v[:,1] ≈ d[1]*v[:,1] - @test v*Diagonal(d)*Transpose(v) ≈ asym + @test v*Diagonal(d)*transpose(v) ≈ asym @test isequal(eigvals(asym[1]), eigvals(asym[1:1,1:1])) @test abs.(eigfact(Symmetric(asym), 1:2).vectors'v[:,1:2]) ≈ Matrix(I, 2, 2) eig(Symmetric(asym), 1:2) # same result, but checks that method works @@ -255,7 +256,7 @@ end let A = a[:,1:5]*a[:,1:5]' # Make sure A is Hermitian even in the presence of rounding error # xianyi/OpenBLAS#729 - A = (adjoint(A) + A) / 2 + A = (A + A') / 2 @test rank(A) == rank(Hermitian(A)) end end @@ -289,13 +290,13 @@ end @testset "linalg binary ops" begin @testset "mat * vec" begin @test Symmetric(asym)*x+y ≈ asym*x+y - # testing fallbacks for Transpose-vector * Transpose(SymHerm) - xadj = Transpose(x) - @test xadj * Transpose(Symmetric(asym)) ≈ xadj * asym + # testing fallbacks for transpose-vector * transpose(SymHerm) + xadj = transpose(x) + @test xadj * transpose(Symmetric(asym)) ≈ xadj * asym @test x' * Symmetric(asym) ≈ x' * asym @test Hermitian(aherm)*x+y ≈ aherm*x+y - # testing fallbacks for Adjoint-vector * SymHerm' + # testing fallbacks for adjoint-vector * SymHerm' xadj = x' @test x' * Hermitian(aherm) ≈ x' * aherm @test xadj * Hermitian(aherm)' ≈ xadj * aherm @@ -318,13 +319,13 @@ end @test C ≈ a*asym tri_b = UpperTriangular(triu(b)) - @test Array(Transpose(Hermitian(aherm)) * tri_b) ≈ Transpose(aherm) * Array(tri_b) - @test Array(tri_b * Transpose(Hermitian(aherm))) ≈ Array(tri_b) * Transpose(aherm) + @test Array(transpose(Hermitian(aherm)) * tri_b) ≈ transpose(aherm) * Array(tri_b) + @test Array(tri_b * transpose(Hermitian(aherm))) ≈ Array(tri_b) * transpose(aherm) @test Array(Hermitian(aherm)' * tri_b) ≈ aherm' * Array(tri_b) @test Array(tri_b * Hermitian(aherm)') ≈ Array(tri_b) * aherm' - @test Array(Transpose(Symmetric(asym)) * tri_b) ≈ Transpose(asym) * Array(tri_b) - @test Array(tri_b * Transpose(Symmetric(asym))) ≈ Array(tri_b) * Transpose(asym) + @test Array(transpose(Symmetric(asym)) * tri_b) ≈ transpose(asym) * Array(tri_b) + @test Array(tri_b * transpose(Symmetric(asym))) ≈ Array(tri_b) * transpose(asym) @test Array(Symmetric(asym)' * tri_b) ≈ asym' * Array(tri_b) @test Array(tri_b * Symmetric(asym)') ≈ Array(tri_b) * asym' end @@ -383,7 +384,7 @@ end @test conj(c) == conj(Array(c)) cc = copy(c) @test conj!(c) == conj(Array(cc)) - c = Hermitian(b + adjoint(b)) + c = Hermitian(b + b') @test conj(c) == conj(Array(c)) cc = copy(c) @test conj!(c) == conj(Array(cc)) diff --git a/test/linalg/triangular.jl b/test/linalg/triangular.jl index 8a6dfcba2f0a7..8c53fcf9bb60a 100644 --- a/test/linalg/triangular.jl +++ b/test/linalg/triangular.jl @@ -1,10 +1,11 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license debug = false -using Test +using Test, Random using Base.LinAlg: BlasFloat, errorbounds, full!, naivesub!, transpose!, UnitUpperTriangular, UnitLowerTriangular, - mul!, rdiv!, Adjoint, Transpose + mul!, mul1!, mul2!, rdiv! +using SparseArrays debug && println("Triangular matrices") @@ -24,7 +25,7 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo (UnitLowerTriangular, :L)) # Construct test matrix - A1 = t1(elty1 == Int ? rand(1:7, n, n) : convert(Matrix{elty1}, (elty1 <: Complex ? complex.(randn(n, n), randn(n, n)) : randn(n, n)) |> t -> chol(t't) |> t -> uplo1 == :U ? t : adjoint(t))) + A1 = t1(elty1 == Int ? rand(1:7, n, n) : convert(Matrix{elty1}, (elty1 <: Complex ? complex.(randn(n, n), randn(n, n)) : randn(n, n)) |> t -> chol(t't) |> t -> uplo1 == :U ? t : copy(t'))) debug && println("elty1: $elty1, A1: $t1") @@ -133,11 +134,11 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo # [c]transpose[!] (test views as well, see issue #14317) let vrange = 1:n-1, viewA1 = t1(view(A1.data, vrange, vrange)) # transpose - @test transpose(A1) == transpose(Matrix(A1)) - @test transpose(viewA1) == transpose(Matrix(viewA1)) + @test copy(transpose(A1)) == transpose(Matrix(A1)) + @test copy(transpose(viewA1)) == transpose(Matrix(viewA1)) # adjoint - @test adjoint(A1) == adjoint(Matrix(A1)) - @test adjoint(viewA1) == adjoint(Matrix(viewA1)) + @test copy(A1') == Matrix(A1)' + @test copy(viewA1') == Matrix(viewA1)' # transpose! @test transpose!(copy(A1)) == transpose(A1) @test transpose!(t1(view(copy(A1).data, vrange, vrange))) == transpose(viewA1) @@ -166,14 +167,14 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo B = similar(A1) copyto!(B, A1) @test B == A1 - B = similar(transpose(A1)) - copyto!(B, transpose(A1)) - @test B == transpose(A1) + B = similar(copy(transpose(A1))) + copyto!(B, copy(transpose(A1))) + @test B == copy(transpose(A1)) B = similar(viewA1) copyto!(B, viewA1) @test B == viewA1 - B = similar(transpose(viewA1)) - copyto!(B, transpose(viewA1)) + B = similar(copy(transpose(viewA1))) + copyto!(B, copy(transpose(viewA1))) @test B == transpose(viewA1) end @@ -277,7 +278,7 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo debug && println("elty1: $elty1, A1: $t1, elty2: $elty2") - A2 = t2(elty2 == Int ? rand(1:7, n, n) : convert(Matrix{elty2}, (elty2 <: Complex ? complex.(randn(n, n), randn(n, n)) : randn(n, n)) |> t -> chol(t't) |> t -> uplo2 == :U ? t : adjoint(t))) + A2 = t2(elty2 == Int ? rand(1:7, n, n) : convert(Matrix{elty2}, (elty2 <: Complex ? complex.(randn(n, n), randn(n, n)) : randn(n, n)) |> t -> chol(t't) |> t -> uplo2 == :U ? t : copy(t'))) # Convert if elty1 <: Real && !(elty2 <: Integer) @@ -292,22 +293,22 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo # Triangular-Triangualar multiplication and division @test A1*A2 ≈ Matrix(A1)*Matrix(A2) - @test Transpose(A1)*A2 ≈ Transpose(Matrix(A1))*Matrix(A2) + @test transpose(A1)*A2 ≈ transpose(Matrix(A1))*Matrix(A2) @test A1'A2 ≈ Matrix(A1)'Matrix(A2) - @test A1*Transpose(A2) ≈ Matrix(A1)*Transpose(Matrix(A2)) + @test A1*transpose(A2) ≈ Matrix(A1)*transpose(Matrix(A2)) @test A1*A2' ≈ Matrix(A1)*Matrix(A2)' - @test Transpose(A1)*Transpose(A2) ≈ Transpose(Matrix(A1))*Transpose(Matrix(A2)) + @test transpose(A1)*transpose(A2) ≈ transpose(Matrix(A1))*transpose(Matrix(A2)) @test A1'A2' ≈ Matrix(A1)'Matrix(A2)' @test A1/A2 ≈ Matrix(A1)/Matrix(A2) @test A1\A2 ≈ Matrix(A1)\Matrix(A2) offsizeA = Matrix{Float64}(I, n+1, n+1) @test_throws DimensionMismatch offsizeA / A2 - @test_throws DimensionMismatch offsizeA / Transpose(A2) + @test_throws DimensionMismatch offsizeA / transpose(A2) @test_throws DimensionMismatch offsizeA / A2' @test_throws DimensionMismatch offsizeA * A2 - @test_throws DimensionMismatch offsizeA * Transpose(A2) + @test_throws DimensionMismatch offsizeA * transpose(A2) @test_throws DimensionMismatch offsizeA * A2' - @test_throws DimensionMismatch Transpose(A2) * offsizeA + @test_throws DimensionMismatch transpose(A2) * offsizeA @test_throws DimensionMismatch A2' * offsizeA @test_throws DimensionMismatch A2 * offsizeA end @@ -320,75 +321,75 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo if !(eltyB in (BigFloat, Complex{BigFloat})) # rand does not support BigFloat and Complex{BigFloat} as of Dec 2015 Tri = Tridiagonal(rand(eltyB,n-1),rand(eltyB,n),rand(eltyB,n-1)) - @test mul!(Tri,copy(A1)) ≈ Tri*Matrix(A1) + @test mul2!(Tri,copy(A1)) ≈ Tri*Matrix(A1) end # Triangular-dense Matrix/vector multiplication @test A1*B[:,1] ≈ Matrix(A1)*B[:,1] @test A1*B ≈ Matrix(A1)*B - @test Transpose(A1)*B[:,1] ≈ Transpose(Matrix(A1))*B[:,1] + @test transpose(A1)*B[:,1] ≈ transpose(Matrix(A1))*B[:,1] @test A1'B[:,1] ≈ Matrix(A1)'B[:,1] - @test Transpose(A1)*B ≈ Transpose(Matrix(A1))*B + @test transpose(A1)*B ≈ transpose(Matrix(A1))*B @test A1'B ≈ Matrix(A1)'B - @test A1*Transpose(B) ≈ Matrix(A1)*Transpose(B) + @test A1*transpose(B) ≈ Matrix(A1)*transpose(B) @test A1*B' ≈ Matrix(A1)*B' @test B*A1 ≈ B*Matrix(A1) - @test Transpose(B[:,1])*A1 ≈ Transpose(B[:,1])*Matrix(A1) + @test transpose(B[:,1])*A1 ≈ transpose(B[:,1])*Matrix(A1) @test B[:,1]'A1 ≈ B[:,1]'Matrix(A1) - @test Transpose(B)*A1 ≈ Transpose(B)*Matrix(A1) + @test transpose(B)*A1 ≈ transpose(B)*Matrix(A1) @test B'A1 ≈ B'Matrix(A1) - @test B*Transpose(A1) ≈ B*Transpose(Matrix(A1)) + @test B*transpose(A1) ≈ B*transpose(Matrix(A1)) @test B*A1' ≈ B*Matrix(A1)' - @test Transpose(B[:,1])*Transpose(A1) ≈ Transpose(B[:,1])*Transpose(Matrix(A1)) + @test transpose(B[:,1])*transpose(A1) ≈ transpose(B[:,1])*transpose(Matrix(A1)) @test B[:,1]'A1' ≈ B[:,1]'Matrix(A1)' - @test Transpose(B)*Transpose(A1) ≈ Transpose(B)*Transpose(Matrix(A1)) + @test transpose(B)*transpose(A1) ≈ transpose(B)*transpose(Matrix(A1)) @test B'A1' ≈ B'Matrix(A1)' if eltyB == elty1 @test mul!(similar(B),A1,B) ≈ A1*B - @test mul!(similar(B), A1, Adjoint(B)) ≈ A1*B' - @test mul!(similar(B), A1, Transpose(B)) ≈ A1*Transpose(B) - @test mul!(similar(B), Adjoint(A1), B) ≈ A1'*B - @test mul!(similar(B), Transpose(A1), B) ≈ Transpose(A1)*B + @test mul!(similar(B), A1, adjoint(B)) ≈ A1*B' + @test mul!(similar(B), A1, transpose(B)) ≈ A1*transpose(B) + @test mul!(similar(B), adjoint(A1), B) ≈ A1'*B + @test mul!(similar(B), transpose(A1), B) ≈ transpose(A1)*B # test also vector methods B1 = vec(B[1,:]) @test mul!(similar(B1),A1,B1) ≈ A1*B1 - @test mul!(similar(B1), Adjoint(A1), B1) ≈ A1'*B1 - @test mul!(similar(B1), Transpose(A1), B1) ≈ Transpose(A1)*B1 + @test mul!(similar(B1), adjoint(A1), B1) ≈ A1'*B1 + @test mul!(similar(B1), transpose(A1), B1) ≈ transpose(A1)*B1 end #error handling Ann, Bmm, bm = A1, Matrix{eltyB}(uninitialized, n+1, n+1), Vector{eltyB}(uninitialized, n+1) - @test_throws DimensionMismatch mul!(Ann, bm) - @test_throws DimensionMismatch mul!(Bmm, Ann) - @test_throws DimensionMismatch mul!(Transpose(Ann), bm) - @test_throws DimensionMismatch mul!(Adjoint(Ann), bm) - @test_throws DimensionMismatch mul!(Bmm, Adjoint(Ann)) - @test_throws DimensionMismatch mul!(Bmm, Transpose(Ann)) + @test_throws DimensionMismatch mul2!(Ann, bm) + @test_throws DimensionMismatch mul1!(Bmm, Ann) + @test_throws DimensionMismatch mul2!(transpose(Ann), bm) + @test_throws DimensionMismatch mul2!(adjoint(Ann), bm) + @test_throws DimensionMismatch mul1!(Bmm, adjoint(Ann)) + @test_throws DimensionMismatch mul1!(Bmm, transpose(Ann)) # ... and division @test A1\B[:,1] ≈ Matrix(A1)\B[:,1] @test A1\B ≈ Matrix(A1)\B - @test Transpose(A1)\B[:,1] ≈ Transpose(Matrix(A1))\B[:,1] + @test transpose(A1)\B[:,1] ≈ transpose(Matrix(A1))\B[:,1] @test A1'\B[:,1] ≈ Matrix(A1)'\B[:,1] - @test Transpose(A1)\B ≈ Transpose(Matrix(A1))\B + @test transpose(A1)\B ≈ transpose(Matrix(A1))\B @test A1'\B ≈ Matrix(A1)'\B - @test A1\Transpose(B) ≈ Matrix(A1)\Transpose(B) + @test A1\transpose(B) ≈ Matrix(A1)\transpose(B) @test A1\B' ≈ Matrix(A1)\B' - @test Transpose(A1)\Transpose(B) ≈ Transpose(Matrix(A1))\Transpose(B) + @test transpose(A1)\transpose(B) ≈ transpose(Matrix(A1))\transpose(B) @test A1'\B' ≈ Matrix(A1)'\B' Ann, bm = A1, Vector{elty1}(uninitialized,n+1) @test_throws DimensionMismatch Ann\bm @test_throws DimensionMismatch Ann'\bm - @test_throws DimensionMismatch Transpose(Ann)\bm + @test_throws DimensionMismatch transpose(Ann)\bm if t1 == UpperTriangular || t1 == LowerTriangular @test_throws Base.LinAlg.SingularException naivesub!(t1(zeros(elty1,n,n)),fill(eltyB(1),n)) end @test B/A1 ≈ B/Matrix(A1) - @test B/Transpose(A1) ≈ B/Transpose(Matrix(A1)) + @test B/transpose(A1) ≈ B/transpose(Matrix(A1)) @test B/A1' ≈ B/Matrix(A1)' - @test Transpose(B)/A1 ≈ Transpose(B)/Matrix(A1) + @test transpose(B)/A1 ≈ transpose(B)/Matrix(A1) @test B'/A1 ≈ B'/Matrix(A1) - @test Transpose(B)/Transpose(A1) ≈ Transpose(B)/Transpose(Matrix(A1)) + @test transpose(B)/transpose(A1) ≈ transpose(B)/transpose(Matrix(A1)) @test B'/A1' ≈ B'/Matrix(A1)' # Error bounds @@ -498,15 +499,15 @@ let n = 5 @test_throws DimensionMismatch rdiv!(A, UnitLowerTriangular(B)) @test_throws DimensionMismatch rdiv!(A, UnitUpperTriangular(B)) - @test_throws DimensionMismatch rdiv!(A, Adjoint(LowerTriangular(B))) - @test_throws DimensionMismatch rdiv!(A, Adjoint(UpperTriangular(B))) - @test_throws DimensionMismatch rdiv!(A, Adjoint(UnitLowerTriangular(B))) - @test_throws DimensionMismatch rdiv!(A, Adjoint(UnitUpperTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, adjoint(LowerTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, adjoint(UpperTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, adjoint(UnitLowerTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, adjoint(UnitUpperTriangular(B))) - @test_throws DimensionMismatch rdiv!(A, Transpose(LowerTriangular(B))) - @test_throws DimensionMismatch rdiv!(A, Transpose(UpperTriangular(B))) - @test_throws DimensionMismatch rdiv!(A, Transpose(UnitLowerTriangular(B))) - @test_throws DimensionMismatch rdiv!(A, Transpose(UnitUpperTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, transpose(LowerTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, transpose(UpperTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, transpose(UnitLowerTriangular(B))) + @test_throws DimensionMismatch rdiv!(A, transpose(UnitUpperTriangular(B))) end # Test that UpperTriangular(LowerTriangular) throws. See #16201 diff --git a/test/linalg/tridiag.jl b/test/linalg/tridiag.jl index 2fd6b4a4ca5a0..52dc80b961774 100644 --- a/test/linalg/tridiag.jl +++ b/test/linalg/tridiag.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random, SparseArrays + #Test equivalence of eigenvectors/singular vectors taking into account possible phase (sign) differences function test_approx_eq_vecs(a::StridedVecOrMat{S}, b::StridedVecOrMat{T}, error=nothing) where {S<:Real,T<:Real} n = size(a, 1) diff --git a/test/linalg/uniformscaling.jl b/test/linalg/uniformscaling.jl index 7a9f3a1236c16..498602fbe307a 100644 --- a/test/linalg/uniformscaling.jl +++ b/test/linalg/uniformscaling.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random +using SparseArrays srand(123) @@ -76,7 +77,7 @@ let @testset "transpose, conj, inv" begin @test ndims(J) == 2 @test transpose(J) == J - @test J * [1 0; 0 1] == conj(*(Base.LinAlg.Adjoint(J), [1 0; 0 1])) # ctranpose (and A(c)_mul_B) + @test J * [1 0; 0 1] == conj(*(adjoint(J), [1 0; 0 1])) # ctranpose (and A(c)_mul_B) @test I + I === UniformScaling(2) # + @test inv(I) == I @test inv(J) == UniformScaling(inv(λ)) diff --git a/test/logging.jl b/test/logging.jl index 6ff43052091a8..95d9919c3abd0 100644 --- a/test/logging.jl +++ b/test/logging.jl @@ -84,7 +84,7 @@ end @testset "Log message exception handling" begin # Exceptions in message creation are caught by default - @test_logs (Error,) catch_exceptions=true @info "foo $(1÷0)" + @test_logs (Error,Test.Ignored(),Test.Ignored(),:logevent_error) catch_exceptions=true @info "foo $(1÷0)" # Exceptions propagate if explicitly disabled for the logger (by default # for the test logger) @test_throws DivideError collect_test_logs() do diff --git a/test/markdown.jl b/test/markdown.jl index dcdce625a7510..4b9df5512e926 100644 --- a/test/markdown.jl +++ b/test/markdown.jl @@ -1079,3 +1079,17 @@ t = """ :-- | --: 1 | 2""" @test sprint(Markdown.term, Markdown.parse(t), 0) == "a b\n– –\n1 2\n" + +# test Base.copy +let + md = doc"test" + md′ = copy(md) + @test length(md) == length(md′) == 1 + push!(md, "new") + @test length(md) == 2 + @test length(md′) == 1 + + @test !haskey(md.meta, :foo) + md.meta[:foo] = 42 + @test !haskey(md′.meta, :foo) +end diff --git a/test/math.jl b/test/math.jl index ffe8cae351390..8571b6299917e 100644 --- a/test/math.jl +++ b/test/math.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + function isnan_type(::Type{T}, x) where T isa(x, T) && isnan(x) end @@ -297,7 +299,7 @@ end @testset "test abstractarray trig functions" begin TAA = rand(2,2) - TAA = (TAA + transpose(TAA))/2. + TAA = (TAA + TAA')/2. STAA = Symmetric(TAA) @test Array(atanh.(STAA)) == atanh.(TAA) @test Array(asinh.(STAA)) == asinh.(TAA) diff --git a/test/misc.jl b/test/misc.jl index 7755cc4afc8e9..c97e051c3470d 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -226,6 +226,7 @@ end # Issue 14173 module Tmp14173 + using Random export A A = randn(2000, 2000) end @@ -480,6 +481,14 @@ let buf_color = IOBuffer() @test expected_str == String(take!(buf_color)) end +# Test that `print_with_color` on multiline input prints the ANSI codes +# on each line +let buf_color = IOBuffer() + str = "Two\nlines" + print_with_color(:red, IOContext(buf_color, :color=>true), str; bold=true) + @test String(take!(buf_color)) == "\e[31m\e[1mTwo\e[22m\e[39m\n\e[31m\e[1mlines\e[22m\e[39m" +end + if STDOUT isa Base.TTY @test haskey(STDOUT, :color) == true @test haskey(STDOUT, :bar) == false @@ -508,7 +517,7 @@ let buf = IOBuffer() # Check that boldness is turned off print_with_color(:red, buf_color, "foo"; bold = true) - @test String(take!(buf)) == "\e[1m\e[31mfoo\e[39m\e[22m" + @test String(take!(buf)) == "\e[31m\e[1mfoo\e[22m\e[39m" end abstract type DA_19281{T, N} <: AbstractArray{T, N} end @@ -632,3 +641,9 @@ end # PR #23664, make sure names don't get added to the default `Main` workspace @test readlines(`$(Base.julia_cmd()) --startup-file=no -e 'foreach(println, names(Main))'`) == ["Base","Core","Main"] + +# PR #24997: test that `varinfo` doesn't fail when encountering `missing` +module A + export missing + varinfo(A) +end \ No newline at end of file diff --git a/test/mod2pi.jl b/test/mod2pi.jl index f0fe43b9ed776..5b0cb906bcef2 100644 --- a/test/mod2pi.jl +++ b/test/mod2pi.jl @@ -222,23 +222,23 @@ testModPi() # ieee754_rem_pio2_return contains the returned value from the ieee754_rem_pio2 # function in openlibm: https://github.com/JuliaLang/openlibm/blob/0598080ca09468490a13ae393ba17d8620c1b201/src/e_rem_pio2.c - ieee754_rem_pio2_return = adjoint([1.5707963267948966 1.5707963267948966; - 1.0471975511965979 -1.0471975511965979; - 0.10000000000000014 -0.10000000000000014; - 6.123233995736766e-17 -6.123233995736766e-17; - -0.6853981633974481 0.6853981633974481; - 0.10000000000000021 -0.10000000000000021; - 1.2246467991473532e-16 -1.2246467991473532e-16; - -0.6853981633974481 0.6853981633974481; - 0.09999999999999983 -0.09999999999999983; - 1.8369701987210297e-16 -1.8369701987210297e-16; - -0.6853981633974484 0.6853981633974484; - 2.4492935982947064e-16 -2.4492935982947064e-16; - 0.0999999999999999 -0.0999999999999999; - -0.6853981633974484 0.6853981633974484; - 3.135095805817224e-14 -3.135095805817224e-14; - 3.287386219680602e-8 -3.287386219680602e-8; - -0.1757159771004682 0.1757159771004682]) + ieee754_rem_pio2_return = [ 1.5707963267948966 1.5707963267948966; + 1.0471975511965979 -1.0471975511965979; + 0.10000000000000014 -0.10000000000000014; + 6.123233995736766e-17 -6.123233995736766e-17; + -0.6853981633974481 0.6853981633974481; + 0.10000000000000021 -0.10000000000000021; + 1.2246467991473532e-16 -1.2246467991473532e-16; + -0.6853981633974481 0.6853981633974481; + 0.09999999999999983 -0.09999999999999983; + 1.8369701987210297e-16 -1.8369701987210297e-16; + -0.6853981633974484 0.6853981633974484; + 2.4492935982947064e-16 -2.4492935982947064e-16; + 0.0999999999999999 -0.0999999999999999; + -0.6853981633974484 0.6853981633974484; + 3.135095805817224e-14 -3.135095805817224e-14; + 3.287386219680602e-8 -3.287386219680602e-8; + -0.1757159771004682 0.1757159771004682 ]' for (i, case) in enumerate(cases) # negative argument diff --git a/test/mpfr.jl b/test/mpfr.jl index cd90a75165346..7c107c253b0ff 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -880,8 +880,10 @@ end end # issue #22758 -setprecision(2_000_000) do - @test abs(sin(big(pi)/6) - 0.5) < ldexp(big(1.0),-1_999_000) +if MPFR.version() > v"3.1.5" || "r11590" in MPFR.patches() + setprecision(2_000_000) do + @test abs(sin(big(pi)/6) - 0.5) < ldexp(big(1.0),-1_999_000) + end end @testset "show BigFloat" begin diff --git a/test/namedtuple.jl b/test/namedtuple.jl index 5b2c2179a05a5..df5e5d274e3f3 100644 --- a/test/namedtuple.jl +++ b/test/namedtuple.jl @@ -208,3 +208,8 @@ abstr_nt_22194_3() @test Base.structdiff((a=1, b=2, z=20), NamedTuple{(:b,)}) == (a=1, z=20) @test typeof(Base.structdiff(NamedTuple{(:a, :b), Tuple{Int32, Union{Int32, Nothing}}}((1, Int32(2))), (a=0,))) === NamedTuple{(:b,), Tuple{Union{Int32, Nothing}}} + +@test @inferred find(equalto(1), (a=1, b=2)) == [:a] +@test @inferred find(equalto(1), (a=1, b=1)) == [:a, :b] +@test @inferred isempty(find(equalto(1), NamedTuple())) +@test @inferred isempty(find(equalto(1), (a=2, b=3))) \ No newline at end of file diff --git a/test/numbers.jl b/test/numbers.jl index dd9adc60ebae4..570ffa5813d59 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -1,6 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base.MathConstants +using Random + const ≣ = isequal # convenient for comparing NaNs # remove these tests and re-enable the same ones in the diff --git a/test/offsetarray.jl b/test/offsetarray.jl index f27a59983eb3b..0e2634d74addd 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -3,6 +3,7 @@ isdefined(Main, :TestHelpers) || @eval Main include(joinpath(dirname(@__FILE__), "TestHelpers.jl")) using Main.TestHelpers.OAs using DelimitedFiles +using Random const OAs_name = join(fullname(OAs), ".") @@ -32,12 +33,12 @@ S = OffsetArray(view(A0, 1:2, 1:2), (-1,2)) # IndexCartesian @test_throws BoundsError A[0,3,2] @test_throws BoundsError S[0,3,2] # partial indexing -S3 = OffsetArray(view(reshape(collect(1:4*3*1), 4, 3, 1), 1:3, 1:2, :), (-1,-2,1)) +S3 = OffsetArray(view(reshape(Vector(1:4*3*1), 4, 3, 1), 1:3, 1:2, :), (-1,-2,1)) @test S3[1,-1] == 2 @test S3[1,0] == 6 @test_throws BoundsError S3[1,1] @test_throws BoundsError S3[1,-2] -S4 = OffsetArray(view(reshape(collect(1:4*3*2), 4, 3, 2), 1:3, 1:2, :), (-1,-2,1)) +S4 = OffsetArray(view(reshape(Vector(1:4*3*2), 4, 3, 2), 1:3, 1:2, :), (-1,-2,1)) @test S4[1,-1,2] == 2 @test S4[1,0,2] == 6 @test_throws BoundsError S4[1,1,2] @@ -123,16 +124,16 @@ S = view(A, :, :) @test_throws BoundsError S[1,1] @test axes(S) === (0:1, 3:4) # https://github.com/JuliaArrays/OffsetArrays.jl/issues/27 -g = OffsetArray(collect(-2:3), (-3,)) +g = OffsetArray(Vector(-2:3), (-3,)) gv = view(g, -1:2) @test axes(gv, 1) === Base.OneTo(4) -@test collect(gv) == collect(-1:2) +@test collect(gv) == -1:2 gv = view(g, OffsetArray(-1:2, (-2,))) @test axes(gv, 1) === -1:2 -@test collect(gv) == collect(-1:2) +@test collect(gv) == -1:2 gv = view(g, OffsetArray(-1:2, (-1,))) @test axes(gv, 1) === 0:3 -@test collect(gv) == collect(-1:2) +@test collect(gv) == -1:2 # iteration for (a,d) in zip(A, A0) @@ -327,8 +328,8 @@ cv = copy(v) A = OffsetArray(rand(4,4), (-3,5)) @test A ≈ A -@test axes(adjoint(A)) === (6:9, -2:1) -@test parent(adjoint(A)) == adjoint(parent(A)) +@test axes(A') === (6:9, -2:1) +@test parent(copy(A')) == copy(parent(A)') @test collect(A) == parent(A) @test maximum(A) == maximum(parent(A)) @test minimum(A) == minimum(parent(A)) @@ -359,9 +360,8 @@ pmax, ipmax = findmax(parent(A)) @test A[iamax] == amax @test amax == parent(A)[ipmax] z = OffsetArray([0 0; 2 0; 0 0; 0 0], (-3,-1)) -I,J = findn(z) -@test I == [-1] -@test J == [0] +I = find(!iszero, z) +@test I == [CartesianIndex(-1, 0)] I,J,N = findnz(z) @test I == [-1] @test J == [0] @@ -430,7 +430,7 @@ v = OffsetArray(rand(8), (-2,)) @test circshift(A, (-1,2)) == OffsetArray(circshift(parent(A), (-1,2)), A.offsets) -src = reshape(collect(1:16), (4,4)) +src = reshape(Vector(1:16), (4,4)) dest = OffsetArray(Matrix{Int}(uninitialized, 4,4), (-1,1)) circcopy!(dest, src) @test parent(dest) == [8 12 16 4; 5 9 13 1; 6 10 14 2; 7 11 15 3] diff --git a/test/operators.jl b/test/operators.jl index 96c0f538ad2bf..51a3094f025c9 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random: randstring + @test ifelse(true, 1, 2) == 1 @test ifelse(false, 1, 2) == 2 @@ -52,13 +54,6 @@ p = 1=>:foo @test xor(2) == 2 @test (⊻)(2) == 2 -@test_throws ArgumentError Base.scalarmin(['a','b'],['c','d']) -@test_throws ArgumentError Base.scalarmin('a',['c','d']) -@test_throws ArgumentError Base.scalarmin(['a','b'],'c') -@test_throws ArgumentError Base.scalarmax(['a','b'],['c','d']) -@test_throws ArgumentError Base.scalarmax('a',['c','d']) -@test_throws ArgumentError Base.scalarmax(['a','b'],'c') - @test_throws MethodError min(Set([1]), Set([2])) @test_throws MethodError max(Set([1]), Set([2])) @test_throws MethodError minmax(Set([1]), Set([2])) @@ -106,12 +101,12 @@ Base.promote_rule(::Type{T19714}, ::Type{Int}) = T19714 # pr #17155 @testset "function composition" begin - @test (Base.Unicode.uppercase∘hex)(239487) == "3A77F" + @test (uppercase∘hex)(239487) == "3A77F" end @testset "function negation" begin str = randstring(20) - @test filter(!Base.Unicode.isupper, str) == replace(str, r"[A-Z]" => "") - @test filter(!Base.Unicode.islower, str) == replace(str, r"[a-z]" => "") + @test filter(!isupper, str) == replace(str, r"[A-Z]" => "") + @test filter(!islower, str) == replace(str, r"[a-z]" => "") end # issue #19891 diff --git a/test/perf/kernel/json.jl b/test/perf/kernel/json.jl index 44917d6b86d44..8f992508614b3 100644 --- a/test/perf/kernel/json.jl +++ b/test/perf/kernel/json.jl @@ -69,7 +69,7 @@ function parse_json(strng::AbstractString) end function skip_whitespace() - while pos <= len && Base.Unicode.isspace(strng[pos]) + while pos <= len && isspace(strng[pos]) pos = pos + 1 end end diff --git a/test/perf/lapack/eig.jl b/test/perf/lapack/eig.jl index 47d980bff88ea..aeea0559fd72d 100644 --- a/test/perf/lapack/eig.jl +++ b/test/perf/lapack/eig.jl @@ -2,9 +2,8 @@ # Real function realeigtest(n, iter) + local d, v A = rand(n,n) - d = Vector{eltype(A)} - v = similar(A) for i = 1:iter d,v = eig(A) end @@ -13,10 +12,9 @@ end # Symmetric function symeigtest(n, iter) + local d, v A = rand(n,n) - A = A + adjoint(A) - d = Vector{eltype(A)} - v = similar(A) + A = A + A' for i = 1:iter d,v = eig(A) end @@ -25,10 +23,9 @@ end # Hermitian function hermitianeigtest(n, iter) - A = rand(n,n) + im*rand(n,n) - A = A + adjoint(A) - d = Vector{eltype(A)} - v = similar(A) + local d, v + A = rand(ComplexF64, n, n) + A = A + A' for i = 1:iter d,v = eig(A) end diff --git a/test/perf/micro/Makefile b/test/perf/micro/Makefile index 480f3a3b76cec..c811c3e46e1dc 100644 --- a/test/perf/micro/Makefile +++ b/test/perf/micro/Makefile @@ -58,7 +58,7 @@ bin/perf%: perf.c perf.h bin/fperf%: perf.f90 mkdir -p mods/$@ #Modules for each binary go in separate directories # $(FC) $(FFLAGS) -Jmods/$@ -O$* $< -o $@ $(LIBBLAS) -L$(LIBMDIR) $(LIBM) -lpthread - $(FC) $(FFLAGS) -Jmods/$@ -O$* $< -o $@ -lblas -L$(LIBMDIR) $(LIBM) -lpthread + $(FC) $(FFLAGS) -Jmods/$@ -O$* $< -o $@ -lopenblas -L$(LIBMDIR) $(LIBM) -lpthread benchmarks/c.csv: \ benchmarks/c0.csv \ diff --git a/test/perf/micro/bin/table.pl b/test/perf/micro/bin/table.pl index b8a8c3349a6cc..4405733274395 100755 --- a/test/perf/micro/bin/table.pl +++ b/test/perf/micro/bin/table.pl @@ -51,7 +51,7 @@ # "stata" => ["Stata" , $stata_ver ], ); -our @systems = qw(c julia lua fortran go java javascript mathematica python matlab r octave); +our @systems = qw(c julia lua go fortran java javascript matlab mathematica python r octave); print qq[\n]; print qq[\n]; diff --git a/test/perf/micro/java/src/main/java/PerfPure.java b/test/perf/micro/java/src/main/java/PerfPure.java index 9a30dea1706e2..25e26a5cfcdc5 100644 --- a/test/perf/micro/java/src/main/java/PerfPure.java +++ b/test/perf/micro/java/src/main/java/PerfPure.java @@ -149,7 +149,7 @@ void printfd(int n) { PrintStream ps = new PrintStream(f); long i = 0; for (i = 0; i < n; i++) { - ps.println(i+" "+i); + ps.println(i + " " + (i+1)); } ps.close(); } catch (FileNotFoundException e) { diff --git a/test/perf/micro/perf.R b/test/perf/micro/perf.R index 3108634c1f26d..fe5c163e5634b 100644 --- a/test/perf/micro/perf.R +++ b/test/perf/micro/perf.R @@ -44,7 +44,7 @@ timeit("parse_integers", parseintperf, 1000) printfdperf = function(t) { fd<-file("/dev/null") for (i in 1:t) { - s = sprintf("%d %d", i, i) + s = sprintf("%d %d", i, i+1) writeLines(s, fd) } } diff --git a/test/perf/micro/perf.c b/test/perf/micro/perf.c index b088b00e36089..71a5a30ee99c5 100644 --- a/test/perf/micro/perf.c +++ b/test/perf/micro/perf.c @@ -223,7 +223,7 @@ void printfd(int n) { FILE *f = fopen("/dev/null", "w"); long i = 0; for (i = 0; i < n; i++) - fprintf(f, "%ld %ld\n", i, i); + fprintf(f, "%ld %ld\n", i, i+1); fclose(f); } diff --git a/test/perf/micro/perf.f90 b/test/perf/micro/perf.f90 index bbf940e1935a2..1661cb77f6467 100644 --- a/test/perf/micro/perf.f90 +++ b/test/perf/micro/perf.f90 @@ -193,9 +193,9 @@ integer function parse_int(s, base) result(n) subroutine printfd(n) integer, intent(in) :: n integer :: i , unit -open(unit=1, file="foo") +open(unit=1, file="/dev/null") do i = 1, n - write(unit=1, fmt=*) i, i + write(unit=1, fmt=*) i, i+1 end do close(unit=1) end subroutine diff --git a/test/perf/micro/perf.go b/test/perf/micro/perf.go index 7f63ede70b2bb..077a0bc7827a6 100644 --- a/test/perf/micro/perf.go +++ b/test/perf/micro/perf.go @@ -64,7 +64,7 @@ func printfd(n int) { w := bufio.NewWriter(f) for i := 0; i < n; i++ { - _, err = fmt.Fprintf(w, "%d %d\n", i, i) + _, err = fmt.Fprintf(w, "%d %d\n", i, i+1) } w.Flush() f.Close() diff --git a/test/perf/micro/perf.jl b/test/perf/micro/perf.jl index 125667ed646ef..01dc45c5a3a99 100644 --- a/test/perf/micro/perf.jl +++ b/test/perf/micro/perf.jl @@ -1,6 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Test +using Printf + include("../perfutil.jl") @@ -125,8 +127,8 @@ function randmatstat(t) d = randn(n,n) P = [a b c d] Q = [a b; c d] - v[i] = trace((Transpose(P)*P)^4) - w[i] = trace((Transpose(Q)*Q)^4) + v[i] = trace((P'*P)^4) + w[i] = trace((Q'*Q)^4) end return (std(v)/mean(v), std(w)/mean(w)) end diff --git a/test/perf/micro/perf.m b/test/perf/micro/perf.m index e47a0eb76dfd2..28742ff44a3d3 100644 --- a/test/perf/micro/perf.m +++ b/test/perf/micro/perf.m @@ -107,7 +107,7 @@ function timeit(name, func, varargin) %% mandelbrot set: complex arithmetic and comprehensions %% function r = abs2(z) - r = real(z)*real(z) + imag(z)*imag(z) + r = real(z)*real(z) + imag(z)*imag(z); end function n = mandel(z) @@ -228,7 +228,7 @@ function timeit(name, func, varargin) function printfd(n) f = fopen('/dev/null','w'); for i = 1:n - fprintf(f, '%d %d\n', i, i); + fprintf(f, '%d %d\n', i, i + 1); end fclose(f); end diff --git a/test/perf/micro/perf.nb b/test/perf/micro/perf.nb index efede5ff7da96..8c01a74495b8a 100644 --- a/test/perf/micro/perf.nb +++ b/test/perf/micro/perf.nb @@ -72,7 +72,7 @@ printfdperf[t_] := Module[ filename = "/dev/null"; fd = OpenWrite[filename]; For[i=1, i<=t, ++i, - WriteString[fd, StringForm["`1` `2`\n", i, i]]; + WriteString[fd, StringForm["`1` `2`\n", i, i + 1]]; ]; Close[fd]; ]; diff --git a/test/perf/micro/perf.py b/test/perf/micro/perf.py index 539f1e49a6f33..1081cc1960dfa 100644 --- a/test/perf/micro/perf.py +++ b/test/perf/micro/perf.py @@ -105,7 +105,7 @@ def parse_int(t): def printfd(t): f = open("/dev/null", "w") for i in range(1,t): - f.write("%d %d\n") + f.write("{:d} {:d}\n".format(i, i+1)) f.close() diff --git a/test/perf/perfgeneric.jl b/test/perf/perfgeneric.jl index 4fef6051e42ae..4e7dba0fa8051 100644 --- a/test/perf/perfgeneric.jl +++ b/test/perf/perfgeneric.jl @@ -3,6 +3,6 @@ #Generic benchmark driver for (testfunc, testname, longtestname, problem_sizes) in testdata for (n, t, size) in problem_sizes - @timeit testfunc(n, t) string(testname,"_",size) string(Base.Unicode.uppercase(size[1]),size[2:end]," ",longtestname," test") + @timeit testfunc(n, t) string(testname,"_",size) string(uppercase(size[1]),size[2:end]," ",longtestname," test") end end diff --git a/test/perf/perfutil.jl b/test/perf/perfutil.jl index 69a6a85f2ad83..7c923aa3612a0 100644 --- a/test/perf/perfutil.jl +++ b/test/perf/perfutil.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Printf, Random + const mintrials = 5 const mintime = 2000.0 print_output = isempty(ARGS) @@ -69,19 +71,21 @@ end macro timeit(ex,name,desc,group...) quote - t = Float64[] - tot = 0.0 - i = 0 - while i < mintrials || tot < mintime - e = 1000*(@elapsed $(esc(ex))) - tot += e - if i > 0 - # warm up on first iteration - push!(t, e) + let + t = Float64[] + tot = 0.0 + i = 0 + while i < mintrials || tot < mintime + e = 1000*(@elapsed $(esc(ex))) + tot += e + if i > 0 + # warm up on first iteration + push!(t, e) + end + i += 1 end - i += 1 + @output_timings t $(esc(name)) $(esc(desc)) $(esc(group)) end - @output_timings t $(esc(name)) $(esc(desc)) $(esc(group)) end end diff --git a/test/perf/shootout/k_nucleotide.jl b/test/perf/shootout/k_nucleotide.jl index a070e79c97719..d132efe210049 100644 --- a/test/perf/shootout/k_nucleotide.jl +++ b/test/perf/shootout/k_nucleotide.jl @@ -70,7 +70,7 @@ function k_nucleotide(infile="knucleotide-input.txt") i, j = 1, 1 while i <= length(data) if data[i] != '\n' - data[j] = Base.Unicode.uppercase(data[i]) + data[j] = uppercase(data[i]) j += 1 end i += 1 diff --git a/test/perf/simd/sum_reduce.jl b/test/perf/simd/sum_reduce.jl index 9ad02e7c9fb7a..b6bf05dbebc54 100644 --- a/test/perf/simd/sum_reduce.jl +++ b/test/perf/simd/sum_reduce.jl @@ -23,4 +23,3 @@ for t in [Float32,Float64] bits = 8*sizeof(t) @timeit(flog_sum_reduce(100,x), "sum_reduction_$bits", "SIMD sum reduction over array of type $t", "SIMD") end - diff --git a/test/perf/sparse/getindex.jl b/test/perf/sparse/getindex.jl index 03d6a6f36b267..64595ea50dbdf 100644 --- a/test/perf/sparse/getindex.jl +++ b/test/perf/sparse/getindex.jl @@ -57,7 +57,7 @@ function sparse_getindex_perf() intinds = nothing logicalinds = nothing # needs to be generated for a specific matrix size. rangeinds = 121:237 - orderedinds = collect(rangeinds) + orderedinds = Vector(rangeinds) disorderedinds = orderedinds[randperm(length(orderedinds))] inds = [(intinds, "integers"), (logicalinds, "logical array"), (rangeinds, "a range"), diff --git a/test/perf/spell/perf.jl b/test/perf/spell/perf.jl index 687b9243ac99a..8fa1e8426f32b 100644 --- a/test/perf/spell/perf.jl +++ b/test/perf/spell/perf.jl @@ -15,7 +15,7 @@ include("../perfutil.jl") -words(text) = eachmatch(r"[a-z]+", Base.Unicode.lowercase(text)) +words(text) = eachmatch(r"[a-z]+", lowercase(text)) function train(features) model = Dict{AbstractString, Int}() diff --git a/test/pkg.jl b/test/pkg.jl index 3f2dee5d118b2..99b0294ce5d40 100644 --- a/test/pkg.jl +++ b/test/pkg.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license import Base.Pkg.PkgError +using Random: randstring function capture_stdout(f::Function) let fname = tempname() diff --git a/test/ranges.jl b/test/ranges.jl index c12bb55473aa1..8acb419dce83f 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Dates +using Dates, Random # Compare precision in a manner sensitive to subnormals, which lose # precision compared to widening. @@ -251,7 +251,7 @@ end @test length(1:2:0) == 0 end @testset "find(::OccursIn, ::Array)" begin - @test find(occursin(3:20), [5.2, 3.3]) == find(occursin(collect(3:20)), [5.2, 3.3]) + @test find(occursin(3:20), [5.2, 3.3]) == find(occursin(Vector(3:20)), [5.2, 3.3]) let span = 5:20, r = -7:3:42 @@ -505,8 +505,8 @@ end (0, 1, 5, 0), (0, -10, 5, 0), (0, -10, 0, 1), (0, -1, 1, 0), (0, 1, -1, 0), (0, -1, -10, 11)) r = start/10:step/10:stop/10 - a = collect(start:step:stop)./10 - ra = collect(r) + a = Vector(start:step:stop)./10 + ra = Vector(r) @test r == a @test isequal(r, a) @@ -519,7 +519,7 @@ end if len > 0 l = linspace(start/10, stop/10, len) - la = collect(l) + la = Vector(l) @test a == l @test r == l @@ -536,8 +536,8 @@ end @test 1.0:1/49:27.0 == linspace(1.0,27.0,1275) == [49:1323;]./49 @test isequal(1.0:1/49:27.0, linspace(1.0,27.0,1275)) - @test isequal(1.0:1/49:27.0, collect(49:1323)./49) - @test hash(1.0:1/49:27.0) == hash(linspace(1.0,27.0,1275)) == hash(collect(49:1323)./49) + @test isequal(1.0:1/49:27.0, Vector(49:1323)./49) + @test hash(1.0:1/49:27.0) == hash(linspace(1.0,27.0,1275)) == hash(Vector(49:1323)./49) @test [prevfloat(0.1):0.1:0.3;] == [prevfloat(0.1), 0.2, 0.3] @test [nextfloat(0.1):0.1:0.3;] == [nextfloat(0.1), 0.2] @@ -691,12 +691,12 @@ end linspace(0, 1, 20), map(Float32, linspace(0, 1, 20))] for r in Rs local r - ar = collect(r) + ar = Vector(r) @test r == ar @test isequal(r,ar) @test hash(r) == hash(ar) for s in Rs - as = collect(s) + as = Vector(s) @test isequal(r,s) == (hash(r)==hash(s)) @test (r==s) == (ar==as) end @@ -950,15 +950,15 @@ end function test_linspace_identity(r::AbstractRange{T}, mr) where T @test -r == mr - @test -collect(r) == collect(mr) + @test -Vector(r) == Vector(mr) @test isa(-r, typeof(r)) @test broadcast(+, broadcast(+, 1, r), -1) == r - @test 1 .+ collect(r) == collect(1 .+ r) == collect(r .+ 1) + @test 1 .+ Vector(r) == Vector(1 .+ r) == Vector(r .+ 1) @test isa(broadcast(+, broadcast(+, 1, r), -1), typeof(r)) @test broadcast(-, broadcast(-, 1, r), 1) == mr - @test 1 .- collect(r) == collect(1 .- r) == collect(1 .+ mr) - @test collect(r) .- 1 == collect(r .- 1) == -collect(mr .+ 1) + @test 1 .- Vector(r) == Vector(1 .- r) == Vector(1 .+ mr) + @test Vector(r) .- 1 == Vector(r .- 1) == -Vector(mr .+ 1) @test isa(broadcast(-, broadcast(-, 1, r), 1), typeof(r)) @test 1 * r * 1 == r @@ -969,9 +969,9 @@ end @test r / T(0.5) * T(0.5) == r @test isa(r / 1, typeof(r)) - @test (2 * collect(r) == collect(r * 2) == collect(2 * r) == - collect(r * T(2.0)) == collect(T(2.0) * r) == - collect(r / T(0.5)) == -collect(mr * T(2.0))) + @test (2 * Vector(r) == Vector(r * 2) == Vector(2 * r) == + Vector(r * T(2.0)) == Vector(T(2.0) * r) == + Vector(r / T(0.5)) == -Vector(mr * T(2.0))) end test_linspace_identity(linspace(1.0, 27.0, 10), linspace(-1.0, -27.0, 10)) @@ -1024,10 +1024,10 @@ end @test r1 - r2 == r_diff @test r2 - r1 == -r_diff - @test collect(r1) + collect(r2) == collect(r_sum) - @test collect(r2) + collect(r1) == collect(r_sum) - @test collect(r1) - collect(r2) == collect(r_diff) - @test collect(r2) - collect(r1) == collect(-r_diff) + @test Vector(r1) + Vector(r2) == Vector(r_sum) + @test Vector(r2) + Vector(r1) == Vector(r_sum) + @test Vector(r1) - Vector(r2) == Vector(r_diff) + @test Vector(r2) - Vector(r1) == Vector(-r_diff) end test_range_sum_diff(1:5, 0:2:8, 1:3:13, 1:-1:-3) @@ -1196,11 +1196,11 @@ Base.isless(x, y::NotReal) = isless(x, y.val) isdefined(Main, :TestHelpers) || @eval Main include("TestHelpers.jl") using Main.TestHelpers: Furlong @testset "dimensional correctness" begin - @test length(collect(Furlong(2):Furlong(10))) == 9 + @test length(Vector(Furlong(2):Furlong(10))) == 9 @test length(range(Furlong(2), 9)) == 9 - @test collect(Furlong(2):Furlong(1):Furlong(10)) == collect(range(Furlong(2),Furlong(1),9)) == Furlong.(2:10) - @test collect(Furlong(1.0):Furlong(0.5):Furlong(10.0)) == - collect(Furlong(1):Furlong(0.5):Furlong(10)) == Furlong.(1:0.5:10) + @test Vector(Furlong(2):Furlong(1):Furlong(10)) == Vector(range(Furlong(2),Furlong(1),9)) == Furlong.(2:10) + @test Vector(Furlong(1.0):Furlong(0.5):Furlong(10.0)) == + Vector(Furlong(1):Furlong(0.5):Furlong(10)) == Furlong.(1:0.5:10) end @testset "issue #22270" begin diff --git a/test/read.jl b/test/read.jl index b6b6fef9bebd2..abf3c00091992 100644 --- a/test/read.jl +++ b/test/read.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using DelimitedFiles +using Random mktempdir() do dir diff --git a/test/reduce.jl b/test/reduce.jl index 67b7160304155..66ac705fab643 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + # fold(l|r) & mapfold(l|r) @test foldl(+, Int64[]) === Int64(0) # In reference to issues #7465/#20144 (PR #20160) @test foldl(+, Int16[]) === Int16(0) # In reference to issues #21536 @@ -43,10 +45,10 @@ @test mapreduce(-, +, [-10]) == 10 @test mapreduce(abs2, +, [-9, -3]) == 81 + 9 @test mapreduce(-, +, [-9, -3, -4, 8, -2]) == (9 + 3 + 4 - 8 + 2) -@test mapreduce(-, +, collect(linspace(1.0, 10000.0, 10000))) == -50005000.0 +@test mapreduce(-, +, Vector(linspace(1.0, 10000.0, 10000))) == -50005000.0 # empty mr @test mapreduce(abs2, +, Float64[]) === 0.0 -@test mapreduce(abs2, Base.scalarmax, Float64[]) === 0.0 +@test mapreduce(abs2, max, Float64[]) === 0.0 @test mapreduce(abs, max, Float64[]) === 0.0 @test_throws ArgumentError mapreduce(abs2, &, Float64[]) @test_throws ArgumentError mapreduce(abs2, |, Float64[]) @@ -209,7 +211,7 @@ prod2(itr) = invoke(prod, Tuple{Any}, itr) @test minimum(abs2, 3:7) == 9 @test maximum(Int16[1]) === Int16(1) -@test maximum(collect(Int16(1):Int16(100))) === Int16(100) +@test maximum(Vector(Int16(1):Int16(100))) === Int16(100) @test maximum(Int32[1,2]) === Int32(2) A = circshift(reshape(1:24,2,3,4), (0,1,1)) @@ -357,8 +359,8 @@ let es = sum(BigFloat.(z)), es2 = sum(BigFloat.(z[1:10^5])) @test (es2 - cs[10^5]) < es2 * 1e-13 end -@test sum(collect(map(UInt8,0:255))) == 32640 -@test sum(collect(map(UInt8,254:255))) == 509 +@test sum(Vector(map(UInt8,0:255))) == 32640 +@test sum(Vector(map(UInt8,254:255))) == 509 A = reshape(map(UInt8, 101:109), (3,3)) @test @inferred(sum(A)) == 945 @@ -374,7 +376,7 @@ A = reshape(map(UInt8, 1:100), (10,10)) @test prod([-0.0, -0.0]) === 0.0 #contains -let A = collect(1:10) +let A = Vector(1:10) @test A ∋ 5 @test A ∌ 11 @test any(y->y==6,A) diff --git a/test/reducedim.jl b/test/reducedim.jl index 452582497f194..53435f454d464 100644 --- a/test/reducedim.jl +++ b/test/reducedim.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + # main tests function safe_mapslices(op, A, region) diff --git a/test/reflection.jl b/test/reflection.jl index b5dfd45d87155..e22c553c03771 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -5,7 +5,7 @@ # sufficient to catch segfault bugs. module ReflectionTest -using Test +using Test, Random function test_ast_reflection(freflect, f, types) @test !isempty(freflect(f, types)) @@ -55,7 +55,7 @@ end # module ReflectionTest # code_warntype module WarnType -using Test +using Test, Random function warntype_hastag(f, types, tag) iob = IOBuffer() @@ -782,7 +782,7 @@ test_similar_codeinfo(cinfo, cinfo_generated) @test_throws ErrorException code_lowered(f22979, typeof.(x22979), false) module MethodDeletion -using Test +using Test, Random # Deletion after compiling top-level call bar1(x) = 1 diff --git a/test/repl.jl b/test/repl.jl index e0aa274cf46c1..ae39f0cf2b9a6 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -7,6 +7,7 @@ include("testenv.jl") isdefined(Main, :TestHelpers) || @eval Main include(joinpath(dirname(@__FILE__), "TestHelpers.jl")) using Main.TestHelpers import Base: REPL, LineEdit +using Random function fake_repl(f; options::REPL.Options=REPL.Options(confirm_exit=false)) # Use pipes so we can easily do blocking reads diff --git a/test/replcompletions.jl b/test/replcompletions.jl index 497baa63a096d..acc076d7b92dc 100644 --- a/test/replcompletions.jl +++ b/test/replcompletions.jl @@ -1,9 +1,12 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base.REPLCompletions +using Random let ex = quote module CompletionFoo + using Random + mutable struct Test_y yy end @@ -51,7 +54,7 @@ let ex = quote test5(x::Float64) = pass const a=x->x test6()=[a, a] - test7() = rand() > 0.5 ? 1 : 1.0 + test7() = rand(Bool) ? 1 : 1.0 test8() = Any[1][1] kwtest(; x=1, y=2, w...) = pass @@ -207,6 +210,12 @@ let s = "Pkg.add(\"lol" @test res == false end +# inexistent completion inside a cmd +let s = "run(`lol" + c, r, res = test_complete(s) + @test res == false +end + # test latex symbol completions let s = "\\alpha" c, r = test_bslashcomplete(s) @@ -767,6 +776,7 @@ end if Sys.iswindows() tmp = tempname() + touch(tmp) path = dirname(tmp) file = basename(tmp) temp_name = basename(path) @@ -888,3 +898,4 @@ test_dict_completion("test_repl_comp_customdict") c, r, res = test_complete("CompletionFoo.tϵsτc") @test "tϵsτcmδ`" in c end + diff --git a/test/replutil.jl b/test/replutil.jl index 38d2f76d0dffd..596d8aa9e4ec2 100644 --- a/test/replutil.jl +++ b/test/replutil.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + # For curmod_* include("testenv.jl") @@ -12,8 +14,8 @@ Base.show_method_candidates(buf, Base.MethodError(method_c1,(1, 1, ""))) @test String(take!(buf)) == "\nClosest candidates are:\n method_c1(!Matched::Float64, !Matched::AbstractString...)$cfile$c1line" @test length(methods(method_c1)) <= 3 # because of '...' in candidate printing Base.show_method_candidates(IOContext(buf, :color => true), Base.MethodError(method_c1,(1, 1, ""))) -@test String(take!(buf)) == "\e[0m\nClosest candidates are:\n method_c1(\e[91m::Float64\e[39m, \e[91m::AbstractString...\e[39m)$cfile$c1line" +@test String(take!(buf)) == "\n\e[0mClosest candidates are:\n\e[0m method_c1(\e[91m::Float64\e[39m, \e[91m::AbstractString...\e[39m)$cfile$c1line" Base.show_method_candidates(buf, Base.MethodError(method_c1,(1, "", ""))) @test String(take!(buf)) == "\nClosest candidates are:\n method_c1(!Matched::Float64, ::AbstractString...)$cfile$c1line" diff --git a/test/runtests.jl b/test/runtests.jl index 583d542ca8629..93195a9e38850 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -92,62 +92,101 @@ cd(dirname(@__FILE__)) do end end - @sync begin - for p in workers() - @async begin - while length(tests) > 0 - test = popfirst!(tests) - local resp - wrkr = p - try - resp = remotecall_fetch(runtests, wrkr, test, test_path(test); seed=seed) - catch e - resp = [e] + all_tests = [tests; node1_tests] + + local stdin_monitor + all_tasks = Task[] + try + if isa(STDIN, Base.TTY) + t = current_task() + # Monitor STDIN and kill this task on ^C + stdin_monitor = @async begin + term = Base.Terminals.TTYTerminal("xterm", STDIN, STDOUT, STDERR) + try + Base.Terminals.raw!(term, true) + while true + if read(term, Char) == '\x3' + Base.throwto(t, InterruptException()) + break + end end - push!(results, (test, resp)) - if resp[1] isa Exception - if exit_on_error - skipped = length(tests) - empty!(tests) + catch e + isa(e, InterruptException) || rethrow(e) + finally + Base.Terminals.raw!(term, false) + end + end + end + @sync begin + for p in workers() + @async begin + push!(all_tasks, current_task()) + while length(tests) > 0 + test = popfirst!(tests) + local resp + wrkr = p + try + resp = remotecall_fetch(runtests, wrkr, test, test_path(test); seed=seed) + catch e + isa(e, InterruptException) && return + resp = [e] end - elseif resp[end] > max_worker_rss - if n > 1 - rmprocs(wrkr, waitfor=30) - p = addprocs_with_testenv(1)[1] - remotecall_fetch(include, p, "testdefs.jl") - else # single process testing - error("Halting tests. Memory limit reached : $resp > $max_worker_rss") + push!(results, (test, resp)) + if resp[1] isa Exception + if exit_on_error + skipped = length(tests) + empty!(tests) + end + elseif resp[end] > max_worker_rss + if n > 1 + rmprocs(wrkr, waitfor=30) + p = addprocs_with_testenv(1)[1] + remotecall_fetch(include, p, "testdefs.jl") + else # single process testing + error("Halting tests. Memory limit reached : $resp > $max_worker_rss") + end end - end - !isa(resp[1], Exception) && print_testworker_stats(test, wrkr, resp) - end - if p != 1 - # Free up memory =) - rmprocs(p, waitfor=30) + !isa(resp[1], Exception) && print_testworker_stats(test, wrkr, resp) + end + if p != 1 + # Free up memory =) + rmprocs(p, waitfor=30) + end end end end - end - n > 1 && length(node1_tests) > 1 && print("\nExecuting tests that run on node 1 only:\n") - for t in node1_tests - # As above, try to run each test - # which must run on node 1. If - # the test fails, catch the error, - # and either way, append the results - # to the overall aggregator - isolate = true - t == "SharedArrays" && (isolate = false) - local resp - try - resp = eval(Expr(:call, () -> runtests(t, test_path(t), isolate, seed=seed))) # runtests is defined by the include above - print_testworker_stats(t, 1, resp) - catch e - resp = [e] + n > 1 && length(node1_tests) > 1 && print("\nExecuting tests that run on node 1 only:\n") + for t in node1_tests + # As above, try to run each test + # which must run on node 1. If + # the test fails, catch the error, + # and either way, append the results + # to the overall aggregator + isolate = true + t == "SharedArrays" && (isolate = false) + local resp + try + resp = eval(Expr(:call, () -> runtests(t, test_path(t), isolate, seed=seed))) # runtests is defined by the include above + print_testworker_stats(t, 1, resp) + catch e + resp = [e] + end + push!(results, (t, resp)) + end + catch e + isa(e, InterruptException) || rethrow(e) + # If the test suite was merely interrupted, still print the + # summary, which can be useful to diagnose what's going on + foreach(task->try; schedule(task, InterruptException(); error=true); end, all_tasks) + foreach(wait, all_tasks) + finally + if isa(STDIN, Base.TTY) + schedule(stdin_monitor, InterruptException(); error=true) end - push!(results, (t, resp)) end + #= ` Construct a testset on the master node which will hold results from all the test files run on workers and on node1. The loop goes through the results, @@ -172,7 +211,9 @@ cd(dirname(@__FILE__)) do =# o_ts = Test.DefaultTestSet("Overall") Test.push_testset(o_ts) + completed_tests = Set{String}() for res in results + push!(completed_tests, res[1]) if isa(res[2][1], Test.DefaultTestSet) Test.push_testset(res[2][1]) Test.record(o_ts, res[2][1]) @@ -218,6 +259,14 @@ cd(dirname(@__FILE__)) do error(string("Unknown result type : ", typeof(res))) end end + for test in all_tests + (test in completed_tests) && continue + fake = Test.DefaultTestSet(test) + Test.record(fake, Test.Error(:test_interrupted, test, InterruptException(), [], LineNumberNode(1))) + Test.push_testset(fake) + Test.record(o_ts, fake) + Test.pop_testset() + end println() Test.print_test_results(o_ts,1) if !o_ts.anynonpass diff --git a/test/serialize.jl b/test/serialize.jl index 5b2aa48c92826..456d08fbbe3e7 100644 --- a/test/serialize.jl +++ b/test/serialize.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random # Check that serializer hasn't gone out-of-frame @test Serializer.sertag(Symbol) == 1 diff --git a/test/sets.jl b/test/sets.jl index fe7927000f196..12ff5cbc164d6 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -61,6 +61,15 @@ end @test !isequal(Set{Any}([1,2,3,4]), Set{Int}([1,2,3])) @test !isequal(Set{Int}([1,2,3,4]), Set{Any}([1,2,3])) end + +@testset "hash and == for Set/BitSet" begin + for s = (Set([1]), Set(1:10), Set(-100:7:100)) + b = BitSet(s) + @test hash(s) == hash(b) + @test s == b + end +end + @testset "eltype, empty" begin s1 = empty(Set([1,"hello"])) @test isequal(s1, Set()) @@ -482,9 +491,12 @@ end @test replace!(x->maybe(2x, iseven(x)), a) === a @test a == [1, 4, 3, 1] @test replace(a, 1=>0) == [0, 4, 3, 0] - @test replace(a, 1=>0, count=1) == [0, 4, 3, 1] + for count = (1, 0x1, big(1)) + @test replace(a, 1=>0, count=count) == [0, 4, 3, 1] + end @test replace!(a, 1=>2) === a @test a == [2, 4, 3, 2] + @test replace!(x->2x, a, count=0x2) == [4, 8, 3, 2] d = Dict(1=>2, 3=>4) @test replace(x->x.first > 2, d, 0=>0) == Dict(1=>2, 0=>0) @@ -493,24 +505,30 @@ end @test replace(d, (3=>8)=>(0=>0)) == Dict(1=>2, 0=>0) @test replace!(d, (3=>8)=>(2=>2)) === d @test d == Dict(1=>2, 2=>2) - @test replace(x->x.second == 2, d, 0=>0, count=1) in [Dict(1=>2, 0=>0), - Dict(2=>2, 0=>0)] - + for count = (1, 0x1, big(1)) + @test replace(x->x.second == 2, d, 0=>0, count=count) in [Dict(1=>2, 0=>0), + Dict(2=>2, 0=>0)] + end s = Set([1, 2, 3]) @test replace(x->maybe(2x, x>1), s) == Set([1, 4, 6]) - @test replace(x->maybe(2x, x>1), s, count=1) in [Set([1, 4, 3]), Set([1, 2, 6])] + for count = (1, 0x1, big(1)) + @test replace(x->maybe(2x, x>1), s, count=count) in [Set([1, 4, 3]), Set([1, 2, 6])] + end @test replace(s, 1=>4) == Set([2, 3, 4]) @test replace!(s, 1=>2) === s @test s == Set([2, 3]) + @test replace!(x->2x, s, count=0x1) in [Set([4, 3]), Set([2, 6])] - @test replace([1, 2], 1=>0, 2=>0, count=0) == [1, 2] # count=0 --> no replacements + for count = (0, 0x0, big(0)) + @test replace([1, 2], 1=>0, 2=>0, count=count) == [1, 2] # count=0 --> no replacements + end end # test collisions with AbstractSet/AbstractDict @test replace!(x->2x, Set([3, 6])) == Set([6, 12]) @test replace!(x->2x, Set([1:20;])) == Set([2:2:40;]) @test replace!(kv -> (2kv[1] => kv[2]), Dict(1=>2, 2=>4, 4=>8, 8=>16)) == Dict(2=>2, 4=>4, 8=>8, 16=>16) - # test Some(nothing) + # test Some(nothing) a = [1, 2, nothing, 4] @test replace(x -> x === nothing ? 0 : Some(nothing), a) == [nothing, nothing, 0, nothing] @test replace(x -> x === nothing ? 0 : nothing, a) == [1, 2, 0, 4] @@ -527,3 +545,40 @@ end # avoid recursive call issue #25384 @test_throws MethodError replace!("") end + +@testset "⊆, ⊊, ⊈, ⊇, ⊋, ⊉, <, <=, issetequal" begin + a = [1, 2] + b = [2, 1, 3] + for C = (Tuple, identity, Set, BitSet) + A = C(a) + B = C(b) + @test A ⊆ B + @test A ⊊ B + @test !(A ⊈ B) + @test !(A ⊇ B) + @test !(A ⊋ B) + @test A ⊉ B + @test !(B ⊆ A) + @test !(B ⊊ A) + @test B ⊈ A + @test B ⊇ A + @test B ⊋ A + @test !(B ⊉ A) + @test !issetequal(A, B) + @test !issetequal(B, A) + if A isa AbstractSet && B isa AbstractSet + @test A <= B + @test A < B + @test !(A >= B) + @test !(A > B) + @test !(B <= A) + @test !(B < A) + @test B >= A + @test B > A + end + for D = (Tuple, identity, Set, BitSet) + @test issetequal(A, D(A)) + @test !issetequal(A, D(B)) + end + end +end diff --git a/test/show.jl b/test/show.jl index b852e512f0afe..48ec3c9f57245 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using SparseArrays + # For curmod_* include("testenv.jl") @@ -586,8 +588,8 @@ end # This fits on screen: @test replstr(Matrix(1.0I, 10, 10)) == "10×10 Array{Float64,2}:\n 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0" # an array too long vertically to fit on screen, and too long horizontally: -@test replstr(collect(1.:100.)) == "100-element Array{Float64,1}:\n 1.0\n 2.0\n 3.0\n 4.0\n 5.0\n 6.0\n 7.0\n 8.0\n 9.0\n 10.0\n ⋮ \n 92.0\n 93.0\n 94.0\n 95.0\n 96.0\n 97.0\n 98.0\n 99.0\n 100.0" -@test replstr(collect(1.:100.)') == "1×100 Adjoint{Float64,Array{Float64,1}}:\n 1.0 2.0 3.0 4.0 5.0 6.0 7.0 … 95.0 96.0 97.0 98.0 99.0 100.0" +@test replstr(Vector(1.:100.)) == "100-element Array{Float64,1}:\n 1.0\n 2.0\n 3.0\n 4.0\n 5.0\n 6.0\n 7.0\n 8.0\n 9.0\n 10.0\n ⋮ \n 92.0\n 93.0\n 94.0\n 95.0\n 96.0\n 97.0\n 98.0\n 99.0\n 100.0" +@test replstr(Vector(1.:100.)') == "1×100 Adjoint{Float64,Array{Float64,1}}:\n 1.0 2.0 3.0 4.0 5.0 6.0 7.0 … 95.0 96.0 97.0 98.0 99.0 100.0" # too big in both directions to fit on screen: @test replstr((1.:100.)*(1:100)') == "100×100 Array{Float64,2}:\n 1.0 2.0 3.0 4.0 5.0 6.0 … 97.0 98.0 99.0 100.0\n 2.0 4.0 6.0 8.0 10.0 12.0 194.0 196.0 198.0 200.0\n 3.0 6.0 9.0 12.0 15.0 18.0 291.0 294.0 297.0 300.0\n 4.0 8.0 12.0 16.0 20.0 24.0 388.0 392.0 396.0 400.0\n 5.0 10.0 15.0 20.0 25.0 30.0 485.0 490.0 495.0 500.0\n 6.0 12.0 18.0 24.0 30.0 36.0 … 582.0 588.0 594.0 600.0\n 7.0 14.0 21.0 28.0 35.0 42.0 679.0 686.0 693.0 700.0\n 8.0 16.0 24.0 32.0 40.0 48.0 776.0 784.0 792.0 800.0\n 9.0 18.0 27.0 36.0 45.0 54.0 873.0 882.0 891.0 900.0\n 10.0 20.0 30.0 40.0 50.0 60.0 970.0 980.0 990.0 1000.0\n ⋮ ⋮ ⋱ \n 92.0 184.0 276.0 368.0 460.0 552.0 8924.0 9016.0 9108.0 9200.0\n 93.0 186.0 279.0 372.0 465.0 558.0 9021.0 9114.0 9207.0 9300.0\n 94.0 188.0 282.0 376.0 470.0 564.0 9118.0 9212.0 9306.0 9400.0\n 95.0 190.0 285.0 380.0 475.0 570.0 9215.0 9310.0 9405.0 9500.0\n 96.0 192.0 288.0 384.0 480.0 576.0 … 9312.0 9408.0 9504.0 9600.0\n 97.0 194.0 291.0 388.0 485.0 582.0 9409.0 9506.0 9603.0 9700.0\n 98.0 196.0 294.0 392.0 490.0 588.0 9506.0 9604.0 9702.0 9800.0\n 99.0 198.0 297.0 396.0 495.0 594.0 9603.0 9702.0 9801.0 9900.0\n 100.0 200.0 300.0 400.0 500.0 600.0 9700.0 9800.0 9900.0 10000.0" @@ -638,7 +640,7 @@ let A = reshape(1:16, 4, 4) @test replstr(Diagonal(A)) == "4×4 Diagonal{$(Int),Array{$(Int),1}}:\n 1 ⋅ ⋅ ⋅\n ⋅ 6 ⋅ ⋅\n ⋅ ⋅ 11 ⋅\n ⋅ ⋅ ⋅ 16" @test replstr(Bidiagonal(A, :U)) == "4×4 Bidiagonal{$(Int),Array{$(Int),1}}:\n 1 5 ⋅ ⋅\n ⋅ 6 10 ⋅\n ⋅ ⋅ 11 15\n ⋅ ⋅ ⋅ 16" @test replstr(Bidiagonal(A, :L)) == "4×4 Bidiagonal{$(Int),Array{$(Int),1}}:\n 1 ⋅ ⋅ ⋅\n 2 6 ⋅ ⋅\n ⋅ 7 11 ⋅\n ⋅ ⋅ 12 16" - @test replstr(SymTridiagonal(A + adjoint(A))) == "4×4 SymTridiagonal{$(Int),Array{$(Int),1}}:\n 2 7 ⋅ ⋅\n 7 12 17 ⋅\n ⋅ 17 22 27\n ⋅ ⋅ 27 32" + @test replstr(SymTridiagonal(A + A')) == "4×4 SymTridiagonal{$(Int),Array{$(Int),1}}:\n 2 7 ⋅ ⋅\n 7 12 17 ⋅\n ⋅ 17 22 27\n ⋅ ⋅ 27 32" @test replstr(Tridiagonal(diag(A, -1), diag(A), diag(A, +1))) == "4×4 Tridiagonal{$(Int),Array{$(Int),1}}:\n 1 5 ⋅ ⋅\n 2 6 10 ⋅\n ⋅ 7 11 15\n ⋅ ⋅ 12 16" @test replstr(UpperTriangular(copy(A))) == "4×4 UpperTriangular{$Int,Array{$Int,2}}:\n 1 5 9 13\n ⋅ 6 10 14\n ⋅ ⋅ 11 15\n ⋅ ⋅ ⋅ 16" @test replstr(LowerTriangular(copy(A))) == "4×4 LowerTriangular{$Int,Array{$Int,2}}:\n 1 ⋅ ⋅ ⋅\n 2 6 ⋅ ⋅\n 3 7 11 ⋅\n 4 8 12 16" @@ -1031,7 +1033,7 @@ let x = TypeVar(:_), y = TypeVar(:_) end @testset "showarg" begin - A = reshape(collect(Int16(1):Int16(2*3*5)), 2, 3, 5) + A = reshape(Vector(Int16(1):Int16(2*3*5)), 2, 3, 5) @test summary(A) == "2×3×5 Array{Int16,3}" v = view(A, :, 3, 2:5) @test summary(v) == "2×4 view(::Array{Int16,3}, :, 3, 2:5) with eltype Int16" diff --git a/test/simdloop.jl b/test/simdloop.jl index 4909101cc108d..72513a1311d3b 100644 --- a/test/simdloop.jl +++ b/test/simdloop.jl @@ -144,5 +144,5 @@ function simd_sum_over_array(a) end s end -@test 2001000 == simd_sum_over_array(collect(1:2000)) +@test 2001000 == simd_sum_over_array(Vector(1:2000)) @test 2001000 == simd_sum_over_array(Float32[i+j*500 for i=1:500, j=0:3]) diff --git a/test/socket.jl b/test/socket.jl index fddde93284e4b..63c459a3c3751 100644 --- a/test/socket.jl +++ b/test/socket.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + @testset "parsing" begin @test ip"127.0.0.1" == IPv4(127,0,0,1) @test ip"192.0" == IPv4(192,0,0,0) diff --git a/test/sorting.jl b/test/sorting.jl index 7d969627b0ca9..427a8c902b911 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base.Order: Forward +using Random @test sort([2,3,1]) == [1,2,3] @test sort([2,3,1], rev=true) == [3,2,1] @@ -20,7 +21,7 @@ end @test partialsort([3,6,30,1,9],3) == 6 @test partialsort([3,6,30,1,9],3:4) == [6,9] @test partialsortperm([3,6,30,1,9], 3:4) == [2,5] -@test partialsortperm!(collect(1:5), [3,6,30,1,9], 3:4) == [2,5] +@test partialsortperm!(Vector(1:5), [3,6,30,1,9], 3:4) == [2,5] let a=[1:10;] for r in Any[2:4, 1:2, 10:10, 4:2, 2:1, 4:-1:2, 2:-1:1, 10:-1:10, 4:1:3, 1:2:8, 10:-3:1] @test partialsort(a, r) == [r;] diff --git a/test/spawn.jl b/test/spawn.jl index dd33d032a7309..4921b2d0cb072 100644 --- a/test/spawn.jl +++ b/test/spawn.jl @@ -4,6 +4,8 @@ # Cross Platform tests for spawn. # ################################### +using Random + valgrind_off = ccall(:jl_running_on_valgrind, Cint, ()) == 0 yescmd = `yes` diff --git a/test/staged.jl b/test/staged.jl index 1c691d9e7db6f..dad910a1b3a5e 100644 --- a/test/staged.jl +++ b/test/staged.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base.Printf: @sprintf +using Random @generated function staged_t1(a,b) if a == Int @@ -140,7 +141,7 @@ end # @generated functions that throw (shouldn't segfault or throw) module TestGeneratedThrow - using Test + using Test, Random @generated function bar(x) error("I'm not happy with type $x") diff --git a/test/statistics.jl b/test/statistics.jl index 5b6154260fb2f..9c043967846d3 100644 --- a/test/statistics.jl +++ b/test/statistics.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random @testset "middle" begin @test middle(3) === 3.0 @@ -107,19 +107,19 @@ end @test var([1], 1; mean=[2], corrected=false) ≈ [1.0] @test var(1:8) == 6. - @test varm(1:8,1) == varm(collect(1:8),1) + @test varm(1:8,1) == varm(Vector(1:8),1) @test isnan(varm(1:1,1)) @test isnan(var(1:1)) @test isnan(var(1:-1)) @test @inferred(var(1.0:8.0)) == 6. - @test varm(1.0:8.0,1.0) == varm(collect(1.0:8.0),1) + @test varm(1.0:8.0,1.0) == varm(Vector(1.0:8.0),1) @test isnan(varm(1.0:1.0,1.0)) @test isnan(var(1.0:1.0)) @test isnan(var(1.0:-1.0)) @test @inferred(var(1.0f0:8.0f0)) === 6.f0 - @test varm(1.0f0:8.0f0,1.0f0) == varm(collect(1.0f0:8.0f0),1) + @test varm(1.0f0:8.0f0,1.0f0) == varm(Vector(1.0f0:8.0f0),1) @test isnan(varm(1.0f0:1.0f0,1.0f0)) @test isnan(var(1.0f0:1.0f0)) @test isnan(var(1.0f0:-1.0f0)) @@ -137,8 +137,8 @@ end @test var((1,2,3); mean=0, corrected=false) ≈ 14.0/3 @test_throws ArgumentError var((1,2,3); mean=()) - @test var([1 2 3 4 5; 6 7 8 9 10], 2) ≈ adjoint([2.5 2.5]) - @test var([1 2 3 4 5; 6 7 8 9 10], 2; corrected=false) ≈ adjoint([2.0 2.0]) + @test var([1 2 3 4 5; 6 7 8 9 10], 2) ≈ [2.5 2.5]' + @test var([1 2 3 4 5; 6 7 8 9 10], 2; corrected=false) ≈ [2.0 2.0]' @test stdm([1,2,3], 2) ≈ 1. @test std([1,2,3]) ≈ 1. @@ -152,8 +152,8 @@ end @test std((1,2,3); mean=0) ≈ sqrt(7.0) @test std((1,2,3); mean=0, corrected=false) ≈ sqrt(14.0/3) - @test std([1 2 3 4 5; 6 7 8 9 10], 2) ≈ sqrt.(adjoint([2.5 2.5])) - @test std([1 2 3 4 5; 6 7 8 9 10], 2; corrected=false) ≈ sqrt.(adjoint([2.0 2.0])) + @test std([1 2 3 4 5; 6 7 8 9 10], 2) ≈ sqrt.([2.5 2.5]') + @test std([1 2 3 4 5; 6 7 8 9 10], 2; corrected=false) ≈ sqrt.([2.0 2.0]') let A = ComplexF64[exp(i*im) for i in 1:10^4] @test varm(A, 0.) ≈ sum(map(abs2, A)) / (length(A) - 1) @@ -175,8 +175,16 @@ function safe_cov(x, y, zm::Bool, cr::Bool) end dot(vec(x), vec(y)) / (n - Int(cr)) end -X = adjoint([1. 2. 3. 4. 5.; 5. 4. 6. 2. 1.]) -Y = adjoint([6. 1. 5. 3. 2.; 2. 7. 8. 4. 3.]) +X = [1.0 5.0; + 2.0 4.0; + 3.0 6.0; + 4.0 2.0; + 5.0 1.0] +Y = [6.0 2.0; + 1.0 7.0; + 5.0 8.0; + 3.0 4.0; + 2.0 3.0] @testset "covariance" begin for vd in [1, 2], zm in [true, false], cr in [true, false] @@ -328,7 +336,7 @@ end @test cor(1:17, 1:17) <= 1.0 @test cor(1:17, 18:34) <= 1.0 let tmp = linspace(1, 85, 100) - tmp2 = collect(tmp) + tmp2 = Vector(tmp) @test cor(tmp, tmp) <= 1.0 @test cor(tmp, tmp2) <= 1.0 end @@ -338,9 +346,9 @@ end @test quantile([1,2,3,4],0.5) == 2.5 @test quantile([1,2,3,4],[0.5]) == [2.5] @test quantile([1., 3],[.25,.5,.75])[2] == median([1., 3]) - @test quantile(100.0:-1.0:0.0, 0.0:0.1:1.0) == collect(0.0:10.0:100.0) - @test quantile(0.0:100.0, 0.0:0.1:1.0, sorted=true) == collect(0.0:10.0:100.0) - @test quantile(100f0:-1f0:0.0, 0.0:0.1:1.0) == collect(0f0:10f0:100f0) + @test quantile(100.0:-1.0:0.0, 0.0:0.1:1.0) == 0.0:10.0:100.0 + @test quantile(0.0:100.0, 0.0:0.1:1.0, sorted=true) == 0.0:10.0:100.0 + @test quantile(100f0:-1f0:0.0, 0.0:0.1:1.0) == 0f0:10f0:100f0 @test quantile([Inf,Inf],0.5) == Inf @test quantile([-Inf,1],0.5) == -Inf @test quantile([0,1],1e-18) == 1e-18 @@ -417,7 +425,7 @@ isdefined(Main, :TestHelpers) || @eval Main include("TestHelpers.jl") using Main.TestHelpers: Furlong @testset "Unitful elements" begin r = Furlong(1):Furlong(1):Furlong(2) - a = collect(r) + a = Vector(r) @test sum(r) == sum(a) == Furlong(3) @test cumsum(r) == Furlong.([1,3]) @test mean(r) == mean(a) == median(a) == median(r) == Furlong(1.5) diff --git a/test/strings/basic.jl b/test/strings/basic.jl index aba06f60dd769..29ea38b3664f2 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + @testset "constructors" begin @test String([0x61,0x62,0x63,0x21]) == "abc!" @test String("abc!") == "abc!" @@ -233,7 +235,7 @@ end @test done(eachindex("foobar"),7) @test eltype(Base.EachStringIndex) == Int - @test map(Base.Unicode.uppercase, "foó") == "FOÓ" + @test map(uppercase, "foó") == "FOÓ" @test nextind("fóobar", 0, 3) == 4 @test Symbol(gstr) == Symbol("12") @@ -293,6 +295,8 @@ end @test tryparse(Float32, "32o") === nothing end +import Unicode + @testset "issue #10994: handle embedded NUL chars for string parsing" begin for T in [BigInt, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128] @test_throws ArgumentError parse(T, "1\0") @@ -300,7 +304,7 @@ end for T in [BigInt, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, Float64, Float32] @test tryparse(T, "1\0") === nothing end - let s = Base.Unicode.normalize("tést",:NFKC) + let s = Unicode.normalize("tést",:NFKC) @test unsafe_string(Base.unsafe_convert(Cstring, Base.cconvert(Cstring, s))) == s @test unsafe_string(Base.unsafe_convert(Cstring, Symbol(s))) == s end @@ -818,3 +822,8 @@ let v = unsafe_wrap(Vector{UInt8}, "abc") push!(v, UInt8('x')) @test s == "abc" end + +# PR #25535 +let v = [0x40,0x41,0x42] + @test String(view(v, 2:3)) == "AB" +end diff --git a/test/strings/io.jl b/test/strings/io.jl index 79476810c3329..28f7d9bdf5e4b 100644 --- a/test/strings/io.jl +++ b/test/strings/io.jl @@ -66,14 +66,14 @@ cp, ch, st = cx[i,:] @test cp == convert(UInt32, ch) @test string(ch) == unescape_string(st) - if isascii(ch) || !Base.Unicode.isprint(ch) + if isascii(ch) || !isprint(ch) @test st == escape_string(string(ch)) end for j = 1:size(cx,1) local str = string(ch, cx[j,2]) @test str == unescape_string(escape_string(str)) end - @test repr(ch) == "'$(Base.Unicode.isprint(ch) ? ch : st)'" + @test repr(ch) == "'$(isprint(ch) ? ch : st)'" end for i = 0:0x7f, p = ["","\0","x","xxx","\x7f","\uFF","\uFFF", diff --git a/test/strings/search.jl b/test/strings/search.jl index 8d499207589eb..a499c6d52b0aa 100644 --- a/test/strings/search.jl +++ b/test/strings/search.jl @@ -26,38 +26,38 @@ end for str in [astr, GenericString(astr)] @test_throws BoundsError findnext(equalto('z'), str, 0) @test_throws BoundsError findnext(equalto('∀'), str, 0) - @test findfirst(equalto('x'), str) == 0 - @test findfirst(equalto('\0'), str) == 0 - @test findfirst(equalto('\u80'), str) == 0 - @test findfirst(equalto('∀'), str) == 0 + @test findfirst(equalto('x'), str) == nothing + @test findfirst(equalto('\0'), str) == nothing + @test findfirst(equalto('\u80'), str) == nothing + @test findfirst(equalto('∀'), str) == nothing @test findfirst(equalto('H'), str) == 1 @test findfirst(equalto('l'), str) == 3 @test findnext(equalto('l'), str, 4) == 4 @test findnext(equalto('l'), str, 5) == 11 - @test findnext(equalto('l'), str, 12) == 0 + @test findnext(equalto('l'), str, 12) == nothing @test findfirst(equalto(','), str) == 6 - @test findnext(equalto(','), str, 7) == 0 + @test findnext(equalto(','), str, 7) == nothing @test findfirst(equalto('\n'), str) == 14 - @test findnext(equalto('\n'), str, 15) == 0 + @test findnext(equalto('\n'), str, 15) == nothing @test_throws BoundsError findnext(equalto('ε'), str, nextind(str,endof(str))+1) @test_throws BoundsError findnext(equalto('a'), str, nextind(str,endof(str))+1) end # ascii backward search for str in [astr] - @test findlast(equalto('x'), str) == 0 - @test findlast(equalto('\0'), str) == 0 - @test findlast(equalto('\u80'), str) == 0 - @test findlast(equalto('∀'), str) == 0 + @test findlast(equalto('x'), str) == nothing + @test findlast(equalto('\0'), str) == nothing + @test findlast(equalto('\u80'), str) == nothing + @test findlast(equalto('∀'), str) == nothing @test findlast(equalto('H'), str) == 1 - @test findprev(equalto('H'), str, 0) == 0 + @test findprev(equalto('H'), str, 0) == nothing @test findlast(equalto('l'), str) == 11 @test findprev(equalto('l'), str, 5) == 4 @test findprev(equalto('l'), str, 4) == 4 @test findprev(equalto('l'), str, 3) == 3 - @test findprev(equalto('l'), str, 2) == 0 + @test findprev(equalto('l'), str, 2) == nothing @test findlast(equalto(','), str) == 6 - @test findprev(equalto(','), str, 5) == 0 + @test findprev(equalto(','), str, 5) == nothing @test findlast(equalto('\n'), str) == 14 end @@ -65,53 +65,53 @@ end for str in (u8str, GenericString(u8str)) @test_throws BoundsError findnext(equalto('z'), str, 0) @test_throws BoundsError findnext(equalto('∀'), str, 0) - @test findfirst(equalto('z'), str) == 0 - @test findfirst(equalto('\0'), str) == 0 - @test findfirst(equalto('\u80'), str) == 0 - @test findfirst(equalto('∄'), str) == 0 + @test findfirst(equalto('z'), str) == nothing + @test findfirst(equalto('\0'), str) == nothing + @test findfirst(equalto('\u80'), str) == nothing + @test findfirst(equalto('∄'), str) == nothing @test findfirst(equalto('∀'), str) == 1 @test_throws StringIndexError findnext(equalto('∀'), str, 2) - @test findnext(equalto('∀'), str, 4) == 0 + @test findnext(equalto('∀'), str, 4) == nothing @test findfirst(equalto('∃'), str) == 13 @test_throws StringIndexError findnext(equalto('∃'), str, 15) - @test findnext(equalto('∃'), str, 16) == 0 + @test findnext(equalto('∃'), str, 16) == nothing @test findfirst(equalto('x'), str) == 26 @test findnext(equalto('x'), str, 27) == 43 - @test findnext(equalto('x'), str, 44) == 0 + @test findnext(equalto('x'), str, 44) == nothing @test findfirst(equalto('δ'), str) == 17 @test_throws StringIndexError findnext(equalto('δ'), str, 18) @test findnext(equalto('δ'), str, nextind(str,17)) == 33 - @test findnext(equalto('δ'), str, nextind(str,33)) == 0 + @test findnext(equalto('δ'), str, nextind(str,33)) == nothing @test findfirst(equalto('ε'), str) == 5 @test findnext(equalto('ε'), str, nextind(str,5)) == 54 - @test findnext(equalto('ε'), str, nextind(str,54)) == 0 - @test findnext(equalto('ε'), str, nextind(str,endof(str))) == 0 - @test findnext(equalto('a'), str, nextind(str,endof(str))) == 0 + @test findnext(equalto('ε'), str, nextind(str,54)) == nothing + @test findnext(equalto('ε'), str, nextind(str,endof(str))) == nothing + @test findnext(equalto('a'), str, nextind(str,endof(str))) == nothing @test_throws BoundsError findnext(equalto('ε'), str, nextind(str,endof(str))+1) @test_throws BoundsError findnext(equalto('a'), str, nextind(str,endof(str))+1) end # utf-8 backward search for str in [u8str] - @test findlast(equalto('z'), str) == 0 - @test findlast(equalto('\0'), str) == 0 - @test findlast(equalto('\u80'), str) == 0 - @test findlast(equalto('∄'), str) == 0 + @test findlast(equalto('z'), str) == nothing + @test findlast(equalto('\0'), str) == nothing + @test findlast(equalto('\u80'), str) == nothing + @test findlast(equalto('∄'), str) == nothing @test findlast(equalto('∀'), str) == 1 - @test findprev(equalto('∀'), str, 0) == 0 + @test findprev(equalto('∀'), str, 0) == nothing @test findlast(equalto('∃'), str) == 13 @test findprev(equalto('∃'), str, 14) == 13 @test findprev(equalto('∃'), str, 13) == 13 - @test findprev(equalto('∃'), str, 12) == 0 + @test findprev(equalto('∃'), str, 12) == nothing @test findlast(equalto('x'), str) == 43 @test findprev(equalto('x'), str, 42) == 26 - @test findprev(equalto('x'), str, 25) == 0 + @test findprev(equalto('x'), str, 25) == nothing @test findlast(equalto('δ'), str) == 33 @test findprev(equalto('δ'), str, 32) == 17 - @test findprev(equalto('δ'), str, 16) == 0 + @test findprev(equalto('δ'), str, 16) == nothing @test findlast(equalto('ε'), str) == 54 @test findprev(equalto('ε'), str, 53) == 5 - @test findprev(equalto('ε'), str, 4) == 0 + @test findprev(equalto('ε'), str, 4) == nothing end # string forward search with a single-char string @@ -324,3 +324,7 @@ end @test findnext(equalto('('), "(⨳(", 2) == 5 @test findlast(equalto('('), "(⨳(") == 5 @test findprev(equalto('('), "(⨳(", 2) == 1 + +@test @inferred find(equalto('a'), "éa") == [3] +@test @inferred find(equalto('€'), "€€") == [1, 4] +@test @inferred isempty(find(equalto('é'), "")) \ No newline at end of file diff --git a/test/strings/types.jl b/test/strings/types.jl index 0eefac0549c3c..48df6715da005 100644 --- a/test/strings/types.jl +++ b/test/strings/types.jl @@ -119,7 +119,7 @@ end let str = "Hello, world!" u = SubString(str, 1, 5) @test findlast("World", u) == 0:-1 - @test findlast(equalto('z'), u) == 0 + @test findlast(equalto('z'), u) == nothing @test findlast("ll", u) == 3:4 end diff --git a/test/strings/util.jl b/test/strings/util.jl index 97a417fe86e8c..3ac1eb7edbdd1 100644 --- a/test/strings/util.jl +++ b/test/strings/util.jl @@ -242,7 +242,7 @@ end @test replace("ḟøøƀäṙḟøø", r"(ḟø|ƀä)" => "xx") == "xxøxxṙxxø" @test replace("ḟøøƀäṙḟøø", r"(ḟøø|ƀä)" => "ƀäṙ") == "ƀäṙƀäṙṙƀäṙ" - @test replace("foo", "oo" => Base.Unicode.uppercase) == "fOO" + @test replace("foo", "oo" => uppercase) == "fOO" # Issue 13332 @test replace("abc", 'b' => 2.1) == "a2.1c" @@ -334,3 +334,12 @@ end @test_throws ArgumentError hex2bytes(b"0123456789abcdefABCDEFGH") end end + +# b"" should be immutable +let testb() = b"0123" + b = testb() + @test eltype(b) === UInt8 + @test b isa AbstractVector + @test_throws ErrorException b[4] = '4' + @test testb() == UInt8['0','1','2','3'] +end diff --git a/test/subarray.jl b/test/subarray.jl index b23a267fc80ec..211e6bd24563e 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random ######## Utilities ########### @@ -486,12 +486,12 @@ end # issue #15168 let A = rand(10), sA = view(copy(A), :) @test sA[Int16(1)] === sA[Int32(1)] === sA[Int64(1)] === A[1] - permute!(sA, collect(Int16, 1:10)) + permute!(sA, Vector{Int16}(1:10)) @test A == sA end # the following segfaults with LLVM 3.8 on Windows, ref #15417 -@test collect(view(view(reshape(1:13^3, 13, 13, 13), 3:7, 6:6, :), 1:2:5, :, 1:2:5)) == +@test Array(view(view(reshape(1:13^3, 13, 13, 13), 3:7, 6:6, :), 1:2:5, :, 1:2:5)) == cat(3,[68,70,72],[406,408,410],[744,746,748]) # tests @view (and replace_ref_end!) diff --git a/test/syntax.jl b/test/syntax.jl index f38711da81ea3..327a663e0eb32 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -2,6 +2,8 @@ # tests for parser and syntax lowering +using Random + import Base.Meta.ParseError function parseall(str) @@ -1246,3 +1248,9 @@ function f25055() return x end @test f25055() !== f25055() + +# issue #25391 +@test Meta.parse("0:-1, \"\"=>\"\"") == Meta.parse("(0:-1, \"\"=>\"\")") == + Expr(:tuple, Expr(:(:), 0, -1), Expr(:call, :(=>), "", "")) +@test Meta.parse("a => b = c") == Expr(:(=), Expr(:call, :(=>), :a, :b), Expr(:block, LineNumberNode(1, :none), :c)) +@test Meta.parse("a = b => c") == Expr(:(=), :a, Expr(:call, :(=>), :b, :c)) diff --git a/test/testdefs.jl b/test/testdefs.jl index c6af76df2b8c8..e040988651266 100644 --- a/test/testdefs.jl +++ b/test/testdefs.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Test +using Test, Random function runtests(name, path, isolate=true; seed=nothing) old_print_setting = Test.TESTSET_PRINT_ENABLE[] @@ -14,7 +14,7 @@ function runtests(name, path, isolate=true; seed=nothing) else m = Main end - @eval(m, using Test) + @eval(m, using Test, Random) ex = quote @timed @testset $"$name" begin # srand(nothing) will fail diff --git a/test/tuple.jl b/test/tuple.jl index 74becec9e6401..f7f5d0260da31 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -364,3 +364,10 @@ end @testset "issue 24707" begin @test eltype(Tuple{Vararg{T}} where T<:Integer) >: Integer end + +@testset "find" begin + @test @inferred find(equalto(1), (1, 2)) == [1] + @test @inferred find(equalto(1), (1, 1)) == [1, 2] + @test @inferred isempty(find(equalto(1), ())) + @test @inferred isempty(find(equalto(1), (2, 3))) +end \ No newline at end of file diff --git a/test/version.jl b/test/version.jl index e45639fe16c69..13d6309e15364 100644 --- a/test/version.jl +++ b/test/version.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Random + # parsing tests @test v"2" == VersionNumber(2) @test v"3.2" == VersionNumber(3, 2)