CorrelationTrackers.jl

CorrelationTrackers.jl package has means to do fast updates of correlation functions calculated by CorrelationFunctions.Directional module in CorrelationFunctions.jl. Correlation functions are recalculated when you change an element of the underlying array. Currently supported functions are:

• Two-point function $S_2(r)$
• Lineal-path function $L_2(r)$
• Surface-surface function $F_{ss}(r)$
• Surface-void function $F_{sv}(r)$
• Cross-correlation function $S_2^{p_1p_2}(r)$

An update after one element of the underlying system was changed is about 10000 times faster compared to a full recalculation of the correlation functions for that system.

This package also supports fast rollback to the previous state if the last update must be rejected (via AnnealingRollbackAPI).

Examples

This is a step-by-step guide on how to use CorrelationTrackers.jl:

1. For the beginning, create your system you want to calculate correlation functions for. Let it be two-dimensional two-phase system with size 20x30.
2. Pick combinations of correlation function + phase which you want to track, e.g $S_2^{(1)}(r)$, $L_2^{(1)}(r)$ and $L_2^{(0)}(r)$. A combination of function and phase is represented by AbstractTracker types, e.g. S2Tracker(1) will track $S_2^{(1)}(r)$ function.
3. Create CorrelationTracker structure and access it as an ordinary array.
4. Obtain correlation functions at any time using functions from CorrelationFunctions.Directional. module.
using StatsBase
using PrettyTables
using Random
using CorrelationFunctions
using CorrelationTrackers

# Create our system
system = rand(MersenneTwister(348), 0:1, (20, 30))

# Suppose we want to track two-point function for phase 1 and lineal-path
# function for phase 0.
tracking = [S2Tracker(1), L2Tracker(0)]

# Create the tracker. It may require some time if your system is big.
tracker = CorrelationTracker(system; tracking = tracking)

# Do some phase flipping in both the original system and the tracker
indices = CartesianIndices(tracker)
state = MersenneTwister(123)
for n in 1:100
idx = rand(state, indices)
system[idx]  = 1 - system[idx]
tracker[idx] = 1 - tracker[idx]
end

pretty_table(stdout, hcat(Directional.s2(system,  1) |> mean,
Directional.s2(tracker, 1) |> mean,
Directional.l2(system,  0) |> mean,
Directional.l2(tracker, 0) |> mean);
header = ["S2 recalculated", "S2 tracked",
"L2 recalculated", "L2 tracked"])
┌─────────────────┬────────────┬─────────────────┬────────────┐
│ S2 recalculated │ S2 tracked │ L2 recalculated │ L2 tracked │
├─────────────────┼────────────┼─────────────────┼────────────┤
│        0.488333 │   0.488333 │        0.511667 │   0.511667 │
│        0.246957 │   0.246957 │        0.266087 │   0.266087 │
│        0.228182 │   0.228182 │        0.133636 │   0.133636 │
│        0.232381 │   0.232381 │       0.0580952 │  0.0580952 │
│           0.233 │      0.233 │           0.019 │      0.019 │
│        0.231579 │   0.231579 │      0.00526316 │ 0.00526316 │
│        0.228889 │   0.228889 │      0.00111111 │ 0.00111111 │
│        0.231765 │   0.231765 │             0.0 │        0.0 │
│           0.215 │      0.215 │             0.0 │        0.0 │
│            0.24 │       0.24 │             0.0 │        0.0 │
└─────────────────┴────────────┴─────────────────┴────────────┘

API

Types used to designate a correlation function

This is a part of AnnealingAPI.jl package since version 0.6.0.

Constructor and accessors

CorrelationTrackers.CorrelationTrackerType
CorrelationTracker(system   :: AbstractArray{T, N};
tracking = default_trackers(T),
periodic = false[, directions][, kwargs...])

Create correlation functions tracker.

Create correlation tracker for the array system. tracking is a vector of AbstractTracker types which specify correlation functions you wish to track. periodic and direction have the same meaning as in the most functions in CorrelationFunctions.jl package. Additional arguments such as len may be passed in kwargs.

Returned tracker supports interface of AbstractArray (e.g. you can perform element-wise read and write operations).

Examples

