From b9b568de1b74666b7d24a2e41e9e65e5cd1d81ed Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Wed, 22 Nov 2017 14:20:39 -0800 Subject: [PATCH] Move iterative eigensolvers to the stdlib --- base/deprecated.jl | 3 ++ base/exports.jl | 2 - base/linalg/linalg.jl | 5 --- base/sparse/linalg.jl | 2 +- base/sysimg.jl | 2 +- doc/make.jl | 45 ++++++++++--------- doc/src/index.md | 1 + doc/src/stdlib/index.md | 1 + doc/src/stdlib/linalg.md | 3 -- .../IterativeEigenSolvers/docs/src/index.md | 7 +++ .../src/IterativeEigenSolvers.jl | 27 ++++++++--- .../IterativeEigenSolvers/src}/arpack.jl | 0 .../IterativeEigenSolvers/test/runtests.jl | 1 + test/choosetests.jl | 6 +-- test/compile.jl | 5 ++- test/show.jl | 4 +- 16 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 stdlib/IterativeEigenSolvers/docs/src/index.md rename base/linalg/arnoldi.jl => stdlib/IterativeEigenSolvers/src/IterativeEigenSolvers.jl (96%) rename {base/linalg => stdlib/IterativeEigenSolvers/src}/arpack.jl (100%) rename test/linalg/arnoldi.jl => stdlib/IterativeEigenSolvers/test/runtests.jl (99%) diff --git a/base/deprecated.jl b/base/deprecated.jl index 18e9ee6d93d41..4cab0e857b016 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1281,6 +1281,9 @@ export conv, conv2, deconv, filt, filt!, xcorr @eval @deprecate_moved $(Symbol("@dateformat_str")) "Dates" true true @deprecate_moved now "Dates" true true +@deprecate_moved eigs "IterativeEigenSolvers" true true +@deprecate_moved svds "IterativeEigenSolvers" true true + # PR #21709 @deprecate cov(x::AbstractVector, corrected::Bool) cov(x, corrected=corrected) @deprecate cov(x::AbstractMatrix, vardim::Int, corrected::Bool) cov(x, vardim, corrected=corrected) diff --git a/base/exports.jl b/base/exports.jl index 275fc68be1c17..d72f39ffc8f04 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -555,7 +555,6 @@ export eigfact, eigmax, eigmin, - eigs, eigvals, eigvals!, eigvecs, @@ -602,7 +601,6 @@ export svd, svdfact!, svdfact, - svds, svdvals!, svdvals, sylvester, diff --git a/base/linalg/linalg.jl b/base/linalg/linalg.jl index a46682c8f354e..ce75dd49c4fc7 100644 --- a/base/linalg/linalg.jl +++ b/base/linalg/linalg.jl @@ -83,7 +83,6 @@ export eigfact!, eigmax, eigmin, - eigs, eigvals, eigvals!, eigvecs, @@ -131,7 +130,6 @@ export svd, svdfact!, svdfact, - svds, svdvals!, svdvals, sylvester, @@ -277,9 +275,6 @@ include("ldlt.jl") include("schur.jl") -include("arpack.jl") -include("arnoldi.jl") - function __init__() try BLAS.check() diff --git a/base/sparse/linalg.jl b/base/sparse/linalg.jl index dc2e8089dbf82..388a8f63f4922 100644 --- a/base/sparse/linalg.jl +++ b/base/sparse/linalg.jl @@ -951,7 +951,7 @@ end chol(A::SparseMatrixCSC) = error("Use cholfact() instead of chol() for sparse matrices.") lu(A::SparseMatrixCSC) = error("Use lufact() instead of lu() for sparse matrices.") -eig(A::SparseMatrixCSC) = error("Use eigs() instead of eig() for sparse matrices.") +eig(A::SparseMatrixCSC) = error("Use IterativeEigenSolvers.eigs() instead of eig() for sparse matrices.") function Base.cov(X::SparseMatrixCSC, vardim::Int=1; corrected::Bool=true) a, b = size(X) diff --git a/base/sysimg.jl b/base/sysimg.jl index c3903d93a807b..e0000f60b2e5f 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -490,13 +490,13 @@ Base.require(:CRC32c) Base.require(:Dates) Base.require(:DelimitedFiles) Base.require(:FileWatching) +Base.require(:IterativeEigenSolvers) Base.require(:Mmap) Base.require(:Profile) Base.require(:SharedArrays) Base.require(:SuiteSparse) Base.require(:Test) - empty!(LOAD_PATH) Base.isfile("userimg.jl") && Base.include(Main, "userimg.jl") diff --git a/doc/make.jl b/doc/make.jl index bd02e1b0e59c1..894603566394a 100644 --- a/doc/make.jl +++ b/doc/make.jl @@ -21,25 +21,27 @@ 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/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") 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/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") end const PAGES = [ @@ -114,6 +116,7 @@ const PAGES = [ "stdlib/sharedarrays.md", "stdlib/filewatching.md", "stdlib/crc32c.md", + "stdlib/iterativeeigensolvers.md", ], "Developer Documentation" => [ "devdocs/reflection.md", @@ -148,11 +151,13 @@ const PAGES = [ ], ] -using DelimitedFiles, Test, Mmap, SharedArrays, Profile, Base64, FileWatching, CRC32c, Dates +using DelimitedFiles, Test, Mmap, SharedArrays, Profile, Base64, FileWatching, CRC32c, + Dates, IterativeEigenSolvers makedocs( build = joinpath(pwd(), "_build/html/en"), - modules = [Base, Core, BuildSysImg, DelimitedFiles, Test, Mmap, SharedArrays, Profile, Base64, FileWatching, Dates], + modules = [Base, Core, BuildSysImg, DelimitedFiles, Test, Mmap, SharedArrays, Profile, + Base64, FileWatching, Dates, IterativeEigenSolvers], clean = false, doctest = "doctest" in ARGS, linkcheck = "linkcheck" in ARGS, diff --git a/doc/src/index.md b/doc/src/index.md index 2c7fa3ae8c0dd..abb6f6ec9eb49 100644 --- a/doc/src/index.md +++ b/doc/src/index.md @@ -71,6 +71,7 @@ * [Shared Arrays](@ref) * [Base64](@ref) * [File Events](@ref lib-filewatching) + * [Iterative Eigensolvers](@ref lib-itereigen) ## Developer Documentation diff --git a/doc/src/stdlib/index.md b/doc/src/stdlib/index.md index be772c5f695e9..5b7ef9bd20adc 100644 --- a/doc/src/stdlib/index.md +++ b/doc/src/stdlib/index.md @@ -29,3 +29,4 @@ * [Shared Arrays](@ref) * [Base64](@ref) * [File Events](@ref lib-filewatching) + * [Iterative Eigensolvers](@ref lib-itereigen) diff --git a/doc/src/stdlib/linalg.md b/doc/src/stdlib/linalg.md index cb2aa8236a566..b8c9fb13b8aec 100644 --- a/doc/src/stdlib/linalg.md +++ b/doc/src/stdlib/linalg.md @@ -136,9 +136,6 @@ Base.transpose Base.transpose! Base.adjoint Base.adjoint! -Base.LinAlg.eigs(::Any) -Base.LinAlg.eigs(::Any, ::Any) -Base.LinAlg.svds Base.LinAlg.peakflops Base.LinAlg.stride1 ``` diff --git a/stdlib/IterativeEigenSolvers/docs/src/index.md b/stdlib/IterativeEigenSolvers/docs/src/index.md new file mode 100644 index 0000000000000..ea5c50cef0a55 --- /dev/null +++ b/stdlib/IterativeEigenSolvers/docs/src/index.md @@ -0,0 +1,7 @@ +# [Iterative Eigensolvers](@id lib-itereigen) + +```@docs +IterativeEigenSolvers.eigs(::Any) +IterativeEigenSolvers.eigs(::Any, ::Any) +IterativeEigenSolvers.svds +``` diff --git a/base/linalg/arnoldi.jl b/stdlib/IterativeEigenSolvers/src/IterativeEigenSolvers.jl similarity index 96% rename from base/linalg/arnoldi.jl rename to stdlib/IterativeEigenSolvers/src/IterativeEigenSolvers.jl index 636d2fc2ce4fa..d5e62c2e42da3 100644 --- a/base/linalg/arnoldi.jl +++ b/stdlib/IterativeEigenSolvers/src/IterativeEigenSolvers.jl @@ -1,5 +1,18 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +__precompile__(true) + +""" +Arnoldi and Lanczos iteration for computing eigenvalues +""" +module IterativeEigenSolvers + +using Base.LinAlg: BlasFloat, BlasInt, SVD, checksquare + +export eigs, svds + +include("arpack.jl") + using .ARPACK ## eigs @@ -308,14 +321,14 @@ function SVDAugmented(A::AbstractMatrix{T}) where T SVDAugmented{Tnew,typeof(Anew)}(Anew) end -function A_mul_B!(y::StridedVector{T}, A::SVDAugmented{T}, x::StridedVector{T}) where T +function Base.A_mul_B!(y::StridedVector{T}, A::SVDAugmented{T}, x::StridedVector{T}) where T m, mn = size(A.X, 1), length(x) A_mul_B!( view(y, 1:m), A.X, view(x, m + 1:mn)) # left singular vector Ac_mul_B!(view(y, m + 1:mn), A.X, view(x, 1:m)) # right singular vector return y end -size(A::SVDAugmented) = ((+)(size(A.X)...), (+)(size(A.X)...)) -ishermitian(A::SVDAugmented) = true +Base.size(A::SVDAugmented) = ((+)(size(A.X)...), (+)(size(A.X)...)) +Base.ishermitian(A::SVDAugmented) = true struct AtA_or_AAt{T,S} <: AbstractArray{T, 2} A::S @@ -328,7 +341,7 @@ function AtA_or_AAt(A::AbstractMatrix{T}) where T AtA_or_AAt{Tnew,typeof(Anew)}(Anew, Vector{Tnew}(uninitialized, max(size(A)...))) end -function A_mul_B!(y::StridedVector{T}, A::AtA_or_AAt{T}, x::StridedVector{T}) where T +function Base.A_mul_B!(y::StridedVector{T}, A::AtA_or_AAt{T}, x::StridedVector{T}) where T if size(A.A, 1) >= size(A.A, 2) A_mul_B!(A.buffer, A.A, x) return Ac_mul_B!(y, A.A, A.buffer) @@ -337,8 +350,8 @@ function A_mul_B!(y::StridedVector{T}, A::AtA_or_AAt{T}, x::StridedVector{T}) wh return A_mul_B!(y, A.A, A.buffer) end end -size(A::AtA_or_AAt) = ntuple(i -> min(size(A.A)...), Val(2)) -ishermitian(s::AtA_or_AAt) = true +Base.size(A::AtA_or_AAt) = ntuple(i -> min(size(A.A)...), Val(2)) +Base.ishermitian(s::AtA_or_AAt) = true svds(A::AbstractMatrix{<:BlasFloat}; kwargs...) = _svds(A; kwargs...) @@ -433,3 +446,5 @@ function _svds(X; nsv::Int = 6, ritzvec::Bool = true, tol::Float64 = 0.0, maxite ex[2], ex[3], ex[4], ex[5]) end end + +end # module diff --git a/base/linalg/arpack.jl b/stdlib/IterativeEigenSolvers/src/arpack.jl similarity index 100% rename from base/linalg/arpack.jl rename to stdlib/IterativeEigenSolvers/src/arpack.jl diff --git a/test/linalg/arnoldi.jl b/stdlib/IterativeEigenSolvers/test/runtests.jl similarity index 99% rename from test/linalg/arnoldi.jl rename to stdlib/IterativeEigenSolvers/test/runtests.jl index 6678e1e3bdcdb..9c56af6a26b52 100644 --- a/test/linalg/arnoldi.jl +++ b/stdlib/IterativeEigenSolvers/test/runtests.jl @@ -1,5 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using IterativeEigenSolvers using Test @testset "eigs" begin diff --git a/test/choosetests.jl b/test/choosetests.jl index d514e83dd4780..dd76d15ee2406 100644 --- a/test/choosetests.jl +++ b/test/choosetests.jl @@ -127,9 +127,6 @@ function choosetests(choices = []) "linalg/generic", "linalg/uniformscaling", "linalg/lq", "linalg/hessenberg", "linalg/rowvector", "linalg/conjarray", "linalg/blas"] - if Base.USE_GPL_LIBS - push!(linalgtests, "linalg/arnoldi") - end if "linalg" in skip_tests filter!(x -> (x != "linalg" && !(x in linalgtests)), tests) @@ -179,6 +176,9 @@ function choosetests(choices = []) filter!(x -> (x != "Profile"), tests) end + # The shift and invert solvers need SuiteSparse for sparse input + Base.USE_GPL_LIBS || filter!(x->x != "IterativeEigenSolvers", STDLIBS) + filter!(x -> !(x in skip_tests), tests) tests, net_on, exit_on_error, seed diff --git a/test/compile.jl b/test/compile.jl index 0a78df05b63cc..0f6c97801bf07 100644 --- a/test/compile.jl +++ b/test/compile.jl @@ -218,8 +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, :Mmap, - :Profile, :SharedArrays, :SuiteSparse, :Test])) + [:Base64, :CRC32c, :Dates, :DelimitedFiles, :FileWatching, + :IterativeEigenSolvers, :Mmap, :Profile, :SharedArrays, + :SuiteSparse, :Test])) @test discard_module.(deps) == deps1 @test current_task()(0x01, 0x4000, 0x30031234) == 2 diff --git a/test/show.jl b/test/show.jl index 0dc90782e99f3..9014380315b28 100644 --- a/test/show.jl +++ b/test/show.jl @@ -535,9 +535,9 @@ let repr = sprint(show, "text/html", methods(f16580)) end if isempty(Base.GIT_VERSION_INFO.commit) - @test contains(Base.url(first(methods(eigs))),"https://github.com/JuliaLang/julia/tree/v$VERSION/base/linalg/arnoldi.jl#L") + @test contains(Base.url(first(methods(sin))),"https://github.com/JuliaLang/julia/tree/v$VERSION/base/mpfr.jl#L") else - @test contains(Base.url(first(methods(eigs))),"https://github.com/JuliaLang/julia/tree/$(Base.GIT_VERSION_INFO.commit)/base/linalg/arnoldi.jl#L") + @test contains(Base.url(first(methods(sin))),"https://github.com/JuliaLang/julia/tree/$(Base.GIT_VERSION_INFO.commit)/base/mpfr.jl#L") end # print_matrix should be able to handle small and large objects easily, test by