diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index 46bb83d5d0..0000000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Nightly -on: - pull_request: - -jobs: - test: - name: Julia nightly - ${{ matrix.group }} - ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macOS-latest, windows-latest] - group: - - 'test_manifolds' - - 'test_lie_groups' - steps: - - uses: actions/checkout@v4 - - uses: julia-actions/setup-julia@v1 - with: - version: nightly - arch: x64 - - uses: julia-actions/cache@v1 - - uses: julia-actions/julia-buildpkg@latest - - uses: julia-actions/julia-runtest@latest - env: - PYTHON: "" - MANIFOLDS_TEST_GROUP: ${{ matrix.group }} diff --git a/Project.toml b/Project.toml index 62fb80d976..5864e20d00 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Manifolds" uuid = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e" authors = ["Seth Axen ", "Mateusz Baran ", "Ronny Bergmann ", "Antoine Levitt "] -version = "0.8.77" +version = "0.8.79" [deps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" @@ -51,7 +51,7 @@ Graphs = "1.4" HybridArrays = "0.4" Kronecker = "0.4, 0.5" ManifoldDiff = "0.3.6" -ManifoldsBase = "0.14.11" +ManifoldsBase = "0.14.12" MatrixEquations = "2.2" OrdinaryDiffEq = "6.31" Plots = "1" diff --git a/docs/Project.toml b/docs/Project.toml index 31f1febab2..c051de4de2 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -24,7 +24,8 @@ BoundaryValueDiffEq = "4" CondaPkg = "0.2" DiffEqCallbacks = "2" Distributions = "0.22.6, 0.23, 0.24, 0.25" -Documenter = "0.27" +Documenter = "1" +DocumenterCitations = "1.2.1" FiniteDifferences = "0.12" Graphs = "1.4" HybridArrays = "0.4" diff --git a/docs/make.jl b/docs/make.jl index 9ab2b04778..cdd8d0f344 100755 --- a/docs/make.jl +++ b/docs/make.jl @@ -63,10 +63,12 @@ end # (e) ...finally! make docs bib = CitationBibliography(joinpath(@__DIR__, "src", "references.bib"); style=:alpha) -makedocs( - bib; +makedocs(; # for development, we disable prettyurls - format=Documenter.HTML(prettyurls=false, assets=["assets/favicon.ico"]), + format=Documenter.HTML( + prettyurls=false, + assets=["assets/favicon.ico", "assets/citations.css"], + ), modules=[ Manifolds, isdefined(Base, :get_extension) ? @@ -165,5 +167,7 @@ makedocs( "References" => "misc/references.md", ], ], + plugins=[bib], + warnonly=[:missing_docs], ) deploydocs(repo="github.com/JuliaManifolds/Manifolds.jl.git", push_preview=true) diff --git a/docs/src/assets/citations.css b/docs/src/assets/citations.css new file mode 100644 index 0000000000..5ea611881e --- /dev/null +++ b/docs/src/assets/citations.css @@ -0,0 +1,19 @@ +/* Taken from https://juliadocs.org/DocumenterCitations.jl/v1.2/styling/ */ + +.citation dl { + display: grid; + grid-template-columns: max-content auto; } +.citation dt { + grid-column-start: 1; } +.citation dd { + grid-column-start: 2; + margin-bottom: 0.75em; } +.citation ul { + padding: 0 0 2.25em 0; + margin: 0; + list-style: none;} +.citation ul li { + text-indent: -2.25em; + margin: 0.33em 0.5em 0.5em 2.25em;} +.citation ol li { + padding-left:0.75em;} diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 4b19ff6ff3..12f57674fb 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -127,6 +127,17 @@ function allocate_result( # vals are p and X, so we can use their fields to set up those of the UMVTVector return UMVTVector(allocate(p.U, m, k), allocate(p.S, k, k), allocate(p.Vt, k, n)) end +function allocate_result(::FixedRankMatrices{m,n,k}, ::typeof(rand), p) where {m,n,k} + # vals are p and X, so we can use their fields to set up those of the UMVTVector + return UMVTVector(allocate(p.U, m, k), allocate(p.S, k, k), allocate(p.Vt, k, n)) +end +function allocate_result(::FixedRankMatrices{m,n,k}, ::typeof(rand)) where {m,n,k} + return SVDMPoint( + Matrix{Float64}(undef, m, k), + Vector{Float64}(undef, k), + Matrix{Float64}(undef, k, n), + ) +end Base.copy(v::UMVTVector) = UMVTVector(copy(v.U), copy(v.M), copy(v.Vt)) @@ -448,32 +459,7 @@ and the singular values are sampled uniformly at random. If `vector_at` is not `nothing`, generate a random tangent vector in the tangent space of the point `vector_at` on the `FixedRankMatrices` manifold `M`. """ -function Random.rand(M::FixedRankMatrices; vector_at=nothing, kwargs...) - return rand(Random.default_rng(), M; vector_at=vector_at, kwargs...) -end -function Random.rand( - rng::AbstractRNG, - M::FixedRankMatrices{m,n,k}; - vector_at=nothing, - kwargs..., -) where {m,n,k} - if vector_at === nothing - p = SVDMPoint( - Matrix{Float64}(undef, m, k), - Vector{Float64}(undef, k), - Matrix{Float64}(undef, k, n), - ) - return rand!(rng, M, p; kwargs...) - else - X = UMVTVector( - Matrix{Float64}(undef, m, k), - Matrix{Float64}(undef, k, k), - Matrix{Float64}(undef, k, n), - ) - return rand!(rng, M, X; vector_at, kwargs...) - end -end - +Random.rand(M::FixedRankMatrices; vector_at=nothing, kwargs...) function Random.rand!( rng::AbstractRNG, ::FixedRankMatrices{m,n,k}, diff --git a/src/manifolds/GeneralUnitaryMatrices.jl b/src/manifolds/GeneralUnitaryMatrices.jl index 23c16724b7..9a09e1df95 100644 --- a/src/manifolds/GeneralUnitaryMatrices.jl +++ b/src/manifolds/GeneralUnitaryMatrices.jl @@ -889,7 +889,7 @@ end Compute volume density function of a sphere, i.e. determinant of the differential of exponential map `exp(M, p, X)`. It is derived from Eq. (4.1) and Corollary 4.4 -in [ChevallierLiLuDunson:2022](@ref). See also Theorem 4.1 in [FalorsideHaanDavidsonForre:2019](@cite), +in [ChevallierLiLuDunson:2022](@cite). See also Theorem 4.1 in [FalorsideHaanDavidsonForre:2019](@cite), (note that it uses a different convention). """ function volume_density(M::GeneralUnitaryMatrices{n,ℝ}, p, X) where {n} diff --git a/src/manifolds/PositiveNumbers.jl b/src/manifolds/PositiveNumbers.jl index da9ceadc73..81267c86a4 100644 --- a/src/manifolds/PositiveNumbers.jl +++ b/src/manifolds/PositiveNumbers.jl @@ -294,6 +294,19 @@ function parallel_transport_to!(::PositiveNumbers, Y, p, X, q) return (Y .= X .* q ./ p) end +function Random.rand(M::PositiveNumbers; kwargs...) + return rand(Random.default_rng(), M; kwargs...) +end + +function Random.rand(rng::AbstractRNG, ::PositiveNumbers; σ=1.0, vector_at=nothing) + if vector_at === nothing + pX = exp(randn(rng) * σ) + else + pX = vector_at * randn(rng) * σ + end + return pX +end + function Random.rand!( rng::AbstractRNG, ::PositiveNumbers, diff --git a/src/manifolds/SymmetricPositiveDefinite.jl b/src/manifolds/SymmetricPositiveDefinite.jl index 44e974741d..dd0beb3ebd 100644 --- a/src/manifolds/SymmetricPositiveDefinite.jl +++ b/src/manifolds/SymmetricPositiveDefinite.jl @@ -403,6 +403,10 @@ Generate a random symmetric positive definite matrix on the """ rand(M::SymmetricPositiveDefinite; σ::Real=1) +function allocate_result(M::SymmetricPositiveDefinite, ::typeof(Random.rand), p::SPDPoint) + return zero_vector(M, p) +end + function Random.rand!( rng::AbstractRNG, M::SymmetricPositiveDefinite{N}, diff --git a/src/manifolds/VectorBundle.jl b/src/manifolds/VectorBundle.jl index 64a0a993c6..91a245c0ca 100644 --- a/src/manifolds/VectorBundle.jl +++ b/src/manifolds/VectorBundle.jl @@ -292,6 +292,10 @@ See also [`VectorBundleInverseProductRetraction`](@ref). """ struct VectorBundleProductRetraction <: AbstractRetractionMethod end +function allocate_result(M::TangentSpaceAtPoint, ::typeof(rand)) + return zero_vector(M.fiber.manifold, M.point) +end + base_manifold(B::VectorBundleFibers) = base_manifold(B.manifold) base_manifold(B::VectorSpaceAtPoint) = base_manifold(B.fiber) base_manifold(B::VectorBundle) = base_manifold(B.manifold) diff --git a/test/manifolds/positive_numbers.jl b/test/manifolds/positive_numbers.jl index 6670b03f14..3aec6d5868 100644 --- a/test/manifolds/positive_numbers.jl +++ b/test/manifolds/positive_numbers.jl @@ -94,4 +94,12 @@ include("../utils.jl") @test volume_density(M, 0.5, 2.0) ≈ exp(4.0) @test volume_density(M5, [0.5, 1.0, 2.0], [1.0, -1.0, 2.0]) ≈ exp(2.0) end + @testset "Inplace random values" begin + p = fill(NaN) + X = fill(NaN) + rand!(M, p) + @test is_point(M, p) + rand!(M, X; vector_at=p) + @test is_vector(M, p, X) + end end