• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wexlergroup / FreeBird.jl / 12564742604

31 Dec 2024 11:01PM UTC coverage: 10.227% (+0.03%) from 10.194%
12564742604

push

github

web-flow
Merge pull request #68 from wexlergroup/hotfix/mc-random-moves

Hotfix/mc random moves

0 of 5 new or added lines in 2 files covered. (0.0%)

3 existing lines in 1 file now uncovered.

126 of 1232 relevant lines covered (10.23%)

0.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/SamplingSchemes/nested_sampling.jl
1
"""
2
    mutable struct NestedSamplingParameters <: SamplingParameters
3

4
The `NestedSamplingParameters` struct represents the parameters used in the nested sampling scheme.
5

6
# Fields
7
- `mc_steps::Int64`: The number of total Monte Carlo moves to perform.
8
- `initial_step_size::Float64`: The initial step size, which is the fallback step size if MC routine fails to accept a move.
9
- `step_size::Float64`: The on-the-fly step size used in the sampling process.
10
- `step_size_lo::Float64`: The lower bound of the step size.
11
- `step_size_up::Float64`: The upper bound of the step size.
12
- `fail_count::Int64`: The number of failed MC moves in a row.
13
- `allowed_fail_count::Int64`: The maximum number of failed MC moves allowed before resetting the step size.
14

15
"""
16
mutable struct NestedSamplingParameters <: SamplingParameters
17
    mc_steps::Int64
18
    initial_step_size::Float64
19
    step_size::Float64
20
    step_size_lo::Float64
21
    step_size_up::Float64
22
    fail_count::Int64
23
    allowed_fail_count::Int64
24
end
25

26
mutable struct LatticeNestedSamplingParameters <: SamplingParameters
27
    mc_steps::Int64
28
    energy_perturbation::Float64
29
    fail_count::Int64
30
    allowed_fail_count::Int64
31
end
32

33

34

35
"""
36
    abstract type MCRoutine
37

38
An abstract type representing a Monte Carlo routine.
39
"""
40
abstract type MCRoutine end
41

42
"""
43
    struct MCRandomWalkMaxE <: MCRoutine
44
A type for generating a new walker by performing a random walk for decorrelation on the highest-energy walker.
45
"""
46
struct MCRandomWalkMaxE <: MCRoutine end
47

48
"""
49
    struct MCRandomWalkClone <: MCRoutine
50
A type for generating a new walker by cloning an existing walker and performing a random walk for decorrelation.
51
"""
52
struct MCRandomWalkClone <: MCRoutine end
53

54
"""
55
    struct MCNewSample <: MCRoutine
56
A type for generating a new walker from a random configuration. Currently, it is intended to use this routine for lattice gas systems.
57
"""
58
struct MCNewSample <: MCRoutine end
59

60

61

62

63
"""
64
    sort_by_energy!(liveset::LJAtomWalkers)
65

66
Sorts the walkers in the liveset by their energy in descending order.
67

68
# Arguments
69
- `liveset::LJAtomWalkers`: The liveset of walkers to be sorted.
70

71
# Returns
72
- `liveset::LJAtomWalkers`: The sorted liveset.
73
"""
74
function sort_by_energy!(liveset::AbstractLiveSet)
×
75
    sort!(liveset.walkers, by = x -> x.energy, rev=true)
×
76
    # println("after sort ats[1].system_data.energy: ", ats[1].system_data.energy)
77
    return liveset
×
78
end
79

80
"""
81
    update_iter!(liveset::AtomWalkers)
82

83
Update the iteration count for each walker in the liveset.
84

85
# Arguments
86
- `liveset::AtomWalkers`: The set of walkers to update.
87

88
"""
89
function update_iter!(liveset::AbstractLiveSet)
×
90
    for at in liveset.walkers
×
91
        at.iter += 1
×
92
    end
×
93
end
94

95

