From 114bb9fcf798eadb7daeff9917c6f05bfcc2f360 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 17 Aug 2025 06:57:04 -0400 Subject: [PATCH 1/2] Move Statistics.jl to weak dependency extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Moved Statistics from deps to weakdeps in Project.toml - Created RecursiveArrayToolsStatisticsExt extension module - Moved Statistics-dependent functions to extension - Added Statistics to test dependencies This reduces the base dependency footprint while maintaining full functionality when Statistics is loaded. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- Project.toml | 6 ++++-- ext/RecursiveArrayToolsStatisticsExt.jl | 15 +++++++++++++++ src/RecursiveArrayTools.jl | 2 +- src/vector_of_array.jl | 8 -------- 4 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 ext/RecursiveArrayToolsStatisticsExt.jl diff --git a/Project.toml b/Project.toml index 8284bfe1..4f139a5e 100644 --- a/Project.toml +++ b/Project.toml @@ -11,7 +11,6 @@ GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" SymbolicIndexingInterface = "2efcf032-c050-4f8e-a9bb-153293bab1f5" [weakdeps] @@ -22,6 +21,7 @@ Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" @@ -35,6 +35,7 @@ RecursiveArrayToolsMeasurementsExt = "Measurements" RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] RecursiveArrayToolsSparseArraysExt = ["SparseArrays"] +RecursiveArrayToolsStatisticsExt = "Statistics" RecursiveArrayToolsStructArraysExt = "StructArrays" RecursiveArrayToolsTablesExt = ["Tables"] RecursiveArrayToolsTrackerExt = "Tracker" @@ -88,6 +89,7 @@ SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" @@ -95,4 +97,4 @@ Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [targets] -test = ["Aqua", "FastBroadcast", "ForwardDiff", "JET", "KernelAbstractions", "Measurements", "NLsolve", "Pkg", "Random", "SafeTestsets", "SciMLBase", "SparseArrays", "StaticArrays", "StructArrays", "Tables", "Test", "Unitful", "Zygote"] +test = ["Aqua", "FastBroadcast", "ForwardDiff", "JET", "KernelAbstractions", "Measurements", "NLsolve", "Pkg", "Random", "SafeTestsets", "SciMLBase", "SparseArrays", "StaticArrays", "Statistics", "StructArrays", "Tables", "Test", "Unitful", "Zygote"] diff --git a/ext/RecursiveArrayToolsStatisticsExt.jl b/ext/RecursiveArrayToolsStatisticsExt.jl new file mode 100644 index 00000000..abdfb73e --- /dev/null +++ b/ext/RecursiveArrayToolsStatisticsExt.jl @@ -0,0 +1,15 @@ +module RecursiveArrayToolsStatisticsExt + +using RecursiveArrayTools +using Statistics + +@inline Statistics.mean(VA::AbstractVectorOfArray; kwargs...) = mean(Array(VA); kwargs...) +@inline function Statistics.median(VA::AbstractVectorOfArray; kwargs...) + median(Array(VA); kwargs...) +end +@inline Statistics.std(VA::AbstractVectorOfArray; kwargs...) = std(Array(VA); kwargs...) +@inline Statistics.var(VA::AbstractVectorOfArray; kwargs...) = var(Array(VA); kwargs...) +@inline Statistics.cov(VA::AbstractVectorOfArray; kwargs...) = cov(Array(VA); kwargs...) +@inline Statistics.cor(VA::AbstractVectorOfArray; kwargs...) = cor(Array(VA); kwargs...) + +end \ No newline at end of file diff --git a/src/RecursiveArrayTools.jl b/src/RecursiveArrayTools.jl index 1f0b5b27..5815f112 100644 --- a/src/RecursiveArrayTools.jl +++ b/src/RecursiveArrayTools.jl @@ -5,7 +5,7 @@ $(DocStringExtensions.README) module RecursiveArrayTools using DocStringExtensions -using RecipesBase, StaticArraysCore, Statistics, +using RecipesBase, StaticArraysCore, ArrayInterface, LinearAlgebra using SymbolicIndexingInterface diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index 3824b946..fa65b973 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -1153,14 +1153,6 @@ end mapreduce(f, Base.mul_prod, VA; kwargs...) end -@inline Statistics.mean(VA::AbstractVectorOfArray; kwargs...) = mean(Array(VA); kwargs...) -@inline function Statistics.median(VA::AbstractVectorOfArray; kwargs...) - median(Array(VA); kwargs...) -end -@inline Statistics.std(VA::AbstractVectorOfArray; kwargs...) = std(Array(VA); kwargs...) -@inline Statistics.var(VA::AbstractVectorOfArray; kwargs...) = var(Array(VA); kwargs...) -@inline Statistics.cov(VA::AbstractVectorOfArray; kwargs...) = cov(Array(VA); kwargs...) -@inline Statistics.cor(VA::AbstractVectorOfArray; kwargs...) = cor(Array(VA); kwargs...) @inline Base.adjoint(VA::AbstractVectorOfArray) = Adjoint(VA) # linear algebra From 4185d2af33b42c417c1405aa8e222643471b9898 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Mon, 29 Dec 2025 09:10:45 -0500 Subject: [PATCH 2/2] Fix recursive_mean to work without Statistics dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The move of Statistics.jl to a weak dependency caused recursive_mean to fail because it used Statistics.mean internally. This fix: - Removes the generic fallback `recursive_mean(x...) = mean(x...)` from utils.jl - Adds explicit implementations for scalars and arrays of numbers that compute the mean without requiring Statistics - Rewrites recursive_mean(A::ArrayPartition) to avoid using Statistics.mean 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/array_partition.jl | 12 +++++++++++- src/utils.jl | 10 +++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/array_partition.jl b/src/array_partition.jl index 953011b9..7d1c88b6 100644 --- a/src/array_partition.jl +++ b/src/array_partition.jl @@ -342,7 +342,17 @@ function recursivecopy!(A::ArrayPartition{T, S}, return A end -recursive_mean(A::ArrayPartition) = mean((recursive_mean(x) for x in A.x)) +function recursive_mean(A::ArrayPartition) + n = npartitions(A) + if n == 0 + return zero(eltype(A)) + end + total = recursive_mean(A.x[1]) + for i in 2:n + total += recursive_mean(A.x[i]) + end + return total / n +end # note: consider only first partition for recursive one and eltype recursive_one(A::ArrayPartition) = recursive_one(first(A.x)) diff --git a/src/utils.jl b/src/utils.jl index b783eaf9..61fbafe4 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -293,7 +293,6 @@ end recursive_unitless_eltype(a::Type{T}) where {T <: Number} = typeof(one(eltype(a))) recursive_unitless_eltype(::Type{<:Enum{T}}) where {T} = T -recursive_mean(x...) = mean(x...) function recursive_mean(vecvec::Vector{T}) where {T <: AbstractArray} out = zero(vecvec[1]) for i in eachindex(vecvec) @@ -302,6 +301,15 @@ function recursive_mean(vecvec::Vector{T}) where {T <: AbstractArray} out / length(vecvec) end +# Fallback for scalars and general cases without Statistics +function recursive_mean(x::AbstractArray{T}) where {T <: Number} + sum(x) / length(x) +end + +function recursive_mean(x::Number) + x +end + # From Iterators.jl. Moved here since Iterators.jl is not precompile safe anymore. # Concatenate the output of n iterators