From 99a8d96b3b05e59bca085e0b8d6964aa9b04bfe3 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 16:44:47 -0300 Subject: [PATCH 01/28] implement copy for noise types --- src/types.jl | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/types.jl b/src/types.jl index 9823aaf..e464209 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1,5 +1,12 @@ isinplace(W::AbstractNoiseProcess{T, N, S, inplace}) where {T, N, S, inplace} = inplace +function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} + for x in fieldnames(typeof(W)) + setfield!(Wnew, x, deepcopy(getfield(W, x))) + end + Wnew +end + """ ```julia mutable struct NoiseProcess{T,N,Tt,T2,T3,ZType,F,F2,inplace,S1,S2,RSWM,C,RNGType} <: {T,N,Vector{T2},inplace} @@ -233,6 +240,52 @@ function NoiseProcess(t0, W0, Z0, dist, bridge; kwargs...) NoiseProcess{iip}(t0, W0, Z0, dist, bridge; kwargs...) end +#??? rswm::RSWM +#??? cache::C + +function Base.copy!(Wnew::T, W::T) where {T <: NoiseProcess} + for x in (:dist, :bridge, :curt, :dt, :maxstacksize, :maxstacksize2, :save_everystep, + :iter, :reset, :reseed, :continuous) + setfield!(Wnew, x, getfield(W, x)) + end + for x in (:t, :curW, :dW, :dWtilde, :dWtmp, :rng) + setfield!(Wnew, x, copy(getfield(W, x))) + end + if W.Z === nothing + Wnew.Z = nothing + Wnew.curZ = nothing + Wnew.dZ = nothing + Wnew.dZtilde = nothing + Wnew.dZtmp = nothing + else + Wnew.Z = recursivecopy(W.Z) + Wnew.curZ = copy(W.curZ) + Wnew.dZ = copy(W.dZ) + Wnew.dZtilde = copy(W.dZtilde) + Wnew.dZtmp = copy(W.dZtmp) + end + if W.cache === nothing + Wnew.cache = nothing + else + recursivecopy!(Wnew.cache, W.cache) + end + Wnew.W = recursivecopy(W.W) + Wnew.u = Wnew.W + Wnew.S₁.cur = W.S₁.cur + Wnew.S₁.numResets = W.S₁.numResets + Wnew.S₁.data = recursivecopy(W.S₁.data) + Wnew.S₂.cur = W.S₂.cur + Wnew.S₂.numResets = W.S₂.numResets + Wnew.S₂.data = recursivecopy(W.S₂.data) + Wnew.rswm = deepcopy(W.rswm) + Wnew +end + +function Base.copy(W::NoiseProcess) + Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) + copy!(Wnew, W) +end + """ ```julia mutable struct SimpleNoiseProcess{T,N,Tt,T2,T3,ZType,F,F2,inplace,RNGType} <: AbstractNoiseProcess{T,N,Vector{T2},inplace} @@ -595,6 +648,32 @@ function NoiseFunction(t0, W, Z = nothing; kwargs...) NoiseFunction{iip}(t0, W, Z; kwargs...) end +function Base.:(==)(W1::T, W2::T) where {T<:NoiseFunction} + all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(NoiseFunction)) +end + +function Base.copy!(Wnew::T, W::T) where {T <: NoiseFunction} + for x in (:W, :Z, :curt, :dt, :t0, :reset) + setfield!(Wnew, x, getfield(W, x)) + end + for x in (:curW, :dW) + setfield!(Wnew, x, copy(getfield(W, x))) + end + if W.Z === nothing + Wnew.curZ = nothing + Wnew.dZ = nothing + else + Wnew.curZ = copy(W.curZ) + Wnew.dZ = copy(W.dZ) + end + Wnew +end + +function Base.copy(W::NoiseFunction) + Wnew = NoiseFunction(W.t0, W.W, W.Z) + copy!(Wnew, W) +end + """ ```julia mutable struct NoiseTransport{T, N, wType, zType, Tt, T2, T3, TRV, Trv, RNGType, inplace} <: AbstractNoiseProcess{T, N, nothing, inplace} @@ -755,6 +834,28 @@ function NoiseTransport(t0, W, RV; rng = Xorshifts.Xoroshiro128Plus(rand(UInt64) NoiseTransport{iip}(t0, W, RV, rv, Z; rng, reset, reseed, kwargs...) end +function Base.copy!(Wnew::T, W::T) where {T <: NoiseTransport} + for x in (:W, :Z, :curt, :dt, :t0, :reset, :reseed) + setfield!(Wnew, x, getfield(W, x)) + end + for x in (:curW, :dW, :RV, :rv, :rng) + setfield!(Wnew, x, copy(getfield(W, x))) + end + if W.Z === nothing + Wnew.curZ = nothing + Wnew.dZ = nothing + else + Wnew.curZ = copy(W.curZ) + Wnew.dZ = copy(W.dZ) + end + Wnew +end + +function Base.copy(W::NoiseTransport) + Wnew = NoiseTransport(W.t0, W.W, copy(W.RV)) + copy!(Wnew, W) +end + """ A noise grid builds a noise process from arrays of points. For example, you can generate your desired noise process as an array `W` with timepoints `t`, From 3bdb70e420011ea2143a4b8352cdb960c5df1712 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 16:44:56 -0300 Subject: [PATCH 02/28] tests noise copy --- test/copy_noise_test.jl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 test/copy_noise_test.jl diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl new file mode 100644 index 0000000..b22adb2 --- /dev/null +++ b/test/copy_noise_test.jl @@ -0,0 +1,22 @@ +@testset "Copy Noises" begin + using DiffEqNoiseProcess + + for W in (WienerProcess(0.0, 0.0), + GeometricBrownianMotionProcess(0.5, 0.1, 0.0, + 1.0), + OrnsteinUhlenbeckProcess(1.0, 0.2, 1.3, 0.0, + 1.0), + BrownianBridge(0.0, 1.0, 0.0, 1.0)) + W2 = copy(W) + @test W2 == W + @test W2 !== W + @test W2.W === W2.u !== W.W === W.u + end + + for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), + NoiseGrid(0:0.01:1, sin.(0:0.01:1))) + W2 = copy(W) + @test W2 == W + @test W2 !== W + end +end From 6ebc2aa0e0020200058aa454fd690529bc2de677 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 18:28:29 -0300 Subject: [PATCH 03/28] copy some more noises --- src/types.jl | 88 ++++++++++++++++++++++++++++++++++++++++- test/copy_noise_test.jl | 9 ++++- 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/types.jl b/src/types.jl index e464209..0685d73 100644 --- a/src/types.jl +++ b/src/types.jl @@ -377,6 +377,37 @@ function SimpleNoiseProcess(t0, W0, Z0, dist, bridge; kwargs...) SimpleNoiseProcess{iip}(t0, W0, Z0, dist, bridge; kwargs...) end +function Base.copy!(Wnew::T, W::T) where {T <: SimpleNoiseProcess} + for x in (:dist, :bridge, :curt, :dt, :save_everystep, + :iter, :reset, :reseed) + setfield!(Wnew, x, getfield(W, x)) + end + for x in (:t, :curW, :dW, :dWtilde, :dWtmp, :rng) + setfield!(Wnew, x, copy(getfield(W, x))) + end + if W.Z === nothing + Wnew.Z = nothing + Wnew.curZ = nothing + Wnew.dZ = nothing + Wnew.dZtilde = nothing + Wnew.dZtmp = nothing + else + Wnew.Z = recursivecopy(W.Z) + Wnew.curZ = copy(W.curZ) + Wnew.dZ = copy(W.dZ) + Wnew.dZtilde = copy(W.dZtilde) + Wnew.dZtmp = copy(W.dZtmp) + end + Wnew.W = recursivecopy(W.W) + Wnew.u = Wnew.W + Wnew +end + +function Base.copy(W::SimpleNoiseProcess) + Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) + copy!(Wnew, W) +end + """ ```julia mutable struct NoiseWrapper{T,N,Tt,T2,T3,T4,ZType,inplace} <: AbstractNoiseProcess{T,N,Vector{T2},inplace} @@ -543,6 +574,33 @@ function (W::NoiseWrapper)(out1, out2, u, p, t) end adaptive_alg(W::NoiseWrapper) = adaptive_alg(W.source) +function Base.copy!(Wnew::T, W::T) where {T <: NoiseWrapper} + for x in (:curt, :dt, :reset, :reverse) + setfield!(Wnew, x, getfield(W, x)) + end + for x in (:t, :curW, :dW) + setfield!(Wnew, x, copy(getfield(W, x))) + end + if W.Z === nothing + Wnew.Z = nothing + Wnew.curZ = nothing + Wnew.dZ = nothing + else + Wnew.Z = recursivecopy(W.Z) + Wnew.curZ = copy(W.curZ) + Wnew.dZ = copy(W.dZ) + end + Wnew.W = recursivecopy(W.W) + Wnew.u = Wnew.W + copy!(Wnew.source, W.source) + Wnew +end + +function Base.copy(W::NoiseWrapper) + Wnew = NoiseWrapper(W.source) + copy!(Wnew, W) +end + """ ```julia mutable struct NoiseFunction{T,N,wType,zType,Tt,T2,T3,inplace} <: AbstractNoiseProcess{T,N,nothing,inplace} @@ -648,8 +706,8 @@ function NoiseFunction(t0, W, Z = nothing; kwargs...) NoiseFunction{iip}(t0, W, Z; kwargs...) end -function Base.:(==)(W1::T, W2::T) where {T<:NoiseFunction} - all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(NoiseFunction)) +function Base.:(==)(W1::T, W2::T) where {T<:AbstractNoiseProcess} + all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(typeof(W1))) end function Base.copy!(Wnew::T, W::T) where {T <: NoiseFunction} @@ -954,6 +1012,32 @@ end (W::NoiseGrid)(u, p, t) = interpolate!(W, t) (W::NoiseGrid)(out1, out2, u, p, t) = interpolate!(out1, out2, W, t) +function Base.copy!(Wnew::T, W::T) where {T <: NoiseGrid} + for x in (:curt, :dt, :step_setup, :reset) + setfield!(Wnew, x, getfield(W, x)) + end + for x in (:t, :curW, :dW) + setfield!(Wnew, x, copy(getfield(W, x))) + end + if W.Z === nothing + Wnew.Z = nothing + Wnew.curZ = nothing + Wnew.dZ = nothing + else + Wnew.Z = recursivecopy(W.Z) + Wnew.curZ = copy(W.curZ) + Wnew.dZ = copy(W.dZ) + end + Wnew.W = recursivecopy(W.W) + Wnew.u = Wnew.W + Wnew +end + +function Base.copy(W::NoiseGrid) + Wnew = NoiseGrid(W.t, W.W, W.Z) + copy!(Wnew, W) +end + """ In many cases, one would like to define a noise process directly by a stochastic differential equation which does not have an analytical solution. Of course, diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index b22adb2..f5dc754 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -1,7 +1,10 @@ @testset "Copy Noises" begin - using DiffEqNoiseProcess + using DiffEqNoiseProcess, DiffEqBase for W in (WienerProcess(0.0, 0.0), + SimpleWienerProcess(0.0, 0.0), + RealWienerProcess(0.0, 0.0), + CorrelatedWienerProcess([1.0 0.3; 0.3 1.0],0.0, 0.0), GeometricBrownianMotionProcess(0.5, 0.1, 0.0, 1.0), OrnsteinUhlenbeckProcess(1.0, 0.2, 1.3, 0.0, @@ -14,7 +17,9 @@ end for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), - NoiseGrid(0:0.01:1, sin.(0:0.01:1))) + NoiseGrid(0:0.01:1, sin.(0:0.01:1)), + NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)),dt=1/10)) + ) W2 = copy(W) @test W2 == W @test W2 !== W From 9385296f039ce7b98fbc11e020566a9454c32853 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 19:07:04 -0300 Subject: [PATCH 04/28] copy NoiseApproximation --- src/types.jl | 28 ++++++++++++++++++++++++++++ test/copy_noise_test.jl | 6 +++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index 0685d73..5f9a6b1 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1146,6 +1146,34 @@ end (W::NoiseApproximation)(u, p, t) = interpolate!(W, t) (W::NoiseApproximation)(out1, out2, u, p, t) = interpolate!(out1, out2, W, t) +function Base.copy!(Wnew::T, W::T) where {T <: NoiseApproximation} + for x in (:curt, :dt, :reset) + setfield!(Wnew, x, getfield(W, x)) + end + for x in (:t, :curW, :dW) + setfield!(Wnew, x, copy(getfield(W, x))) + end + if W.Z === nothing + Wnew.Z = nothing + Wnew.curZ = nothing + Wnew.dZ = nothing + else + Wnew.Z = recursivecopy(W.Z) + Wnew.curZ = copy(W.curZ) + Wnew.dZ = copy(W.dZ) + end + Wnew.W = recursivecopy(W.W) + Wnew.u = Wnew.W + Wnew.source1 = deepcopy(W.source1) + Wnew.source2 = deepcopy(W.source2) + Wnew +end + +function Base.copy(W::NoiseApproximation) + Wnew = NoiseApproximation(W.source1, W.source2) + copy!(Wnew, W) +end + """ A `VirtualBrownianTree` builds the noise process starting from an initial time `t0`, the first value of the proces `W0`, and (optionally) the first diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index f5dc754..b54751b 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -1,5 +1,5 @@ @testset "Copy Noises" begin - using DiffEqNoiseProcess, DiffEqBase + using DiffEqNoiseProcess, StochasticDiffEq for W in (WienerProcess(0.0, 0.0), SimpleWienerProcess(0.0, 0.0), @@ -24,4 +24,8 @@ @test W2 == W @test W2 !== W end + + W = NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)) + W2 = copy(W) + @test W2 !== W end From 5e55367365c77775bee9cd0a4487fe74474eef02 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 19:30:56 -0300 Subject: [PATCH 05/28] move noise equality to tests --- src/types.jl | 4 ---- test/copy_noise_test.jl | 9 +++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/types.jl b/src/types.jl index 5f9a6b1..93367ec 100644 --- a/src/types.jl +++ b/src/types.jl @@ -706,10 +706,6 @@ function NoiseFunction(t0, W, Z = nothing; kwargs...) NoiseFunction{iip}(t0, W, Z; kwargs...) end -function Base.:(==)(W1::T, W2::T) where {T<:AbstractNoiseProcess} - all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(typeof(W1))) -end - function Base.copy!(Wnew::T, W::T) where {T <: NoiseFunction} for x in (:W, :Z, :curt, :dt, :t0, :reset) setfield!(Wnew, x, getfield(W, x)) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index b54751b..ed1cd9b 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -1,6 +1,14 @@ @testset "Copy Noises" begin using DiffEqNoiseProcess, StochasticDiffEq + function Base.:(==)(W1::T, W2::T) where {T<:DiffEqNoiseProcess.AbstractNoiseProcess} + all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(typeof(W1))) + end + + function Base.:(==)(W1::T, W2::T) where {T<:DiffEqNoiseProcess.NoiseApproximation} + all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(typeof(W1)) if x ∉ (:source1,:source2)) + end + for W in (WienerProcess(0.0, 0.0), SimpleWienerProcess(0.0, 0.0), RealWienerProcess(0.0, 0.0), @@ -27,5 +35,6 @@ W = NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)) W2 = copy(W) + @test W2 == W @test W2 !== W end From 20d193c62963004da2509e5f92369f3f6b10c5e9 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 20:44:53 -0300 Subject: [PATCH 06/28] just one generic `copy!` for AbstractNoise --- src/types.jl | 272 ++++++++++++--------------------------------------- 1 file changed, 63 insertions(+), 209 deletions(-) diff --git a/src/types.jl b/src/types.jl index 93367ec..257b34a 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1,12 +1,5 @@ isinplace(W::AbstractNoiseProcess{T, N, S, inplace}) where {T, N, S, inplace} = inplace -function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} - for x in fieldnames(typeof(W)) - setfield!(Wnew, x, deepcopy(getfield(W, x))) - end - Wnew -end - """ ```julia mutable struct NoiseProcess{T,N,Tt,T2,T3,ZType,F,F2,inplace,S1,S2,RSWM,C,RNGType} <: {T,N,Vector{T2},inplace} @@ -240,52 +233,6 @@ function NoiseProcess(t0, W0, Z0, dist, bridge; kwargs...) NoiseProcess{iip}(t0, W0, Z0, dist, bridge; kwargs...) end -#??? rswm::RSWM -#??? cache::C - -function Base.copy!(Wnew::T, W::T) where {T <: NoiseProcess} - for x in (:dist, :bridge, :curt, :dt, :maxstacksize, :maxstacksize2, :save_everystep, - :iter, :reset, :reseed, :continuous) - setfield!(Wnew, x, getfield(W, x)) - end - for x in (:t, :curW, :dW, :dWtilde, :dWtmp, :rng) - setfield!(Wnew, x, copy(getfield(W, x))) - end - if W.Z === nothing - Wnew.Z = nothing - Wnew.curZ = nothing - Wnew.dZ = nothing - Wnew.dZtilde = nothing - Wnew.dZtmp = nothing - else - Wnew.Z = recursivecopy(W.Z) - Wnew.curZ = copy(W.curZ) - Wnew.dZ = copy(W.dZ) - Wnew.dZtilde = copy(W.dZtilde) - Wnew.dZtmp = copy(W.dZtmp) - end - if W.cache === nothing - Wnew.cache = nothing - else - recursivecopy!(Wnew.cache, W.cache) - end - Wnew.W = recursivecopy(W.W) - Wnew.u = Wnew.W - Wnew.S₁.cur = W.S₁.cur - Wnew.S₁.numResets = W.S₁.numResets - Wnew.S₁.data = recursivecopy(W.S₁.data) - Wnew.S₂.cur = W.S₂.cur - Wnew.S₂.numResets = W.S₂.numResets - Wnew.S₂.data = recursivecopy(W.S₂.data) - Wnew.rswm = deepcopy(W.rswm) - Wnew -end - -function Base.copy(W::NoiseProcess) - Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) - copy!(Wnew, W) -end - """ ```julia mutable struct SimpleNoiseProcess{T,N,Tt,T2,T3,ZType,F,F2,inplace,RNGType} <: AbstractNoiseProcess{T,N,Vector{T2},inplace} @@ -377,37 +324,6 @@ function SimpleNoiseProcess(t0, W0, Z0, dist, bridge; kwargs...) SimpleNoiseProcess{iip}(t0, W0, Z0, dist, bridge; kwargs...) end -function Base.copy!(Wnew::T, W::T) where {T <: SimpleNoiseProcess} - for x in (:dist, :bridge, :curt, :dt, :save_everystep, - :iter, :reset, :reseed) - setfield!(Wnew, x, getfield(W, x)) - end - for x in (:t, :curW, :dW, :dWtilde, :dWtmp, :rng) - setfield!(Wnew, x, copy(getfield(W, x))) - end - if W.Z === nothing - Wnew.Z = nothing - Wnew.curZ = nothing - Wnew.dZ = nothing - Wnew.dZtilde = nothing - Wnew.dZtmp = nothing - else - Wnew.Z = recursivecopy(W.Z) - Wnew.curZ = copy(W.curZ) - Wnew.dZ = copy(W.dZ) - Wnew.dZtilde = copy(W.dZtilde) - Wnew.dZtmp = copy(W.dZtmp) - end - Wnew.W = recursivecopy(W.W) - Wnew.u = Wnew.W - Wnew -end - -function Base.copy(W::SimpleNoiseProcess) - Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) - copy!(Wnew, W) -end - """ ```julia mutable struct NoiseWrapper{T,N,Tt,T2,T3,T4,ZType,inplace} <: AbstractNoiseProcess{T,N,Vector{T2},inplace} @@ -574,33 +490,6 @@ function (W::NoiseWrapper)(out1, out2, u, p, t) end adaptive_alg(W::NoiseWrapper) = adaptive_alg(W.source) -function Base.copy!(Wnew::T, W::T) where {T <: NoiseWrapper} - for x in (:curt, :dt, :reset, :reverse) - setfield!(Wnew, x, getfield(W, x)) - end - for x in (:t, :curW, :dW) - setfield!(Wnew, x, copy(getfield(W, x))) - end - if W.Z === nothing - Wnew.Z = nothing - Wnew.curZ = nothing - Wnew.dZ = nothing - else - Wnew.Z = recursivecopy(W.Z) - Wnew.curZ = copy(W.curZ) - Wnew.dZ = copy(W.dZ) - end - Wnew.W = recursivecopy(W.W) - Wnew.u = Wnew.W - copy!(Wnew.source, W.source) - Wnew -end - -function Base.copy(W::NoiseWrapper) - Wnew = NoiseWrapper(W.source) - copy!(Wnew, W) -end - """ ```julia mutable struct NoiseFunction{T,N,wType,zType,Tt,T2,T3,inplace} <: AbstractNoiseProcess{T,N,nothing,inplace} @@ -706,28 +595,6 @@ function NoiseFunction(t0, W, Z = nothing; kwargs...) NoiseFunction{iip}(t0, W, Z; kwargs...) end -function Base.copy!(Wnew::T, W::T) where {T <: NoiseFunction} - for x in (:W, :Z, :curt, :dt, :t0, :reset) - setfield!(Wnew, x, getfield(W, x)) - end - for x in (:curW, :dW) - setfield!(Wnew, x, copy(getfield(W, x))) - end - if W.Z === nothing - Wnew.curZ = nothing - Wnew.dZ = nothing - else - Wnew.curZ = copy(W.curZ) - Wnew.dZ = copy(W.dZ) - end - Wnew -end - -function Base.copy(W::NoiseFunction) - Wnew = NoiseFunction(W.t0, W.W, W.Z) - copy!(Wnew, W) -end - """ ```julia mutable struct NoiseTransport{T, N, wType, zType, Tt, T2, T3, TRV, Trv, RNGType, inplace} <: AbstractNoiseProcess{T, N, nothing, inplace} @@ -888,28 +755,6 @@ function NoiseTransport(t0, W, RV; rng = Xorshifts.Xoroshiro128Plus(rand(UInt64) NoiseTransport{iip}(t0, W, RV, rv, Z; rng, reset, reseed, kwargs...) end -function Base.copy!(Wnew::T, W::T) where {T <: NoiseTransport} - for x in (:W, :Z, :curt, :dt, :t0, :reset, :reseed) - setfield!(Wnew, x, getfield(W, x)) - end - for x in (:curW, :dW, :RV, :rv, :rng) - setfield!(Wnew, x, copy(getfield(W, x))) - end - if W.Z === nothing - Wnew.curZ = nothing - Wnew.dZ = nothing - else - Wnew.curZ = copy(W.curZ) - Wnew.dZ = copy(W.dZ) - end - Wnew -end - -function Base.copy(W::NoiseTransport) - Wnew = NoiseTransport(W.t0, W.W, copy(W.RV)) - copy!(Wnew, W) -end - """ A noise grid builds a noise process from arrays of points. For example, you can generate your desired noise process as an array `W` with timepoints `t`, @@ -1008,32 +853,6 @@ end (W::NoiseGrid)(u, p, t) = interpolate!(W, t) (W::NoiseGrid)(out1, out2, u, p, t) = interpolate!(out1, out2, W, t) -function Base.copy!(Wnew::T, W::T) where {T <: NoiseGrid} - for x in (:curt, :dt, :step_setup, :reset) - setfield!(Wnew, x, getfield(W, x)) - end - for x in (:t, :curW, :dW) - setfield!(Wnew, x, copy(getfield(W, x))) - end - if W.Z === nothing - Wnew.Z = nothing - Wnew.curZ = nothing - Wnew.dZ = nothing - else - Wnew.Z = recursivecopy(W.Z) - Wnew.curZ = copy(W.curZ) - Wnew.dZ = copy(W.dZ) - end - Wnew.W = recursivecopy(W.W) - Wnew.u = Wnew.W - Wnew -end - -function Base.copy(W::NoiseGrid) - Wnew = NoiseGrid(W.t, W.W, W.Z) - copy!(Wnew, W) -end - """ In many cases, one would like to define a noise process directly by a stochastic differential equation which does not have an analytical solution. Of course, @@ -1142,34 +961,6 @@ end (W::NoiseApproximation)(u, p, t) = interpolate!(W, t) (W::NoiseApproximation)(out1, out2, u, p, t) = interpolate!(out1, out2, W, t) -function Base.copy!(Wnew::T, W::T) where {T <: NoiseApproximation} - for x in (:curt, :dt, :reset) - setfield!(Wnew, x, getfield(W, x)) - end - for x in (:t, :curW, :dW) - setfield!(Wnew, x, copy(getfield(W, x))) - end - if W.Z === nothing - Wnew.Z = nothing - Wnew.curZ = nothing - Wnew.dZ = nothing - else - Wnew.Z = recursivecopy(W.Z) - Wnew.curZ = copy(W.curZ) - Wnew.dZ = copy(W.dZ) - end - Wnew.W = recursivecopy(W.W) - Wnew.u = Wnew.W - Wnew.source1 = deepcopy(W.source1) - Wnew.source2 = deepcopy(W.source2) - Wnew -end - -function Base.copy(W::NoiseApproximation) - Wnew = NoiseApproximation(W.source1, W.source2) - copy!(Wnew, W) -end - """ A `VirtualBrownianTree` builds the noise process starting from an initial time `t0`, the first value of the proces `W0`, and (optionally) the first @@ -1507,3 +1298,66 @@ function BoxWedgeTail!(t0, W0, Z0 = nothing, dist = INPLACE_WHITE_NOISE_DIST, bridge = INPLACE_WHITE_NOISE_BRIDGE; kwargs...) BoxWedgeTail{true}(t0, W0, Z0, dist, bridge; kwargs...) end + +function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} + for x in filter(!=(:u), fieldnames(typeof(W))) + if !ismutable(getfield(W, x)) + setfield!(Wnew, x, getfield(W, x)) + elseif getfield(W, x) isa AbstractNoiseProcess + copy!(getfield(Wnew, x), getfield(W, x)) + elseif getfield(W, x) isa AbstractArray + recursivecopy!(getfield(Wnew, x), getfield(W, x)) + elseif getfield(W, x) isa ResettableStacks.ResettableStack + setfield!(getfield(Wnew, x), :cur, getfield(W, x).cur) + setfield!(getfield(Wnew, x), :numResets, getfield(W, x).numResets) + setfield!(getfield(Wnew, x), :data, recursivecopy(getfield(W, x).data)) + elseif getfield(W, x) isa Random.AbstractRNG + setfield!(Wnew, x, copy(getfield(W, x))) + else + setfield!(Wnew, x, deepcopy(getfield(W, x))) + end + end + if hasfield(typeof(W), :u) + Wnew.u = Wnew.W + end + Wnew +end + +function Base.copy(W::NoiseProcess) + Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) + copy!(Wnew, W) +end + +function Base.copy(W::SimpleNoiseProcess) + Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseWrapper) + Wnew = NoiseWrapper(W.source) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseFunction) + Wnew = NoiseFunction(W.t0, W.W, W.Z) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseTransport) + Wnew = NoiseTransport(W.t0, W.W, copy(W.RV)) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseGrid) + Wnew = NoiseGrid(W.t, W.W, W.Z) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseApproximation) + Wnew = NoiseApproximation(W.source1, W.source2) + copy!(Wnew, W) +end + +#Wnew.S₁.cur = W.S₁.cur +#Wnew.S₁.numResets = W.S₁.numResets +#Wnew.S₁.data = recursivecopy(W.S₁.data) \ No newline at end of file From 1861b4095e8c72dab96bd9a45d9d18ee9679e124 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 20:46:48 -0300 Subject: [PATCH 07/28] move NoiseApproximations to list --- test/copy_noise_test.jl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index ed1cd9b..226ad51 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -26,15 +26,11 @@ for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), NoiseGrid(0:0.01:1, sin.(0:0.01:1)), - NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)),dt=1/10)) + NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)),dt=1/10)), + NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)) ) W2 = copy(W) @test W2 == W @test W2 !== W end - - W = NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)) - W2 = copy(W) - @test W2 == W - @test W2 !== W end From 5a2f33d83d218701a56bb54205f368f57f0d5616 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 20:47:22 -0300 Subject: [PATCH 08/28] cleaning up --- src/types.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/types.jl b/src/types.jl index 257b34a..27b6ff4 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1357,7 +1357,3 @@ function Base.copy(W::NoiseApproximation) Wnew = NoiseApproximation(W.source1, W.source2) copy!(Wnew, W) end - -#Wnew.S₁.cur = W.S₁.cur -#Wnew.S₁.numResets = W.S₁.numResets -#Wnew.S₁.data = recursivecopy(W.S₁.data) \ No newline at end of file From a27a2a70141fc3ec2e7d9d923294b7de75c5b29c Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 21:15:32 -0300 Subject: [PATCH 09/28] add remaining types --- src/types.jl | 12 ++++++++++++ test/copy_noise_test.jl | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index 27b6ff4..29f4e61 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1305,6 +1305,8 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} setfield!(Wnew, x, getfield(W, x)) elseif getfield(W, x) isa AbstractNoiseProcess copy!(getfield(Wnew, x), getfield(W, x)) + elseif getfield(W, x) isa AbstractArray{Nothing, N} where N + setfield!(Wnew, x, copy(getfield(W, x))) elseif getfield(W, x) isa AbstractArray recursivecopy!(getfield(Wnew, x), getfield(W, x)) elseif getfield(W, x) isa ResettableStacks.ResettableStack @@ -1357,3 +1359,13 @@ function Base.copy(W::NoiseApproximation) Wnew = NoiseApproximation(W.source1, W.source2) copy!(Wnew, W) end + +function Base.copy(W::VirtualBrownianTree) + Wnew = VirtualBrownianTree(W.curt, W.curW, W.curZ, W.dist, W.bridge) + copy!(Wnew, W) +end + +function Base.copy(W::BoxWedgeTail) + Wnew = BoxWedgeTail(W.curt, W.curW, W.curZ, W.dist, W.bridge) + copy!(Wnew, W) +end diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index 226ad51..7ee5fe7 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -27,7 +27,9 @@ for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), NoiseGrid(0:0.01:1, sin.(0:0.01:1)), NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)),dt=1/10)), - NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)) + NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)), + BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns), + VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5) ) W2 = copy(W) @test W2 == W From 5719dea4688f1d1329bb7e285f15facd1b72e1d9 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 22:47:52 -0300 Subject: [PATCH 10/28] comment out VBT copy test --- test/copy_noise_test.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index 7ee5fe7..65ed62f 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -28,8 +28,8 @@ NoiseGrid(0:0.01:1, sin.(0:0.01:1)), NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)),dt=1/10)), NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)), - BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns), - VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5) + #VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5), + BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns) ) W2 = copy(W) @test W2 == W From 4df2491b81d4be7c25cc593a8c5eecf8c6f33505 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 22:48:10 -0300 Subject: [PATCH 11/28] chg equality to approx --- test/extraction_test.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extraction_test.jl b/test/extraction_test.jl index 60490ef..89abf26 100644 --- a/test/extraction_test.jl +++ b/test/extraction_test.jl @@ -23,7 +23,7 @@ push!(tarray, t + dt) end @test length(_sol) == length(sol.W) == length(tarray) - @test _sol == sol + @test _sol ≈ sol (rtol = 0.01) Random.seed!(seed) W2 = WienerProcess!(0.0, [0.0], [0.0]) From afa42ba82cb05604ac86741849b553f23d14d89b Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Mon, 17 Oct 2022 22:48:17 -0300 Subject: [PATCH 12/28] add copy tests --- test/runtests.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/runtests.jl b/test/runtests.jl index 4ea6f0d..574276b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -9,6 +9,7 @@ using Test include("noise_wrapper.jl") include("noise_function.jl") include("noise_transport.jl") + include("copy_noise_test.jl") include("VBT_test.jl") include("noise_grid.jl") include("noise_approximation.jl") From dee5565aabe6ccedbd0d7815021139e4c731c4e6 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Tue, 18 Oct 2022 06:34:41 -0300 Subject: [PATCH 13/28] fix copy with array fields with different length --- src/types.jl | 2 +- test/copy_noise_test.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types.jl b/src/types.jl index 29f4e61..ed58cf5 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1308,7 +1308,7 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} elseif getfield(W, x) isa AbstractArray{Nothing, N} where N setfield!(Wnew, x, copy(getfield(W, x))) elseif getfield(W, x) isa AbstractArray - recursivecopy!(getfield(Wnew, x), getfield(W, x)) + setfield!(Wnew, x, recursivecopy(getfield(W, x))) elseif getfield(W, x) isa ResettableStacks.ResettableStack setfield!(getfield(Wnew, x), :cur, getfield(W, x).cur) setfield!(getfield(Wnew, x), :numResets, getfield(W, x).numResets) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index 65ed62f..b1cb758 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -1,4 +1,4 @@ -@testset "Copy Noises" begin +@testset "Copy Noise test" begin using DiffEqNoiseProcess, StochasticDiffEq function Base.:(==)(W1::T, W2::T) where {T<:DiffEqNoiseProcess.AbstractNoiseProcess} @@ -28,7 +28,7 @@ NoiseGrid(0:0.01:1, sin.(0:0.01:1)), NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)),dt=1/10)), NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)), - #VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5), + VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5), BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns) ) W2 = copy(W) From 1cd0cc820dd036e6ab4a1013ea57bffe72c2c251 Mon Sep 17 00:00:00 2001 From: "Ricardo M. S. Rosa" Date: Tue, 18 Oct 2022 13:43:31 -0300 Subject: [PATCH 14/28] sciml format --- src/types.jl | 2 +- test/copy_noise_test.jl | 18 ++++++++++-------- test/extraction_test.jl | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/types.jl b/src/types.jl index ed58cf5..b51472f 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1305,7 +1305,7 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} setfield!(Wnew, x, getfield(W, x)) elseif getfield(W, x) isa AbstractNoiseProcess copy!(getfield(Wnew, x), getfield(W, x)) - elseif getfield(W, x) isa AbstractArray{Nothing, N} where N + elseif getfield(W, x) isa AbstractArray{Nothing, N} where {N} setfield!(Wnew, x, copy(getfield(W, x))) elseif getfield(W, x) isa AbstractArray setfield!(Wnew, x, recursivecopy(getfield(W, x))) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index b1cb758..989a17a 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -1,18 +1,19 @@ @testset "Copy Noise test" begin using DiffEqNoiseProcess, StochasticDiffEq - function Base.:(==)(W1::T, W2::T) where {T<:DiffEqNoiseProcess.AbstractNoiseProcess} + function Base.:(==)(W1::T, W2::T) where {T <: DiffEqNoiseProcess.AbstractNoiseProcess} all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(typeof(W1))) end - function Base.:(==)(W1::T, W2::T) where {T<:DiffEqNoiseProcess.NoiseApproximation} - all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(typeof(W1)) if x ∉ (:source1,:source2)) + function Base.:(==)(W1::T, W2::T) where {T <: DiffEqNoiseProcess.NoiseApproximation} + all(getfield(W1, x) == getfield(W2, x) + for x in fieldnames(typeof(W1)) if x ∉ (:source1, :source2)) end for W in (WienerProcess(0.0, 0.0), SimpleWienerProcess(0.0, 0.0), RealWienerProcess(0.0, 0.0), - CorrelatedWienerProcess([1.0 0.3; 0.3 1.0],0.0, 0.0), + CorrelatedWienerProcess([1.0 0.3; 0.3 1.0], 0.0, 0.0), GeometricBrownianMotionProcess(0.5, 0.1, 0.0, 1.0), OrnsteinUhlenbeckProcess(1.0, 0.2, 1.3, 0.0, @@ -26,11 +27,12 @@ for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), NoiseGrid(0:0.01:1, sin.(0:0.01:1)), - NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)),dt=1/10)), - NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt=1/10)), + NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)), + dt = 1 / 10)), + NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, + (0.0, Inf)), EM(), dt = 1 / 10)), VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5), - BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns) - ) + BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns)) W2 = copy(W) @test W2 == W @test W2 !== W diff --git a/test/extraction_test.jl b/test/extraction_test.jl index 89abf26..55de93e 100644 --- a/test/extraction_test.jl +++ b/test/extraction_test.jl @@ -23,7 +23,7 @@ push!(tarray, t + dt) end @test length(_sol) == length(sol.W) == length(tarray) - @test _sol ≈ sol (rtol = 0.01) + @test _sol≈sol (rtol=0.01) Random.seed!(seed) W2 = WienerProcess!(0.0, [0.0], [0.0]) From 08208aa20a651a329d27ffe04fd5ca5109aa229e Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 13:54:39 -0300 Subject: [PATCH 15/28] check mutability instead --- src/types.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/types.jl b/src/types.jl index b51472f..7e3c61d 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1305,7 +1305,7 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} setfield!(Wnew, x, getfield(W, x)) elseif getfield(W, x) isa AbstractNoiseProcess copy!(getfield(Wnew, x), getfield(W, x)) - elseif getfield(W, x) isa AbstractArray{Nothing, N} where {N} + elseif getfield(W, x) isa AbstractArray && !ismutable(eltype(getfield(W, x))) setfield!(Wnew, x, copy(getfield(W, x))) elseif getfield(W, x) isa AbstractArray setfield!(Wnew, x, recursivecopy(getfield(W, x))) @@ -1313,10 +1313,15 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} setfield!(getfield(Wnew, x), :cur, getfield(W, x).cur) setfield!(getfield(Wnew, x), :numResets, getfield(W, x).numResets) setfield!(getfield(Wnew, x), :data, recursivecopy(getfield(W, x).data)) + elseif getfield(W, x) isa RSWM + setfield!(getfield(Wnew, x), :discard_length, getfield(W, x).discard_length) + setfield!(getfield(Wnew, x), :adaptivealg, getfield(W, x).adaptivealg) elseif getfield(W, x) isa Random.AbstractRNG setfield!(Wnew, x, copy(getfield(W, x))) else + @warn "Got deep with $x::$(typeof(getfield(W, x))) in $(first(split(string(typeof(W)), '}')))" setfield!(Wnew, x, deepcopy(getfield(W, x))) + throw(ArgumentError("Ops, got too deep!")) end end if hasfield(typeof(W), :u) @@ -1331,7 +1336,7 @@ function Base.copy(W::NoiseProcess) end function Base.copy(W::SimpleNoiseProcess) - Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) + Wnew = SimpleNoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) copy!(Wnew, W) end From 0f5c97f5a6c8b61e705f6aef8182a005128db3cc Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 13:58:04 -0300 Subject: [PATCH 16/28] detail equality and more tests --- test/copy_noise_test.jl | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index 989a17a..d84142b 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -2,14 +2,25 @@ using DiffEqNoiseProcess, StochasticDiffEq function Base.:(==)(W1::T, W2::T) where {T <: DiffEqNoiseProcess.AbstractNoiseProcess} - all(getfield(W1, x) == getfield(W2, x) for x in fieldnames(typeof(W1))) - end - - function Base.:(==)(W1::T, W2::T) where {T <: DiffEqNoiseProcess.NoiseApproximation} - all(getfield(W1, x) == getfield(W2, x) - for x in fieldnames(typeof(W1)) if x ∉ (:source1, :source2)) + equal = true + for x in fieldnames(T) + xequal = true + if getfield(W2, x) isa DiffEqNoiseProcess.ResettableStacks.ResettableStack + xequal &= all(getfield(getfield(W1, x), y) == getfield(getfield(W2, x), y) for y in (:cur, :numResets, :data)) + elseif getfield(W2, x) isa DiffEqNoiseProcess.RSWM + xequal &= all(getfield(getfield(W1, x), y) == getfield(getfield(W2, x), y) for y in (:discard_length, :adaptivealg)) + elseif !ismutable(getfield(W1, x)) || getfield(W1, x) isa AbstractArray || getfield(W1, x) === nothing || getfield(W2, x) === nothing + xequal &= (getfield(W1, x) == getfield(W2, x)) + end + if xequal != true + @info "$x::$(typeof(getfield(W1, x))) with value W1.$x = $(getfield(W1, x)) and W2.$x = $(getfield(W2, x)) in $(first(split(string(T), '}')))" + end + equal &= xequal + end + equal end + i = 0 for W in (WienerProcess(0.0, 0.0), SimpleWienerProcess(0.0, 0.0), RealWienerProcess(0.0, 0.0), @@ -18,22 +29,40 @@ 1.0), OrnsteinUhlenbeckProcess(1.0, 0.2, 1.3, 0.0, 1.0), - BrownianBridge(0.0, 1.0, 0.0, 1.0)) - W2 = copy(W) + BrownianBridge(0.0, 1.0, 0.0, 1.0) + ) + W2 = deepcopy(W) + @test typeof(W2) == typeof(W) + copy!(W2, W) @test W2 == W @test W2 !== W @test W2.W === W2.u !== W.W === W.u end + for (W1, W2) in ( + (WienerProcess(0.0, 0.0), WienerProcess(1.0, 1.0)), + (SimpleWienerProcess(0.0, 0.0), SimpleWienerProcess(1.0, 1.0)), + (RealWienerProcess(0.0, 0.0), RealWienerProcess(1.0, 1.0))) + W = deepcopy(W1) + @test typeof(W2) == typeof(W1) + @test W == W1 + copy!(W2, W1) + @test W2 == W1 + @test W2 !== W1 + @test W2.W === W2.u !== W1.W === W1.u + end + for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), NoiseGrid(0:0.01:1, sin.(0:0.01:1)), NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)), dt = 1 / 10)), - NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, - (0.0, Inf)), EM(), dt = 1 / 10)), + NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt = 1 / 10)), VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5), - BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns)) - W2 = copy(W) + BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns) + ) + W2 = deepcopy(W) + @test typeof(W2) == typeof(W) + copy!(W2, W) @test W2 == W @test W2 !== W end From b5816007b3483df61f7921a4c54286db11db178d Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 14:22:57 -0300 Subject: [PATCH 17/28] copy box generation --- src/types.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index 7e3c61d..c2bf274 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1316,12 +1316,16 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} elseif getfield(W, x) isa RSWM setfield!(getfield(Wnew, x), :discard_length, getfield(W, x).discard_length) setfield!(getfield(Wnew, x), :adaptivealg, getfield(W, x).adaptivealg) + elseif typeof(getfield(W, x)) <: Union{BoxGeneration1, BoxGeneration2, BoxGeneration3} + setfield!(getfield(Wnew, x), :boxes, getfield(W, x).boxes) + setfield!(getfield(Wnew, x), :probability, getfield(W, x).probability) + setfield!(getfield(Wnew, x), :offset, getfield(W, x).offset) + setfield!(getfield(Wnew, x), :dist, getfield(W, x).dist) elseif getfield(W, x) isa Random.AbstractRNG setfield!(Wnew, x, copy(getfield(W, x))) else @warn "Got deep with $x::$(typeof(getfield(W, x))) in $(first(split(string(typeof(W)), '}')))" setfield!(Wnew, x, deepcopy(getfield(W, x))) - throw(ArgumentError("Ops, got too deep!")) end end if hasfield(typeof(W), :u) From 84b1ac905116c44fa6373ee32d49bf4550e8ab5b Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 14:23:56 -0300 Subject: [PATCH 18/28] change equality symbol for noises --- test/copy_noise_test.jl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index d84142b..57de38e 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -1,16 +1,18 @@ @testset "Copy Noise test" begin using DiffEqNoiseProcess, StochasticDiffEq - function Base.:(==)(W1::T, W2::T) where {T <: DiffEqNoiseProcess.AbstractNoiseProcess} + # define a temporary equality suitable for comparing noise types (tab-completed by `\boxminus`) + ⊟(W1, W2) = (W1 == W2) + function ⊟(W1::T, W2::T) where {T <: DiffEqNoiseProcess.AbstractNoiseProcess} equal = true for x in fieldnames(T) xequal = true if getfield(W2, x) isa DiffEqNoiseProcess.ResettableStacks.ResettableStack - xequal &= all(getfield(getfield(W1, x), y) == getfield(getfield(W2, x), y) for y in (:cur, :numResets, :data)) + xequal &= all(getfield(getfield(W1, x), y) ⊟ getfield(getfield(W2, x), y) for y in (:cur, :numResets, :data)) elseif getfield(W2, x) isa DiffEqNoiseProcess.RSWM - xequal &= all(getfield(getfield(W1, x), y) == getfield(getfield(W2, x), y) for y in (:discard_length, :adaptivealg)) + xequal &= all(getfield(getfield(W1, x), y) ⊟ getfield(getfield(W2, x), y) for y in (:discard_length, :adaptivealg)) elseif !ismutable(getfield(W1, x)) || getfield(W1, x) isa AbstractArray || getfield(W1, x) === nothing || getfield(W2, x) === nothing - xequal &= (getfield(W1, x) == getfield(W2, x)) + xequal &= (getfield(W1, x) ⊟ getfield(W2, x)) end if xequal != true @info "$x::$(typeof(getfield(W1, x))) with value W1.$x = $(getfield(W1, x)) and W2.$x = $(getfield(W2, x)) in $(first(split(string(T), '}')))" @@ -34,7 +36,7 @@ W2 = deepcopy(W) @test typeof(W2) == typeof(W) copy!(W2, W) - @test W2 == W + @test W2 ⊟ W @test W2 !== W @test W2.W === W2.u !== W.W === W.u end @@ -45,9 +47,9 @@ (RealWienerProcess(0.0, 0.0), RealWienerProcess(1.0, 1.0))) W = deepcopy(W1) @test typeof(W2) == typeof(W1) - @test W == W1 + @test W ⊟ W1 copy!(W2, W1) - @test W2 == W1 + @test W2 ⊟ W1 @test W2 !== W1 @test W2.W === W2.u !== W1.W === W1.u end @@ -63,7 +65,7 @@ W2 = deepcopy(W) @test typeof(W2) == typeof(W) copy!(W2, W) - @test W2 == W + @test W2 ⊟ W @test W2 !== W end end From e9f2ac00fb3d6c973921cdad05cc1937828a528d Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 14:25:35 -0300 Subject: [PATCH 19/28] back with equality test in extraction_test --- test/extraction_test.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extraction_test.jl b/test/extraction_test.jl index 55de93e..60490ef 100644 --- a/test/extraction_test.jl +++ b/test/extraction_test.jl @@ -23,7 +23,7 @@ push!(tarray, t + dt) end @test length(_sol) == length(sol.W) == length(tarray) - @test _sol≈sol (rtol=0.01) + @test _sol == sol Random.seed!(seed) W2 = WienerProcess!(0.0, [0.0], [0.0]) From 9d1c3703c135939978b5b27fa2b70cdad669c669 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 14:31:09 -0300 Subject: [PATCH 20/28] comment out warning for using deepcopy --- src/types.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/types.jl b/src/types.jl index c2bf274..6fb3d1b 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1324,16 +1324,17 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} elseif getfield(W, x) isa Random.AbstractRNG setfield!(Wnew, x, copy(getfield(W, x))) else - @warn "Got deep with $x::$(typeof(getfield(W, x))) in $(first(split(string(typeof(W)), '}')))" + # @warn "Got deep with $x::$(typeof(getfield(W, x))) in $(first(split(string(typeof(W)), '}')))" setfield!(Wnew, x, deepcopy(getfield(W, x))) end end + # field u should be an alias for field W: if hasfield(typeof(W), :u) Wnew.u = Wnew.W end Wnew end - +#= function Base.copy(W::NoiseProcess) Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) copy!(Wnew, W) @@ -1378,3 +1379,4 @@ function Base.copy(W::BoxWedgeTail) Wnew = BoxWedgeTail(W.curt, W.curW, W.curZ, W.dist, W.bridge) copy!(Wnew, W) end + =# \ No newline at end of file From 9a85a65f69222423af3ab8f466e212356673ece1 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 14:32:44 -0300 Subject: [PATCH 21/28] sciml format --- src/types.jl | 5 +++-- test/copy_noise_test.jl | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/types.jl b/src/types.jl index 6fb3d1b..7a50204 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1316,7 +1316,8 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} elseif getfield(W, x) isa RSWM setfield!(getfield(Wnew, x), :discard_length, getfield(W, x).discard_length) setfield!(getfield(Wnew, x), :adaptivealg, getfield(W, x).adaptivealg) - elseif typeof(getfield(W, x)) <: Union{BoxGeneration1, BoxGeneration2, BoxGeneration3} + elseif typeof(getfield(W, x)) <: + Union{BoxGeneration1, BoxGeneration2, BoxGeneration3} setfield!(getfield(Wnew, x), :boxes, getfield(W, x).boxes) setfield!(getfield(Wnew, x), :probability, getfield(W, x).probability) setfield!(getfield(Wnew, x), :offset, getfield(W, x).offset) @@ -1379,4 +1380,4 @@ function Base.copy(W::BoxWedgeTail) Wnew = BoxWedgeTail(W.curt, W.curW, W.curZ, W.dist, W.bridge) copy!(Wnew, W) end - =# \ No newline at end of file + =# diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index 57de38e..64d1a57 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -8,10 +8,13 @@ for x in fieldnames(T) xequal = true if getfield(W2, x) isa DiffEqNoiseProcess.ResettableStacks.ResettableStack - xequal &= all(getfield(getfield(W1, x), y) ⊟ getfield(getfield(W2, x), y) for y in (:cur, :numResets, :data)) + xequal &= all(getfield(getfield(W1, x), y) ⊟ getfield(getfield(W2, x), y) + for y in (:cur, :numResets, :data)) elseif getfield(W2, x) isa DiffEqNoiseProcess.RSWM - xequal &= all(getfield(getfield(W1, x), y) ⊟ getfield(getfield(W2, x), y) for y in (:discard_length, :adaptivealg)) - elseif !ismutable(getfield(W1, x)) || getfield(W1, x) isa AbstractArray || getfield(W1, x) === nothing || getfield(W2, x) === nothing + xequal &= all(getfield(getfield(W1, x), y) ⊟ getfield(getfield(W2, x), y) + for y in (:discard_length, :adaptivealg)) + elseif !ismutable(getfield(W1, x)) || getfield(W1, x) isa AbstractArray || + getfield(W1, x) === nothing || getfield(W2, x) === nothing xequal &= (getfield(W1, x) ⊟ getfield(W2, x)) end if xequal != true @@ -31,8 +34,7 @@ 1.0), OrnsteinUhlenbeckProcess(1.0, 0.2, 1.3, 0.0, 1.0), - BrownianBridge(0.0, 1.0, 0.0, 1.0) - ) + BrownianBridge(0.0, 1.0, 0.0, 1.0)) W2 = deepcopy(W) @test typeof(W2) == typeof(W) copy!(W2, W) @@ -41,10 +43,9 @@ @test W2.W === W2.u !== W.W === W.u end - for (W1, W2) in ( - (WienerProcess(0.0, 0.0), WienerProcess(1.0, 1.0)), - (SimpleWienerProcess(0.0, 0.0), SimpleWienerProcess(1.0, 1.0)), - (RealWienerProcess(0.0, 0.0), RealWienerProcess(1.0, 1.0))) + for (W1, W2) in ((WienerProcess(0.0, 0.0), WienerProcess(1.0, 1.0)), + (SimpleWienerProcess(0.0, 0.0), SimpleWienerProcess(1.0, 1.0)), + (RealWienerProcess(0.0, 0.0), RealWienerProcess(1.0, 1.0))) W = deepcopy(W1) @test typeof(W2) == typeof(W1) @test W ⊟ W1 @@ -58,10 +59,10 @@ NoiseGrid(0:0.01:1, sin.(0:0.01:1)), NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)), dt = 1 / 10)), - NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, (0.0, Inf)), EM(), dt = 1 / 10)), + NoiseApproximation(init(SDEProblem((u, p, t) -> 1.5u, (u, p, t) -> 0.2u, 1.0, + (0.0, Inf)), EM(), dt = 1 / 10)), VirtualBrownianTree(0.0, 0.0; tree_depth = 3, search_depth = 5), - BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns) - ) + BoxWedgeTail(0.0, zeros(2), box_grouping = :Columns)) W2 = deepcopy(W) @test typeof(W2) == typeof(W) copy!(W2, W) From 62343301e6e7c236fccf5743ae43067f57d640e3 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 14:33:51 -0300 Subject: [PATCH 22/28] remove copy --- src/types.jl | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/types.jl b/src/types.jl index 7a50204..9f247a6 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1335,49 +1335,3 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} end Wnew end -#= -function Base.copy(W::NoiseProcess) - Wnew = NoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) - copy!(Wnew, W) -end - -function Base.copy(W::SimpleNoiseProcess) - Wnew = SimpleNoiseProcess(W.curt, W.curW, W.curZ, W.dist, W.bridge) - copy!(Wnew, W) -end - -function Base.copy(W::NoiseWrapper) - Wnew = NoiseWrapper(W.source) - copy!(Wnew, W) -end - -function Base.copy(W::NoiseFunction) - Wnew = NoiseFunction(W.t0, W.W, W.Z) - copy!(Wnew, W) -end - -function Base.copy(W::NoiseTransport) - Wnew = NoiseTransport(W.t0, W.W, copy(W.RV)) - copy!(Wnew, W) -end - -function Base.copy(W::NoiseGrid) - Wnew = NoiseGrid(W.t, W.W, W.Z) - copy!(Wnew, W) -end - -function Base.copy(W::NoiseApproximation) - Wnew = NoiseApproximation(W.source1, W.source2) - copy!(Wnew, W) -end - -function Base.copy(W::VirtualBrownianTree) - Wnew = VirtualBrownianTree(W.curt, W.curW, W.curZ, W.dist, W.bridge) - copy!(Wnew, W) -end - -function Base.copy(W::BoxWedgeTail) - Wnew = BoxWedgeTail(W.curt, W.curW, W.curZ, W.dist, W.bridge) - copy!(Wnew, W) -end - =# From e3b5f9e703e80d9eea0e8063048e285fcbeb66cd Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 17:15:56 -0300 Subject: [PATCH 23/28] copy the noise when solving --- src/solve.jl | 2 +- src/types.jl | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/solve.jl b/src/solve.jl index 25bc449..a4a603b 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -4,7 +4,7 @@ function DiffEqBase.__solve(prob::AbstractNoiseProblem, if dt == 0.0 || dt == nothing error("dt must be provided to simulate a noise process. Please pass dt=...") end - W = deepcopy(prob.noise) + W = copy(prob.noise) if typeof(W) <: Union{NoiseProcess, NoiseTransport} if prob.seed != 0 Random.seed!(W.rng, prob.seed) diff --git a/src/types.jl b/src/types.jl index 9f247a6..4d41e20 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1335,3 +1335,37 @@ function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} end Wnew end + +function Base.copy(W::NoiseProcess) + Wnew = NoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; + rswm = W.rswm, save_everystep = W.save_everystep, + rng = W.rng, + reset = W.reset, reseed = W.reseed, continuous = W.continuous, cache = W.cache) + copy!(Wnew, W) +end + +function Base.copy(W::SimpleNoiseProcess) + Wnew = SimpleNoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; + save_everystep = W.save_everystep, + rng = W.rng, + reset = W.reset, reseed = W.reseed) + copy!(Wnew, W) +end + +function Base.copy(W::Union{NoiseWrapper, NoiseGrid, NoiseApproximation, VirtualBrownianTree, BoxWedgeTail}) + Wnew = typeof(W)((getfield(W, x) for x in fieldnames(typeof(W)))...) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseFunction) + Wnew = NoiseFunction{isinplace(W)}(W.t0, W.W, W.Z; noise_prototype = W.curW, reset = W.reset) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseTransport) + Wnew = NoiseTransport{isinplace(W)}(W.t0, W.W, W.RV, W.rv, W.Z; + rng = W.rng, + reset = W.reset, reseed = W.reseed, + noise_prototype = W.curW) + copy!(Wnew, W) +end From bb862cf5a547994cb5167db0f20062209f6ca3ee Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 17:16:05 -0300 Subject: [PATCH 24/28] more tests --- test/copy_noise_test.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index 64d1a57..f02eb4b 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -39,6 +39,7 @@ @test typeof(W2) == typeof(W) copy!(W2, W) @test W2 ⊟ W + @test copy(W) ⊟ W @test W2 !== W @test W2.W === W2.u !== W.W === W.u end @@ -51,11 +52,13 @@ @test W ⊟ W1 copy!(W2, W1) @test W2 ⊟ W1 + @test copy(W1) ⊟ W1 @test W2 !== W1 @test W2.W === W2.u !== W1.W === W1.u end for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), + NoiseTransport(0.0, (u, p, t, Y) -> exp(t), (rng) -> nothing), NoiseGrid(0:0.01:1, sin.(0:0.01:1)), NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)), dt = 1 / 10)), @@ -67,6 +70,7 @@ @test typeof(W2) == typeof(W) copy!(W2, W) @test W2 ⊟ W + @test copy(W) ⊟ W @test W2 !== W end end From e40b12dacc5dfcf06bf924d326695c38208ffce1 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 17:16:18 -0300 Subject: [PATCH 25/28] format --- src/types.jl | 25 ++++++++++++++----------- test/copy_noise_test.jl | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/types.jl b/src/types.jl index 4d41e20..6702927 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1338,34 +1338,37 @@ end function Base.copy(W::NoiseProcess) Wnew = NoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; - rswm = W.rswm, save_everystep = W.save_everystep, - rng = W.rng, - reset = W.reset, reseed = W.reseed, continuous = W.continuous, cache = W.cache) + rswm = W.rswm, save_everystep = W.save_everystep, + rng = W.rng, + reset = W.reset, reseed = W.reseed, + continuous = W.continuous, cache = W.cache) copy!(Wnew, W) end function Base.copy(W::SimpleNoiseProcess) Wnew = SimpleNoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; - save_everystep = W.save_everystep, - rng = W.rng, - reset = W.reset, reseed = W.reseed) + save_everystep = W.save_everystep, + rng = W.rng, + reset = W.reset, reseed = W.reseed) copy!(Wnew, W) end -function Base.copy(W::Union{NoiseWrapper, NoiseGrid, NoiseApproximation, VirtualBrownianTree, BoxWedgeTail}) +function Base.copy(W::Union{NoiseWrapper, NoiseGrid, NoiseApproximation, + VirtualBrownianTree, BoxWedgeTail}) Wnew = typeof(W)((getfield(W, x) for x in fieldnames(typeof(W)))...) copy!(Wnew, W) end function Base.copy(W::NoiseFunction) - Wnew = NoiseFunction{isinplace(W)}(W.t0, W.W, W.Z; noise_prototype = W.curW, reset = W.reset) + Wnew = NoiseFunction{isinplace(W)}(W.t0, W.W, W.Z; noise_prototype = W.curW, + reset = W.reset) copy!(Wnew, W) end function Base.copy(W::NoiseTransport) Wnew = NoiseTransport{isinplace(W)}(W.t0, W.W, W.RV, W.rv, W.Z; - rng = W.rng, - reset = W.reset, reseed = W.reseed, - noise_prototype = W.curW) + rng = W.rng, + reset = W.reset, reseed = W.reseed, + noise_prototype = W.curW) copy!(Wnew, W) end diff --git a/test/copy_noise_test.jl b/test/copy_noise_test.jl index f02eb4b..8946f6c 100644 --- a/test/copy_noise_test.jl +++ b/test/copy_noise_test.jl @@ -58,7 +58,7 @@ end for W in (NoiseFunction(0.0, (u, p, t) -> exp(t)), - NoiseTransport(0.0, (u, p, t, Y) -> exp(t), (rng) -> nothing), + NoiseTransport(0.0, (u, p, t, Y) -> exp(t), (rng) -> nothing), NoiseGrid(0:0.01:1, sin.(0:0.01:1)), NoiseWrapper(solve(NoiseProblem(WienerProcess(0.0, 0.0), (0.0, 0.1)), dt = 1 / 10)), From b8a1dad01a1dcf4d28e1ca78e8dc35bdc88bb1c9 Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 17:18:53 -0300 Subject: [PATCH 26/28] separate copy methods from types --- src/DiffEqNoiseProcess.jl | 1 + src/copy_noise_types.jl | 73 ++++++++++++++++++++++++++++++++++++++ src/types.jl | 74 --------------------------------------- 3 files changed, 74 insertions(+), 74 deletions(-) create mode 100644 src/copy_noise_types.jl diff --git a/src/DiffEqNoiseProcess.jl b/src/DiffEqNoiseProcess.jl index 8931733..7b07bf7 100644 --- a/src/DiffEqNoiseProcess.jl +++ b/src/DiffEqNoiseProcess.jl @@ -22,6 +22,7 @@ using Markdown using DiffEqBase: @.. include("types.jl") +include("copy_noise_types.jl") include("wiener.jl") include("solve.jl") include("geometric_bm.jl") diff --git a/src/copy_noise_types.jl b/src/copy_noise_types.jl new file mode 100644 index 0000000..2ef779a --- /dev/null +++ b/src/copy_noise_types.jl @@ -0,0 +1,73 @@ +function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} + for x in filter(!=(:u), fieldnames(typeof(W))) + if !ismutable(getfield(W, x)) + setfield!(Wnew, x, getfield(W, x)) + elseif getfield(W, x) isa AbstractNoiseProcess + copy!(getfield(Wnew, x), getfield(W, x)) + elseif getfield(W, x) isa AbstractArray && !ismutable(eltype(getfield(W, x))) + setfield!(Wnew, x, copy(getfield(W, x))) + elseif getfield(W, x) isa AbstractArray + setfield!(Wnew, x, recursivecopy(getfield(W, x))) + elseif getfield(W, x) isa ResettableStacks.ResettableStack + setfield!(getfield(Wnew, x), :cur, getfield(W, x).cur) + setfield!(getfield(Wnew, x), :numResets, getfield(W, x).numResets) + setfield!(getfield(Wnew, x), :data, recursivecopy(getfield(W, x).data)) + elseif getfield(W, x) isa RSWM + setfield!(getfield(Wnew, x), :discard_length, getfield(W, x).discard_length) + setfield!(getfield(Wnew, x), :adaptivealg, getfield(W, x).adaptivealg) + elseif typeof(getfield(W, x)) <: + Union{BoxGeneration1, BoxGeneration2, BoxGeneration3} + setfield!(getfield(Wnew, x), :boxes, getfield(W, x).boxes) + setfield!(getfield(Wnew, x), :probability, getfield(W, x).probability) + setfield!(getfield(Wnew, x), :offset, getfield(W, x).offset) + setfield!(getfield(Wnew, x), :dist, getfield(W, x).dist) + elseif getfield(W, x) isa Random.AbstractRNG + setfield!(Wnew, x, copy(getfield(W, x))) + else + # @warn "Got deep with $x::$(typeof(getfield(W, x))) in $(first(split(string(typeof(W)), '}')))" + setfield!(Wnew, x, deepcopy(getfield(W, x))) + end + end + # field u should be an alias for field W: + if hasfield(typeof(W), :u) + Wnew.u = Wnew.W + end + Wnew +end + +function Base.copy(W::NoiseProcess) + Wnew = NoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; + rswm = W.rswm, save_everystep = W.save_everystep, + rng = W.rng, + reset = W.reset, reseed = W.reseed, + continuous = W.continuous, cache = W.cache) + copy!(Wnew, W) +end + +function Base.copy(W::SimpleNoiseProcess) + Wnew = SimpleNoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; + save_everystep = W.save_everystep, + rng = W.rng, + reset = W.reset, reseed = W.reseed) + copy!(Wnew, W) +end + +function Base.copy(W::Union{NoiseWrapper, NoiseGrid, NoiseApproximation, + VirtualBrownianTree, BoxWedgeTail}) + Wnew = typeof(W)((getfield(W, x) for x in fieldnames(typeof(W)))...) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseFunction) + Wnew = NoiseFunction{isinplace(W)}(W.t0, W.W, W.Z; noise_prototype = W.curW, + reset = W.reset) + copy!(Wnew, W) +end + +function Base.copy(W::NoiseTransport) + Wnew = NoiseTransport{isinplace(W)}(W.t0, W.W, W.RV, W.rv, W.Z; + rng = W.rng, + reset = W.reset, reseed = W.reseed, + noise_prototype = W.curW) + copy!(Wnew, W) +end diff --git a/src/types.jl b/src/types.jl index 6702927..9823aaf 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1298,77 +1298,3 @@ function BoxWedgeTail!(t0, W0, Z0 = nothing, dist = INPLACE_WHITE_NOISE_DIST, bridge = INPLACE_WHITE_NOISE_BRIDGE; kwargs...) BoxWedgeTail{true}(t0, W0, Z0, dist, bridge; kwargs...) end - -function Base.copy!(Wnew::T, W::T) where {T <: AbstractNoiseProcess} - for x in filter(!=(:u), fieldnames(typeof(W))) - if !ismutable(getfield(W, x)) - setfield!(Wnew, x, getfield(W, x)) - elseif getfield(W, x) isa AbstractNoiseProcess - copy!(getfield(Wnew, x), getfield(W, x)) - elseif getfield(W, x) isa AbstractArray && !ismutable(eltype(getfield(W, x))) - setfield!(Wnew, x, copy(getfield(W, x))) - elseif getfield(W, x) isa AbstractArray - setfield!(Wnew, x, recursivecopy(getfield(W, x))) - elseif getfield(W, x) isa ResettableStacks.ResettableStack - setfield!(getfield(Wnew, x), :cur, getfield(W, x).cur) - setfield!(getfield(Wnew, x), :numResets, getfield(W, x).numResets) - setfield!(getfield(Wnew, x), :data, recursivecopy(getfield(W, x).data)) - elseif getfield(W, x) isa RSWM - setfield!(getfield(Wnew, x), :discard_length, getfield(W, x).discard_length) - setfield!(getfield(Wnew, x), :adaptivealg, getfield(W, x).adaptivealg) - elseif typeof(getfield(W, x)) <: - Union{BoxGeneration1, BoxGeneration2, BoxGeneration3} - setfield!(getfield(Wnew, x), :boxes, getfield(W, x).boxes) - setfield!(getfield(Wnew, x), :probability, getfield(W, x).probability) - setfield!(getfield(Wnew, x), :offset, getfield(W, x).offset) - setfield!(getfield(Wnew, x), :dist, getfield(W, x).dist) - elseif getfield(W, x) isa Random.AbstractRNG - setfield!(Wnew, x, copy(getfield(W, x))) - else - # @warn "Got deep with $x::$(typeof(getfield(W, x))) in $(first(split(string(typeof(W)), '}')))" - setfield!(Wnew, x, deepcopy(getfield(W, x))) - end - end - # field u should be an alias for field W: - if hasfield(typeof(W), :u) - Wnew.u = Wnew.W - end - Wnew -end - -function Base.copy(W::NoiseProcess) - Wnew = NoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; - rswm = W.rswm, save_everystep = W.save_everystep, - rng = W.rng, - reset = W.reset, reseed = W.reseed, - continuous = W.continuous, cache = W.cache) - copy!(Wnew, W) -end - -function Base.copy(W::SimpleNoiseProcess) - Wnew = SimpleNoiseProcess{isinplace(W)}(W.curt, W.curW, W.curZ, W.dist, W.bridge; - save_everystep = W.save_everystep, - rng = W.rng, - reset = W.reset, reseed = W.reseed) - copy!(Wnew, W) -end - -function Base.copy(W::Union{NoiseWrapper, NoiseGrid, NoiseApproximation, - VirtualBrownianTree, BoxWedgeTail}) - Wnew = typeof(W)((getfield(W, x) for x in fieldnames(typeof(W)))...) - copy!(Wnew, W) -end - -function Base.copy(W::NoiseFunction) - Wnew = NoiseFunction{isinplace(W)}(W.t0, W.W, W.Z; noise_prototype = W.curW, - reset = W.reset) - copy!(Wnew, W) -end - -function Base.copy(W::NoiseTransport) - Wnew = NoiseTransport{isinplace(W)}(W.t0, W.W, W.RV, W.rv, W.Z; - rng = W.rng, - reset = W.reset, reseed = W.reseed, - noise_prototype = W.curW) - copy!(Wnew, W) -end From 31304e5aaf113f5432f555f5583d30115dd0a11b Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 17:53:22 -0300 Subject: [PATCH 27/28] newline --- src/types.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types.jl b/src/types.jl index 9823aaf..a02a9dc 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1298,3 +1298,4 @@ function BoxWedgeTail!(t0, W0, Z0 = nothing, dist = INPLACE_WHITE_NOISE_DIST, bridge = INPLACE_WHITE_NOISE_BRIDGE; kwargs...) BoxWedgeTail{true}(t0, W0, Z0, dist, bridge; kwargs...) end + From 4750deec4bad5f55d78a482a6300230530061baa Mon Sep 17 00:00:00 2001 From: Ricardo Rosa Date: Wed, 19 Oct 2022 17:53:27 -0300 Subject: [PATCH 28/28] rm --- src/types.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index a02a9dc..9823aaf 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1298,4 +1298,3 @@ function BoxWedgeTail!(t0, W0, Z0 = nothing, dist = INPLACE_WHITE_NOISE_DIST, bridge = INPLACE_WHITE_NOISE_BRIDGE; kwargs...) BoxWedgeTail{true}(t0, W0, Z0, dist, bridge; kwargs...) end -