96
"""
97
    nested_sampling_step!(liveset::AtomWalkers, ns_params::NestedSamplingParameters, mc_routine::MCRandomWalk)
98

99
Perform a single step of the nested sampling algorithm using the Monte Carlo random walk routine.
100

101
Arguments
102
- `liveset::AtomWalkers`: The set of atom walkers.
103
- `ns_params::NestedSamplingParameters`: The parameters for nested sampling.
104
- `mc_routine::MCRandomWalk`: The Monte Carlo random walk routine. Currently within this function, the random walk is only applied to the highest-energy walker, i.e., the one being culled.
105

106
Returns
107
- `iter`: The iteration number after the step.
108
- `emax`: The highest energy recorded during the step.
109
- `liveset`: The updated set of atom walkers.
110
- `ns_params`: The updated nested sampling parameters.
111
"""
112
function nested_sampling_step!(liveset::AtomWalkers, ns_params::NestedSamplingParameters, mc_routine::MCRoutine)
×
113
    sort_by_energy!(liveset)
×
114
    ats = liveset.walkers
×
115
    lj = liveset.lj_potential
×
116
    iter::Union{Missing,Int} = missing
×
117
    emax::Union{Missing,typeof(0.0u"eV")} = liveset.walkers[1].energy
×
118
    if mc_routine isa MCRandomWalkMaxE
×
119
        to_walk = deepcopy(ats[1])
×
120
    elseif mc_routine isa MCRandomWalkClone
×
121
        to_walk = deepcopy(rand(ats[2:end]))
×
122
    else
123
        error("Unsupported MCRoutine type: $mc_routine")
×
124
    end
125
    accept, rate, at = MC_random_walk!(ns_params.mc_steps, to_walk, lj, ns_params.step_size, emax)
×
126
    @info "iter: $(liveset.walkers[1].iter), acceptance rate: $rate, emax: $emax, is_accepted: $accept, step_size: $(ns_params.step_size)"
×
127
    if accept
×
128
        push!(ats, at)
×
129
        popfirst!(ats)
×
130
        update_iter!(liveset)
×
131
        ns_params.fail_count = 0
×
132
        iter = liveset.walkers[1].iter
×
133
    else
134
        @warn "Failed to accept MC move"
×
135
        emax = missing
×
136
        ns_params.fail_count += 1
×
137
    end
138
    adjust_step_size(ns_params, rate)
×
139
    return iter, emax, liveset, ns_params
×
140
end
141

142
"""
143
    nested_sampling_step!(liveset::LatticeGasWalkers, ns_params::LatticeNestedSamplingParameters, mc_routine::MCRoutine; accept_same_config::Bool=true)
144

145
Perform a single step of the nested sampling algorithm.
146

147
This function takes a `liveset` of lattice gas walkers, `ns_params` containing the parameters for nested sampling, and `mc_routine` representing the Monte Carlo 
148
routine for generating new samples. It performs a single step of the nested sampling algorithm by updating the liveset with a new walker.
149

150
## Arguments
151
- `liveset::LatticeGasWalkers`: The liveset of lattice gas walkers.
152
- `ns_params::LatticeNestedSamplingParameters`: The parameters for nested sampling.
153
- `mc_routine::MCRoutine`: The Monte Carlo routine for generating new samples.
154

155
## Returns
156
- `iter`: The iteration number of the liveset after the step.
157
- `emax`: The maximum energy of the liveset after the step.
158
"""
159
function nested_sampling_step!(liveset::LatticeGasWalkers, 
×
160
                               ns_params::LatticeNestedSamplingParameters, 
161
                               mc_routine::MCRoutine)
UNCOV
162
    sort_by_energy!(liveset)
×
163
    ats = liveset.walkers
×
164
    h = liveset.hamiltonian
×
165
    iter::Union{Missing,Int} = missing
×
166
    emax::Union{Missing,Float64} = liveset.walkers[1].energy.val
×
167
    if mc_routine isa MCRandomWalkMaxE
×
168
        to_walk = deepcopy(ats[1])
×
169
    elseif mc_routine isa MCRandomWalkClone
×
170
        to_walk = deepcopy(rand(ats[2:end]))
×
171
    else
172
        error("Unsupported MCRoutine type: $mc_routine")
×
173
    end
174
    accept, rate, at = MC_random_walk!(ns_params.mc_steps, to_walk, h, emax; energy_perturb=ns_params.energy_perturbation)
×
175

176
    @info "iter: $(liveset.walkers[1].iter), acceptance rate: $rate, emax: $emax, is_accepted: $accept"
×
177
    if accept
×
178
        push!(ats, at)
×
179
        popfirst!(ats)
×
180
        update_iter!(liveset)
×
181
        ns_params.fail_count = 0