julia> let
system = rand(MersenneTwister(35), 0:1, (30, 10))
tracker = CorrelationTracker(system)
end
30×10 CorrelationTracker{Int64, 2, Matrix{Int64}}:
0  1  0  1  1  0  0  1  1  0
1  1  1  0  0  0  0  0  1  1
0  0  0  0  0  0  1  1  0  1
1  1  1  0  1  1  1  0  1  0
0  1  0  0  1  0  0  1  1  1
0  0  0  0  0  0  1  0  1  1
0  0  1  0  1  1  0  1  0  1
1  0  0  1  0  0  1  0  1  0
0  1  1  0  0  1  1  1  1  1
0  0  1  1  1  1  0  0  0  0
0  0  1  1  0  0  1  1  1  0
0  1  0  0  0  1  0  0  1  0
1  0  0  1  0  0  1  1  0  1
0  1  0  1  0  0  1  1  1  0
1  1  0  1  1  1  0  1  0  1
1  1  1  0  0  0  0  1  0  1
1  0  0  1  0  0  1  1  1  0
0  0  0  1  0  0  0  1  1  0
1  0  1  0  1  0  0  0  1  0
1  0  0  1  0  0  0  0  0  1
1  1  1  0  1  0  1  0  1  1
0  1  0  1  1  0  0  1  0  1
0  0  0  1  0  0  1  1  1  1
0  0  1  1  1  1  0  1  1  0
1  0  1  1  0  0  0  0  0  1
1  1  0  1  0  1  1  0  1  0
0  1  1  0  0  1  1  0  1  0
0  1  0  0  1  0  0  1  0  0
1  1  0  0  1  1  0  0  0  1
0  0  1  1  0  1  1  1  1  0
CorrelationTracker(system, like)

Create a CorrelationTracker on top of array system with parameters matching those in the tracker like.

CorrelationTrackers.default_trackersFunction
default_trackers(T)

Construct a vector of correlation functions which are tracked by default (that is $S_2^1(x)$, $L_2^1(x)$ and $L_2^0(x)$). T is the type of x.

The following functions are reexported from AnnealingAPI.jl since version 0.6.0.

AnnealingAPI.tracked_dataFunction
tracked_data(x :: AbstractArray)

Return an iterator over correlation function descriptors which are tracked by the tracker x.

Additional correlation functions not covered by AnnealingAPI.jl

AnnealingAPI.CCTrackerType
CCTracker(phase1, phase2)

Descriptor for cross-corelation function for the phases phase1 and phase2.

NB: Cross-correlation function does not commute, i.e. CCTracker(phase1, phase2) and CCTracker(phase2, phase1) track different functions.

CorrelationTrackers.cross_correlationFunction
cross_correlation(tracker :: CorrelationTracker, phase1, phase2)

Return precalculated values of cross correlation function for phases phase1 and phase2.

Extrapolating to other dimensions and directions

Two or more CorrelationTracker objects can be extrapolated to new dimensions and/or directions. For this purpose, an object of type ExtrapolatedData is created which loses the underlying array but preserves tracked correlation functions of the original CorrelationTracker object plus holds extrapolated data. ExtrapolatedData is read-only, which means you cannot call update_corrfns! on it.

CorrelationTrackers.ExtrapolatedDataType
ExtrapolatedData(tracker, dimensions, directions)

Extrapolate correlation functions to other dimensions and/or directions. Correlation functions are defined for objects of ExtrapolatedData type as they are defined for CorrelationTrackers.

Example

julia> begin
a = rand(MersenneTwister(1), 0:1, (20, 20));
tracker = CorrelationTracker(a; periodic = true);
D.s2(tracker, 0)
end
┌────────┬────────┐
│      x │      y │
├────────┼────────┤
│ 0.4975 │ 0.4975 │
│  0.225 │ 0.2325 │
│  0.265 │   0.25 │
│   0.24 │   0.25 │
│  0.235 │  0.245 │
│ 0.2525 │ 0.2275 │
│ 0.2525 │ 0.2675 │
│ 0.2425 │ 0.2475 │
│  0.245 │  0.235 │
│ 0.2575 │ 0.2475 │
└────────┴────────┘
julia> begin
extra = ExtrapolatedData(tracker, 3, [:x, :y, :z, :xyz])
D.s2(extra, 0)
end
┌────────┬────────┬─────────┬──────────┐
│      x │      y │       z │      xyz │
├────────┼────────┼─────────┼──────────┤
│ 0.4975 │ 0.4975 │  0.4975 │   0.4975 │
│  0.225 │ 0.2325 │ 0.22875 │ 0.249796 │
│  0.265 │   0.25 │  0.2575 │ 0.242679 │
│   0.24 │   0.25 │   0.245 │ 0.243923 │
│  0.235 │  0.245 │    0.24 │ 0.246077 │
│ 0.2525 │ 0.2275 │    0.24 │ 0.248253 │
│ 0.2525 │ 0.2675 │    0.26 │ 0.269904 │
│ 0.2425 │ 0.2475 │   0.245 │ 0.291554 │
│  0.245 │  0.235 │    0.24 │ 0.313205 │
│ 0.2575 │ 0.2475 │  0.2525 │ 0.334856 │
└────────┴────────┴─────────┴──────────┘
ExtrapolatedData(extrapolated_data1, extrapolated_data2)

Return ExtrapolatedData object which contains correlation statistics from both extrapolated_data1 and extrapolated_data2. The two input objects must share the same properties such as the shape of underlying data, tracked functions, directions and so on.

Caveats

Currently the functions from CorrelationFunctions.jl package return internal structures of supplied tracker. Do not modify returned values. This behavior can be changed to a safer one in the future.

Phase argument to SSTracker and SVTracker is currently ignored. It should be OK as long as tracked system is two-phase.