@@ -194,10 +194,12 @@ end
194194 (; recf, recf2, mα, mσ, mτ) = cache
195195
196196 gen_prob = ! (
197- (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number) ||
198- (length (W. dW) == 1 )
197+ (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number)
199198 )
200- gen_prob && (vec_χ = 2 .* floor .(false .* W. dW .+ 1 // 2 .+ oftype (W. dW, rand (W. rng, length (W. dW)))) .- true )
199+ if gen_prob
200+ vec_χ = similar (W. dW)
201+ init_χ! (vec_χ, W)
202+ end
201203
202204 alg = unwrap_alg (integrator, true )
203205 alg. eigen_est === nothing ? maxeig! (integrator, cache) : alg. eigen_est (integrator)
265267 # Now uᵢ₋₂ = uₛ₋₂, uᵢ₋₁ = uₛ₋₁, uᵢ = uₛ
266268 # Similarly tᵢ₋₂ = tₛ₋₂, tᵢ₋₁ = tₛ₋₁, tᵢ = tₛ
267269
268- if (W. dW isa Number) || ( length (W . dW) == 1 ) || is_diagonal_noise (integrator. sol. prob)
270+ if (W. dW isa Number) || is_diagonal_noise (integrator. sol. prob)
269271 Gₛ = integrator. f. g (uᵢ₋₁, p, tᵢ₋₁)
270272 u += Gₛ .* W. dW
271273 Gₛ = integrator. f. g (uᵢ, p, tᵢ)
300302 for i in 1 : length (W. dW)
301303 WikJ = W. dW[i]
302304 WikJ2 = vec_χ[i]
303- WikRange = 1 // 2 .* (W. dW .* WikJ .- (1 : length (W. dW) .== i) .* abs (dt)) # .- (1:length(W.dW) .> i) .* dt .* vec_χ .+ (1:length(W.dW) .< i) .* dt .* WikJ2)
305+ WikRange = 1 // 2 .* (
306+ W. dW .* WikJ .- (1 : length (W. dW) .== i) .* abs (dt) .-
307+ (1 : length (W. dW) .> i) .* abs (dt) .* vec_χ .+
308+ (1 : length (W. dW) .< i) .* abs (dt) .* WikJ2
309+ )
304310 uₓ = Gₛ * WikRange
305311 WikRange = 1 // 2 .* (1 : length (W. dW) .== i)
306312 uᵢ₋₂ = uᵢ + uₓ
332338 (; recf, recf2, mα, mσ, mτ) = cache. constantcache
333339 ccache = cache. constantcache
334340 gen_prob = ! (
335- (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number) ||
336- (length (W. dW) == 1 )
341+ (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number)
337342 )
338343
339344 alg = unwrap_alg (integrator, true )
362367
363368 sqrt_dt = sqrt (abs (dt))
364369 if gen_prob
365- vec_χ .= 1 // 2 .+ oftype (W. dW, rand (W. rng, length (W. dW)))
366- @. . vec_χ = 2 * floor (vec_χ) - 1
370+ init_χ! (vec_χ, W)
367371 end
368372
369373 μ = recf[start] # here κ = 0
418422 # Now uᵢ₋₂ = uₛ₋₂, uᵢ₋₁ = uₛ₋₁, uᵢ = uₛ
419423 # Similarly tᵢ₋₂ = tₛ₋₂, tᵢ₋₁ = tₛ₋₁, tᵢ = tₛ
420424
421- if (W. dW isa Number) || ( length (W . dW) == 1 ) || is_diagonal_noise (integrator. sol. prob)
425+ if (W. dW isa Number) || is_diagonal_noise (integrator. sol. prob)
422426 integrator. f. g (Gₛ, uᵢ₋₁, p, tᵢ₋₁)
423427 @. . u += Gₛ * W. dW
424428 integrator. f. g (Gₛ, uᵢ, p, tᵢ)
458462 WikJ2 = vec_χ[i]
459463 dwrange = 1 : length (W. dW)
460464 abs_dt = abs (dt)
461- @. . WikRange = 1 // 2 * (W. dW * WikJ - (dwrange == i) * abs_dt) # + (dwrange < i) * dt * WikJ2 - (dwrange > i) * dt * vec_χ)
465+ @. . WikRange = 1 // 2 *
466+ (
467+ W. dW * WikJ - (dwrange == i) * abs_dt -
468+ (dwrange > i) * abs_dt * vec_χ +
469+ (dwrange < i) * abs_dt * WikJ2
470+ )
462471 mul! (uₓ, Gₛ, WikRange)
463472 @. . uᵢ₋₂ = uᵢ + uₓ
464473 @. . WikRange = 1 // 2 * (dwrange == i)
@@ -542,14 +551,14 @@ end
542551 end
543552
544553 Gₛ = integrator. f. g (u, p, tᵢ)
545- if (W. dW isa Number) || ( length (W . dW) == 1 ) || is_diagonal_noise (integrator. sol. prob)
554+ if (W. dW isa Number) || is_diagonal_noise (integrator. sol. prob)
546555 u += Gₛ .* W. dW
547556 else
548557 u += Gₛ * W. dW
549558 end
550559
551560 if integrator. alg. strong_order_1
552- if (W. dW isa Number) || ( length (W . dW) == 1 ) ||
561+ if (W. dW isa Number) ||
553562 (is_diagonal_noise (integrator. sol. prob))
554563 uᵢ₋₂ = @. 1 // 2 * Gₛ * (W. dW^ 2 - abs (dt))
555564 tmp = @. u + uᵢ₋₂
@@ -633,15 +642,15 @@ end
633642 end
634643
635644 integrator. f. g (Gₛ, u, p, tᵢ)
636- if (W. dW isa Number) || ( length (W . dW) == 1 ) || is_diagonal_noise (integrator. sol. prob)
645+ if (W. dW isa Number) || is_diagonal_noise (integrator. sol. prob)
637646 @. . u += Gₛ * W. dW
638647 else
639648 mul! (uᵢ₋₁, Gₛ, W. dW)
640649 u += uᵢ₋₁
641650 end
642651
643652 if integrator. alg. strong_order_1
644- if (W. dW isa Number) || ( length (W . dW) == 1 ) ||
653+ if (W. dW isa Number) ||
645654 (is_diagonal_noise (integrator. sol. prob))
646655 @. . uᵢ₋₂ = 1 // 2 * Gₛ * (W. dW^ 2 - abs (dt))
647656 @. . tmp = u + uᵢ₋₂
982991 end
983992 end
984993
985- if (W. dW isa Number) || ( length (W . dW) == 1 )
994+ if (W. dW isa Number)
986995 Gₛ = integrator. f. g (Û₁, p, t̂₁)
987996 uₓ += Gₛ * W. dW
988997
@@ -1168,7 +1177,7 @@ end
11681177 end
11691178 end
11701179
1171- if (W. dW isa Number) || ( length (W . dW) == 1 ) || is_diagonal_noise (integrator. sol. prob)
1180+ if (W. dW isa Number) || is_diagonal_noise (integrator. sol. prob)
11721181 integrator. f. g (Gₛ, Û₁, p, t̂₁)
11731182 @. . uₓ += Gₛ * W. dW
11741183
@@ -1227,8 +1236,7 @@ end
12271236 (; recf, mσ, mτ, mδ) = cache
12281237
12291238 gen_prob = ! (
1230- (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number) ||
1231- (length (W. dW) == 1 )
1239+ (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number)
12321240 )
12331241
12341242 alg = unwrap_alg (integrator, true )
@@ -1245,7 +1253,10 @@ end
12451253 τ = mτ[deg_index]
12461254
12471255 sqrt_dt = sqrt (abs (dt))
1248- (gen_prob) && (vec_χ = 2 .* floor .(1 // 2 .+ false .* W. dW .+ rand (length (W. dW))) .- 1 )
1256+ if gen_prob
1257+ vec_χ = similar (W. dW)
1258+ init_χ! (vec_χ, W)
1259+ end
12491260
12501261 tᵢ₋₂ = t
12511262 uᵢ₋₂ = uprev
@@ -1289,7 +1300,7 @@ end
12891300 tᵢ₋₁ += θₛ₋₃ * (tᵢ₋₁ - tᵢ₋₂)
12901301 tᵢ₋₂ = ttmp
12911302
1292- if W. dW isa Number || length (W . dW) == 1 || is_diagonal_noise (integrator. sol. prob)
1303+ if W. dW isa Number || is_diagonal_noise (integrator. sol. prob)
12931304 # stage s-3
12941305 yₛ₋₃ = integrator. f (uᵢ₋₁, p, tᵢ₋₁)
12951306 utmp = uᵢ₋₁ + μₛ₋₃ * yₛ₋₃
@@ -1431,8 +1442,7 @@ end
14311442
14321443 ccache = cache. constantcache
14331444 gen_prob = ! (
1434- (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number) ||
1435- (length (W. dW) == 1 )
1445+ (is_diagonal_noise (integrator. sol. prob)) || (W. dW isa Number)
14361446 )
14371447
14381448 alg = unwrap_alg (integrator, true )
@@ -1459,7 +1469,9 @@ end
14591469 τ = mτ[deg_index]
14601470
14611471 sqrt_dt = sqrt (abs (dt))
1462- (gen_prob) && (vec_χ .= 2 .* floor .(1 // 2 .+ false .* vec_χ .+ rand (length (vec_χ))) .- 1 )
1472+ if gen_prob
1473+ init_χ! (vec_χ, W)
1474+ end
14631475
14641476 tᵢ₋₂ = t
14651477 @. . uᵢ₋₂ = uprev
@@ -1502,7 +1514,7 @@ end
15021514 tᵢ₋₁ += θₛ₋₃ * (tᵢ₋₁ - tᵢ₋₂)
15031515 tᵢ₋₂ = ttmp
15041516
1505- if W. dW isa Number || length (W . dW) == 1 || is_diagonal_noise (integrator. sol. prob)
1517+ if W. dW isa Number || is_diagonal_noise (integrator. sol. prob)
15061518 # stage s-3
15071519 integrator. f (yₛ₋₃, uᵢ₋₁, p, tᵢ₋₁)
15081520 @. . utmp = uᵢ₋₁ + μₛ₋₃ * yₛ₋₃
@@ -1711,7 +1723,7 @@ end
17111723 uᵢ₋₂ = integrator. f (uᵢ₋₂, p, tᵢ₋₂)
17121724 u += dt * (σ + τ) * uᵢ₋₂
17131725
1714- if (W. dW isa Number) || ( length (W . dW) == 1 ) || is_diagonal_noise (integrator. sol. prob)
1726+ if (W. dW isa Number) || is_diagonal_noise (integrator. sol. prob)
17151727 Gₛ = integrator. f. g (uᵢ₋₁, p, tᵢ₋₁)
17161728 u += Gₛ .* W. dW
17171729
@@ -1806,7 +1818,7 @@ end
18061818 integrator. f (k, uᵢ₋₂, p, tᵢ₋₂)
18071819 @. . u += dt * (σ + τ) * k
18081820
1809- if (W. dW isa Number) || ( length (W . dW) == 1 ) || is_diagonal_noise (integrator. sol. prob)
1821+ if (W. dW isa Number) || is_diagonal_noise (integrator. sol. prob)
18101822 integrator. f. g (Gₛ, uᵢ₋₁, p, tᵢ₋₁)
18111823 @. . u += Gₛ * W. dW
18121824
@@ -1840,3 +1852,18 @@ end
18401852
18411853 integrator. u = u
18421854end
1855+
1856+ # Fill `vec_χ` with independent Rademacher (±1) samples drawn from the RNG of the
1857+ # integrator's noise process. Kept as a scalar loop so it works for both `Vector`
1858+ # and `MArray` storage without requiring the Random stdlib as a dependency.
1859+ function init_χ! (vec_χ, W)
1860+ r = rng (W)
1861+ for i in eachindex (vec_χ)
1862+ vec_χ[i] = 2 * (rand (r) < 1 // 2 ) - 1
1863+ end
1864+ return vec_χ
1865+ end
1866+
1867+ # `NoiseWrapper` does not carry its own `rng`; the generator lives on the wrapped
1868+ # source process, so accessing `W.rng` directly crashes (#3188).
1869+ rng (W) = hasfield (typeof (W), :rng ) ? W. rng : W. source. rng
0 commit comments