×
182
        iter = liveset.walkers[1].iter
×
183
    else
184
        @warn "Failed to accept MC move"
×
185
        emax = missing
×
186
        ns_params.fail_count += 1
×
187
    end
188
    # adjust_step_size(ns_params, rate)
189
    return iter, emax, liveset, ns_params
×
190
end
191

192
"""
193
    nested_sampling_step!(liveset::LatticeGasWalkers, ns_params::LatticeNestedSamplingParameters, mc_routine::MCNewSample; accept_same_config::Bool=false)
194

195
Perform a single step of the nested sampling algorithm.
196

197
This function takes a `liveset` of lattice gas walkers, `ns_params` containing the parameters for nested sampling, and `mc_routine` representing the Monte Carlo routine for generating new samples. It performs a single step of the nested sampling algorithm by updating the liveset with a new walker.
198

199
## Arguments
200
- `liveset::LatticeGasWalkers`: The liveset of lattice gas walkers.
201
- `ns_params::LatticeNestedSamplingParameters`: The parameters for nested sampling.
202
- `mc_routine::MCNewSample`: The Monte Carlo routine for generating new samples.
203
- `accept_same_config::Bool=true`: A flag indicating whether to accept a new sample with the same configuration as an existing one.
204

205
## Returns
206
- `iter`: The iteration number of the liveset after the step.
207
- `emax`: The maximum energy of the liveset after the step.
208
- `liveset::LatticeGasWalkers`: The updated liveset after the step.
209
- `ns_params::LatticeNestedSamplingParameters`: The updated nested sampling parameters after the step.
210
"""
211
function nested_sampling_step!(liveset::LatticeGasWalkers, 
×
212
                               ns_params::LatticeNestedSamplingParameters, 
213
                               mc_routine::MCNewSample)
UNCOV
214
    sort_by_energy!(liveset)
×
215
    ats = liveset.walkers
×
216
    h = liveset.hamiltonian
×
217
    iter::Union{Missing,Int} = missing
×
218
    emax::Union{Missing,Float64} = liveset.walkers[1].energy.val
×
219

220
    to_walk = deepcopy(ats[1])
×
221

222
    accept, at = MC_new_sample!(to_walk, h, emax; energy_perturb=ns_params.energy_perturbation)
×
223

UNCOV
224
    @info "iter: $(liveset.walkers[1].iter), emax: $emax, is_accepted: $accept"
×
225
    if accept
×
226
        push!(ats, at)
×
227
        popfirst!(ats)
×
228
        update_iter!(liveset)
×
229
        ns_params.fail_count = 0
×
230
        iter = liveset.walkers[1].iter
×
231
    else
232
        @warn "Failed to accept MC move"
×
233
        emax = missing
×
234
        ns_params.fail_count += 1
×
235
    end
236
    # adjust_step_size(ns_params, rate)
237
    return iter, emax, liveset, ns_params
×
238
end
239

240
"""
241
    adjust_step_size(ns_params::NestedSamplingParameters, rate::Float64)
242

243
Adjusts the step size of the nested sampling algorithm based on the acceptance rate. 
244
    If the acceptance rate is greater than 0.75, the step size is increased by 1%. 
245
    If the acceptance rate is less than 0.25, the step size is decreased by 1%.
246

247
# Arguments
248
- `ns_params::NestedSamplingParameters`: The parameters of the nested sampling algorithm.
249
- `rate::Float64`: The acceptance rate of the algorithm.
250
- `range::Tuple{Float64, Float64}`: The range of acceptance rates for adjusting the step size. Default is (0.25, 0.75).
251

252
# Returns
253
- `ns_params::NestedSamplingParameters`: The updated parameters with adjusted step size.
254
"""
255
function adjust_step_size(ns_params::NestedSamplingParameters, rate::Float64; range::Tuple{Float64, Float64}=(0.25, 0.75))
×
256
    if rate > range[2] && ns_params.step_size < ns_params.step_size_up
×
257
        ns_params.step_size *= 1.05
×
258
    elseif rate < range[1] && ns_params.step_size > ns_params.step_size_lo
×
259
        ns_params.step_size *= 0.95
×
260
    end
261
    return ns_params
×
262
end
263

264

265

