-
-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Randomized qmc #57
Randomized qmc #57
Changes from 60 commits
00830b2
646b3cc
b8b5329
ab44dd4
e73b2e4
563d554
9f3a39e
74d751d
49be1e2
b99865c
ab885ba
fc461d0
e4c995f
7e96838
8a8eeac
6e2f76d
ea84fb6
25ddd5c
e2ada4e
f94acf6
a64f7b7
a21296b
3080969
933c7f8
1e253f3
fcadc55
9279ed8
0e07566
f9658f0
6facc73
ab17bed
bd94bae
e640045
f7e5f6c
3c6d39b
762e110
e8a591f
2df85e7
445b8f8
4ad2f52
2a69efa
5050730
9859057
03e46b3
c2fffdd
ffb13ad
ede1984
55ff172
e80a2f2
0f70820
fb1a6cd
1e9dd2e
0249e6c
6ae1a0b
080bace
5364d89
5942843
3a25a7e
092da9c
a09042b
d5730ea
1f19588
bc70815
b1a45c0
96b1ec0
f3068a3
d49cefa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,11 @@ authors = ["ludoro <[email protected]>, Chris Rackauckas <accounts@chrisra | |
version = "0.3.0" | ||
|
||
[deps] | ||
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" | ||
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" | ||
ConcreteStructs = "2569d6c7-a4a2-43d3-a901-331e8e4be471" | ||
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" | ||
IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" | ||
LatticeRules = "73f95e8e-ec14-4e6a-8b18-0d2e271c4e55" | ||
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" | ||
Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -107,3 +107,99 @@ function sample(n,lb,ub,::NewAmazingSamplingAlgorithm) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
## Randomization | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Note that this feature is currently experimental and is thus subject to interface changes in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
non-breaking (minor) releases. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Given a matrix `x` of size `d×n` and `xᵢₛ∈[0,1]ᵈ` one obtain a randomized version `y` using one the following methods | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `owen_scramble(x, b; pad = pad)` where `b` is the base used to scramble and `pad` the number of bits in base `b` used to represent digits. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `matousek_scramble(x, base; pad = pad)`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `digital_shift(x, base; pad = pad)`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `shift(x)`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
All these functions guarantee that the resulting array will have its components uniformly distributed `yᵢₛ∼𝐔([0,1]ᵈ)` (but not independent). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
### Example | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Randomization of a Faure sequence with various methods. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
```julia | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
m = 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d = 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
b = QuasiMonteCarlo.nextprime(d) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
N = b^m # Number of points | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pad = m | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Unrandomized low discrepency sequence | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x_faure = QuasiMonteCarlo.sample(N, d, FaureSample()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Randomized version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x_nus = randomize(x_faure, OwenScramble(base = b, pad = pad)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x_lms = randomize(x_faure, MatousekScramble(base = b, pad = pad)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x_digital_shift = randomize(x_faure, DigitalShift(base = b, pad = pad)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x_shift = randomize(x_faure, Shift()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x_uniform = rand(d, N) # plain i.i.d. uniform | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
```julia | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
using Plots | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Setting I like for plotting | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
default(fontfamily="Computer Modern", linewidth=1, label=nothing, grid=true, framestyle=:default) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Plot the resulting sequences along dimensions `1` and `3`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
```julia | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
begin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d1 = 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d2 = 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sequences = [x_uniform, x_faure, x_shift, x_digital_shift, x_lms, x_nus] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
names = ["Uniform", "Faure (unrandomized)", "Shift", "Digital Shift", "Linear Matrix Scrambling", "Nested Uniform Scrambling"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
p = [plot(thickness_scaling=1.5, aspect_ratio=:equal) for i in sequences] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (i, x) in enumerate(sequences) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
scatter!(p[i], x[d1, :], x[d2, :], ms=0.9, c=1, grid=false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
title!(names[i]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xlims!(p[i], (0, 1)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ylims!(p[i], (0, 1)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
yticks!(p[i], [0, 1]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xticks!(p[i], [0, 1]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hline!(p[i], range(0, 1, step=1 / 4), c=:gray, alpha=0.2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vline!(p[i], range(0, 1, step=1 / 4), c=:gray, alpha=0.2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hline!(p[i], range(0, 1, step=1 / 2), c=:gray, alpha=0.8) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vline!(p[i], range(0, 1, step=1 / 2), c=:gray, alpha=0.8) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
plot(p..., size=(1500, 900)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ChrisRackauckas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![Different randomize methods of the same initial set of points](img/various_randomization.svg) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Faure nets and scrambled versions of Faure nets are digital $(t,d,m)$-net ([see this nice book by A. Owen](https://artowen.su.domains/mc/qmcstuff.pdf)). It basically means that they have strong equipartition properties. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Here we can (visually) verify that with Nested Uniform Scrambling (it also works with Linear Matrix Scrambling and Digital Shift). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
You must see one point per rectangle of volume $1/b^m$. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
```julia | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
begin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d1 = 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d2 = 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x = x_nus | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
p = [plot(thickness_scaling=1.5, aspect_ratio=:equal) for i in 0:m] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for i in 0:m | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
j = m - i | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xᵢ = range(0, 1, step=1 / b^(i)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xⱼ = range(0, 1, step=1 / b^(j)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
scatter!(p[i+1], x[d1, :], x[d2, :], ms=2, c=1, grid=false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xlims!(p[i+1], (0, 1.01)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ylims!(p[i+1], (0, 1.01)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
yticks!(p[i+1], [0, 1]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xticks!(p[i+1], [0, 1]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hline!(p[i+1], xᵢ, c=:gray, alpha=0.2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vline!(p[i+1], xⱼ, c=:gray, alpha=0.2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
plot(p..., size=(1500, 900)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![All the different elementary rectangle contain only one points](img/equidistribution.svg) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
""" | ||
KroneckerSample(generator::AbstractVector) <: SamplingAlgorithm | ||
KroneckerSample(generator::AbstractVector) <: DeterministicSamplingAlgorithm | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the reason for introducing the "Deterministic Sampling Algorithm" type? I'm not sure we need different types for the two kinds of algorithms, given you can turn a deterministic algorithm into a randomized one quite easily. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree I should document that at some point to clarify. If we were to implement fast scrambled Sobol like in this paper you mentioned, then we would classify it as RandomAlgo as the randomization is done while creating the sequence. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn’t the same algorithm applicable for both sets of matrices? In both cases we can take . I know the current implementation doesn’t randomize while creating the sequence, but creating multiple sequences with a randomizer other than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I first introduced that to keep the default with The second reasons, is that the way I coded
Third, (but again this is personal taste) I find it nice to classify algo by random or deterministic nature. (Especially for people not very familiar with QMC?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that makes sense. Looks good! |
||
|
||
A Kronecker sequence is a point set generated using a vector and equation: | ||
`x[i] = i * generator .% 1` | ||
|
@@ -19,25 +19,26 @@ References: | |
Leobacher, G., & Pillichshammer, F. (2014). *Introduction to quasi-Monte Carlo integration and applications.* Switzerland: Springer International Publishing. | ||
https://link.springer.com/content/pdf/10.1007/978-3-319-03425-6.pdf | ||
""" | ||
struct KroneckerSample{V <: Union{AbstractVector, Missing}} <: SamplingAlgorithm | ||
generator::V | ||
Base.@kwdef struct KroneckerSample{V <: Union{AbstractVector, Missing}} <: | ||
DeterministicSamplingAlgorithm | ||
generator::V = missing | ||
R::RandomizationMethod = NoRand() | ||
end | ||
|
||
KroneckerSample() = KroneckerSample(missing) | ||
function KroneckerSample(d::Integer, T = Float64) | ||
function KroneckerSample(d::Integer, R = NoRand(), T = Float64) | ||
ratio = harmonious(d, 2eps(T)) | ||
generator = [ratio^i for i in 1:d] | ||
return KroneckerSample(generator) | ||
return KroneckerSample(generator, R) | ||
end | ||
|
||
function sample(n::Integer, d::Integer, ::KroneckerSample{Missing}, T = Float64) | ||
return sample(n, d, KroneckerSample(d, T)) | ||
function sample(n::Integer, d::Integer, S::KroneckerSample{Missing}, T = Float64) | ||
return sample(n, d, KroneckerSample(d, S.R, T)) | ||
end | ||
|
||
function sample(n::Integer, d::Integer, k::KroneckerSample{V}, | ||
T) where {V <: AbstractVector} | ||
@assert eltype(V)==T "Sample type must match generator type." | ||
return sample(n, d, k) | ||
return randomize(sample(n, d, k), k.R) | ||
end | ||
|
||
function sample(n::Integer, d::Integer, k::KroneckerSample{V}) where {V <: AbstractVector} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this addition necessary? It looks like it's only a test dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we keep
istms
inscr
as I suggested in another comment, we need to keep that oneThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
istms
is neat, but we don’t want to add new dependencies for it, especially heavy ones likeIntervalArithmetic
. I’d prefer movingistms
to the tests.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not too concerned with dependency in general, so of course do as you see fit for this package.
Maybe some day we could do a
QuasiMonteCarloUI.jl
package with this function and other discrepancy measurements, something practitioners would not care too much about, but theoretician would like.