266
"""
267
    nested_sampling_loop!(liveset::AtomWalkers, ns_params::NestedSamplingParameters, n_steps::Int64, mc_routine::MCRoutine; args...)
268

269
Perform a nested sampling loop for a given number of steps.
270

271
# Arguments
272
- `liveset::AtomWalkers`: The initial set of walkers.
273
- `ns_params::NestedSamplingParameters`: The parameters for nested sampling.
274
- `n_steps::Int64`: The number of steps to perform.
275
- `mc_routine::MCRoutine`: The Monte Carlo routine to use.
276

277
# Returns
278
- `df`: A DataFrame containing the iteration number and maximum energy for each step.
279
- `liveset`: The updated set of walkers.
280
- `ns_params`: The updated nested sampling parameters.
281
"""
282
function nested_sampling_loop!(liveset::AtomWalkers, 
×
283
                                ns_params::NestedSamplingParameters, 
284
                                n_steps::Int64, 
285
                                mc_routine::MCRoutine,
286
                                save_strategy::DataSavingStrategy)
287
    df = DataFrame(iter=Int[], emax=Float64[])
×
288
    for i in 1:n_steps
×
289
        write_walker_every_n(liveset.walkers[1], i, save_strategy)
×
290
        iter, emax, liveset, ns_params = nested_sampling_step!(liveset, ns_params, mc_routine)
×
291
        @debug "n_step $i, iter: $iter, emax: $emax"
×
292
        if ns_params.fail_count >= ns_params.allowed_fail_count
×
293
            @warn "Failed to accept MC move $(ns_params.allowed_fail_count) times in a row. Reset step size!"
×
294
            ns_params.fail_count = 0
×
295
            ns_params.step_size = ns_params.initial_step_size
×
296
        end
297
        if !(iter isa typeof(missing))
×
298
            push!(df, (iter, emax.val))
×
299
        end
300
        write_df_every_n(df, i, save_strategy)
×
301
        write_ls_every_n(liveset, i, save_strategy)
×
302
    end
×
303
    return df, liveset, ns_params
×
304
end
305

306
"""
307
    nested_sampling_loop!(liveset::LatticeGasWalkers, ns_params::LatticeNestedSamplingParameters, n_steps::Int64, mc_routine::MCRoutine, save_strategy::DataSavingStrategy)
308

309
Perform a nested sampling loop on a lattice gas system for a given number of steps.
310

311
# Arguments
312
- `liveset::LatticeGasWalkers`: The initial set of walkers.
313
- `ns_params::LatticeNestedSamplingParameters`: The parameters for nested sampling.
314
- `n_steps::Int64`: The number of steps to perform.
315
- `mc_routine::MCRoutine`: The Monte Carlo routine to use.
316
- `save_strategy::DataSavingStrategy`: The strategy for saving data.
317

318
# Returns
319
- `df`: A DataFrame containing the iteration number and maximum energy for each step.
320
- `liveset`: The updated set of walkers.
321
- `ns_params`: The updated nested sampling parameters.
322
"""
323
function nested_sampling_loop!(liveset::LatticeGasWalkers,
×
324
                                ns_params::LatticeNestedSamplingParameters, 
325
                                n_steps::Int64, 
326
                                mc_routine::MCRoutine,
327
                                save_strategy::DataSavingStrategy)
328

329
    df = DataFrame(iter=Int[], emax=Float64[], config=Any[])
×
330
    for i in 1:n_steps
×
331
        # write_walker_every_n(liveset.walkers[1], i, save_strategy)
332
        
333
        config = liveset.walkers[1].configuration.components
×
334

NEW
335
        iter, emax, liveset, ns_params = nested_sampling_step!(liveset, ns_params, mc_routine)
×
336
        @debug "n_step $i, iter: $iter, emax: $emax"
×
337
        if ns_params.fail_count >= ns_params.allowed_fail_count
×
338
            @warn "Failed to accept MC move $(ns_params.allowed_fail_count) times in a row. Break!"
×
339
            ns_params.fail_count = 0
×
340
            break
×
341
        end
342
        if !(iter isa typeof(missing))
×
343
            push!(df, (iter, emax, config))
×
344
        end
345
        write_df_every_n(df, i, save_strategy)
×
346
        write_ls_every_n(liveset, i, save_strategy)
×
347
    end
×
348
    return df, liveset, ns_params
×
349
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc