@@ -7,7 +7,7 @@ contains variables with uncertainties. In very simple cases this is
...
@@ -7,7 +7,7 @@ contains variables with uncertainties. In very simple cases this is
just a central value and an error
just a central value and an error
```@repl gs
```@repl gs
using ADerrors
using ADerrors
a = uwreal([1.0, 0.1], 1) # 1.0 +/- 0.1
a = uwreal([1.0, 0.1], "Var with error") # 1.0 +/- 0.1
```
```
But it also supports the case where the uncertainty comes from Monte
But it also supports the case where the uncertainty comes from Monte
Carlo measurements
Carlo measurements
...
@@ -23,10 +23,10 @@ for i in 2:1000
...
@@ -23,10 +23,10 @@ for i in 2:1000
end
end
end
end
b = uwreal(x.^2, 200)
b = uwreal(x.^2, "Random walk ensemble in [-1,1]")
c = uwreal(x.^4, 200)
c = uwreal(x.^4, "Random walk ensemble in [-1,1]")
```
```
Correlations between variables are treated consistently. Each call to `uwreal` contains an ensemble `ID` tag. In the previous examples `a` has been measured on ensemble `ID`1, while both `b` and `c` have been measured on ensemble `ID` 200. Monte Carlo measurements with the same `ID` tag are assumed to be measured on the same configurations: `b` and `c` above are statistically correlated, while `a` will be uncorrelated with both `b` and `c`.
Correlations between variables are treated consistently. Each call to `uwreal` contains an ensemble `ID` tag. In the previous examples `a` has been measured on ensemble `ID``Var with error`, while both `b` and `c` have been measured on ensemble `ID``Random walk ensemble in [-1,1]`. Monte Carlo measurements with the same `ID` tag are assumed to be measured on the same configurations: `b` and `c` above are statistically correlated, while `a` will be uncorrelated with both `b` and `c`.
One can perform operations with `uwreal` variables as if there were normal floats
One can perform operations with `uwreal` variables as if there were normal floats
```@repl gs
```@repl gs
...
@@ -45,7 +45,7 @@ A call to `uwerr` will apply the ``\Gamma``-method to MC ensembles. `ADerrors.jl
...
@@ -45,7 +45,7 @@ A call to `uwerr` will apply the ``\Gamma``-method to MC ensembles. `ADerrors.jl
println("Details on variable d: ")
println("Details on variable d: ")
details(d)
details(d)
```
```
Here we can see that there are two ensembles contributing to the uncertainty in `d`. We recognize this as `d` being a function of both `a` (measured on ensemble 1), and `b` and `c`, measured on ensemble 200. Most of the error in `d` comes in fact from ensemble 200.
Here we can see that there are two ensembles contributing to the uncertainty in `d`. We recognize this as `d` being a function of both `a` (measured on ensemble `Var with error`), and `b` and `c`, measured on ensemble `Random walk ensemble in [-1,1]`. Most of the error in `d` comes in fact from ensemble `Random walk ensemble in [-1,1]`.
Note that one does not need to use `uwerr` on a variable unless one is interested in the error on that variable. For example, continuing with the previous example
Note that one does not need to use `uwerr` on a variable unless one is interested in the error on that variable. For example, continuing with the previous example
x4 = uwreal(x[2:2:10000].^4, 1001, collect(2:2:10000), "Random walk in [-1,1]")
```
```
the variables `x2` and `x4` are normal `uwreal` variables, and one can work with them as with any other variable. Note however that the automatic determination of the summation window can fail in these cases, because the autocorrelation function with missing measurements can be very complicated. For example
the variables `x2` and `x4` are normal `uwreal` variables, and one can work with them as with any other variable. Note however that the automatic determination of the summation window can fail in these cases, because the autocorrelation function with missing measurements can be very complicated. For example
In this case `uwerr` complains because with the automatically chosen window the variance for ensemble with ID 1001 is negative. Let's have a look at the normalized autocorrelation function
In this case `uwerr` complains because with the automatically chosen window the variance for ensemble with ID 1001 is negative. Let's have a look at the normalized autocorrelation function
```@repl gaps
```@repl gaps
iw = window(rat, 1001)
iw = window(rat, "Random walk in [-1,1]")
r = rho(rat, 1001);
r = rho(rat, "Random walk in [-1,1]");
dr = drho(rat, 1001);
dr = drho(rat, "Random walk in [-1,1]");
plot(collect(1:100),
plot(collect(1:100),
r[1:100],
r[1:100],
yerr = dr[1:100],
yerr = dr[1:100],
...
@@ -166,7 +165,7 @@ savefig("rat_cf.png") # hide
...
@@ -166,7 +165,7 @@ savefig("rat_cf.png") # hide
The normalized autocorrelation function is oscillating, and the automatically chosen window is 2, producing a negative variance! We better fix the window to 50 for this case
The normalized autocorrelation function is oscillating, and the automatically chosen window is 2, producing a negative variance! We better fix the window to 50 for this case
```@repl gaps
```@repl gaps
wpm = Dict{Int64, Vector{Float64}}()
wpm = Dict{Int64, Vector{Float64}}()
wpm[1001] = [50.0, -1.0, -1.0, -1.0]
wpm["Random walk in [-1,1]"] = [50.0, -1.0, -1.0, -1.0]
uwerr(rat, wpm) # repeat error analysis with our choice (window=50)
uwerr(rat, wpm) # repeat error analysis with our choice (window=50)
println("Ratio: ", rat)
println("Ratio: ", rat)
```
```
...
@@ -175,9 +174,9 @@ Note however that it is very difficult to anticipate which observables will have
...
@@ -175,9 +174,9 @@ Note however that it is very difficult to anticipate which observables will have
```@repl gaps
```@repl gaps
prod = x2*x4
prod = x2*x4
uwerr(prod)
uwerr(prod)
iw = window(prod, 1001)
iw = window(prod, "Random walk in [-1,1]")
r = rho(prod, 1001);
r = rho(prod, "Random walk in [-1,1]");
dr = drho(prod, 1001);
dr = drho(prod, "Random walk in [-1,1]");
plot(collect(1:2*iw),
plot(collect(1:2*iw),
r[1:2*iw],
r[1:2*iw],
yerr = dr[1:2*iw],
yerr = dr[1:2*iw],
...
@@ -197,11 +196,13 @@ All observables are stored in a single `BDIO` record of type `BDIO_BIN_GENERIC`.
...
@@ -197,11 +196,13 @@ All observables are stored in a single `BDIO` record of type `BDIO_BIN_GENERIC`.
- ndata (`Vector{Int32}(neid)`): The length of each ensemble.
- ndata (`Vector{Int32}(neid)`): The length of each ensemble.
- nrep (`Vector{Int32}(neid)`): The number of replica of each enemble.
- nrep (`Vector{Int32}(neid)`): The number of replica of each enemble.
- vrep (`Vector{Int32}`): The replica vector for each ensemble.
- vrep (`Vector{Int32}`): The replica vector for each ensemble.
- ids (`Vector{Int32}(neid)`): The ensemble `ID`'s.
- ids (`Vector{Int32}(neid)`): The ensemble numeric `ID`'s.
- nt (`Vector{Int32}(neid)`): Half the largest replica of each ensemble.
- nt (`Vector{Int32}(neid)`): Half the largest replica of each ensemble.
- zero (`Vector{Float64}(neid)`): just `neid` zeros.
- zero (`Vector{Float64}(neid)`): just `neid` zeros.
- four (`Vector{Float64}(neid)`): just `neid` fours.
- four (`Vector{Float64}(neid)`): just `neid` fours.
- delta (`Vector{Float64}`): The fluctuations for each ensemble.
- delta (`Vector{Float64}`): The fluctuations for each ensemble.
- name (NULL terminated `String`): A description of the observable.
-`ID` tags: A list of `neid` tuples `(Int34, String)` that maps each numeric `ID` to an ensemble tag. All strings are NULL terminated.
!!! alert
!!! alert
Obviously this weird format is what it is for some legacy reasons, but it is strongly encouraged that new implementations respect this standard with all its weirdness.
Obviously this weird format is what it is for some legacy reasons, but it is strongly encouraged that new implementations respect this standard with all its weirdness.
Returns an `uwreal` data type. Depending on the first argument, the `uwreal` stores the following information:
Returns an `uwreal` data type. Depending on the first argument, the `uwreal` stores the following information:
- Input is a single `Float64`. In this case the variable acts in exactly the same way as a real number. This is understood as a quantity with zero error.
- Input is a single `Float64`. In this case the variable acts in exactly the same way as a real number. This is understood as a quantity with zero error.
- Input is a 2 element Vector of `Float64` `[value, error]`. In this case the data is understood as `value +/- error`.
- Input is a 2 element Vector of `Float64` `[value, error]`. In this case the data is understood as `value +/- error`.
- Input is a Vector of `Float64` of length larger than 4. In this case the data is understood as consecutive measurements of an observable in a Monte Carlo (MC) simulation.
- Input is a Vector of `Float64` of length larger than 4. In this case the data is understood as consecutive measurements of an observable in a Monte Carlo (MC) simulation.
In the last two cases, an ensemble `ID` is required as input. Data with the same `ID` are considered as correlated (i.e. fully correlated for the case of a `value +/- error` observables measured on the same sample for the case of data from a MC simulation). For example:
In the last two cases, an ensemble `ID` is required as input. Data with the same `ID` are considered as correlated (i.e. fully correlated for the case of a `value +/- error` observables measured on the same sample for the case of data from a MC simulation). The preferred way to input the ensemble tag is via a `String` that uniquely identifies the ensemble, but an integer is also supported for legacy reasons. For example:
```@example
```@example
using ADerrors # hide
using ADerrors # hide
a = uwreal([1.2, 0.2], 12) # a = 1.2 +/- 0.2
a = uwreal([1.2, 0.2], "Simplevarwitherror") # a = 1.2 +/- 0.2
b = uwreal([1.2, 0.2], 12) # b = 1.2 +/- 0.2
b = uwreal([1.2, 0.2], "Simplevarwitherror") # b = 1.2 +/- 0.2
c = uwreal([1.2, 0.2], 2000) # c = 1.2 +/- 0.2
c = uwreal([1.2, 0.2], "Anothervarwitherror") # c = 1.2 +/- 0.2
d = a-b
d = a-b
uwerr(d)
uwerr(d)
...
@@ -674,7 +734,7 @@ println("e has non zero error because a and c are independent", e)
...
@@ -674,7 +734,7 @@ println("e has non zero error because a and c are independent", e)
using ADerrors # hide
using ADerrors # hide
# 1000 measurements in three replica of lengths
# 1000 measurements in three replica of lengths
# 500, 100 and 400
# 500, 100 and 400
a = uwreal(rand(1000), 12, [500, 100, 400])
a = uwreal(rand(1000), "Ensemblewiththreereplica", [500, 100, 400])
```
```
### Gaps in the measurements
### Gaps in the measurements
...
@@ -685,11 +745,11 @@ In some situations an observable is not measured in every configuration. In this
...
@@ -685,11 +745,11 @@ In some situations an observable is not measured in every configuration. In this
using ADerrors # hide
using ADerrors # hide
# Observable measured on the odd configurations
# Observable measured on the odd configurations
# 1, 3, 5, ..., 999 on an emsemble of length 1000
# 1, 3, 5, ..., 999 on an emsemble of length 1000
a = uwreal(rand(500), 12, collect(1:2:999), 1000)
a = uwreal(rand(500), "Observablewithgaps", collect(1:2:999), 1000)
# Observable measured on the first 900 configurations
# Observable measured on the first 900 configurations
# on the same emsemble
# on the same emsemble
b = uwreal(rand(900), 12, collect(1:900), 1000)
b = uwreal(rand(900), "Observablewithgaps", collect(1:900), 1000)
```
```
Note that in this case, if the ensemble has different replica, `sum(replica)` must match `nms`
Note that in this case, if the ensemble has different replica, `sum(replica)` must match `nms`
```@example
```@example
...
@@ -697,33 +757,78 @@ using ADerrors # hide
...
@@ -697,33 +757,78 @@ using ADerrors # hide
# Observable measured on the even configurations
# Observable measured on the even configurations
# 2, 4, 6, ..., 200 on an emsemble of length 200
# 2, 4, 6, ..., 200 on an emsemble of length 200
# with two replica of lengths 75, 125
# with two replica of lengths 75, 125
a = uwreal(data_a[1:500], 123, [75, 125], collect(2:2:200), 200)
a = uwreal(data_a[1:500], "Observablewithgapsinanensemblewithreplica", [75, 125], collect(2:2:200), 200)
An optional parameter `wpm` can be used to choose the summation window for the relevant autocorrelation functions. The situation is completely analogous to the case of error analysis of single variables.
An optional parameter `wpm` can be used to choose the summation window for the relevant autocorrelation functions. The situation is completely analogous to the case of error analysis of single variables.
Given a vector of `uwreal`, `a[:]` and a two dimensional array `M`, this routine computes ``{\rm tr}(MC)``, where ``C_{ij} = {\rm cov}(a[i], a[j])``.
Given a vector of `uwreal`, `a[:]` and a two dimensional symmtric positive definite array `M`, this routine computes ``{\rm tr}(MC)``, where ``C_{ij} = {\rm cov}(a[i], a[j])``.
```@example
```@example
using ADerrors, LinearAlgebra # hide
using ADerrors, LinearAlgebra # hide
a = uwreal([1.3, 0.01], 1) # 1.3 +/- 0.01
a = uwreal([1.3, 0.01], "Varwitherror1") # 1.3 +/- 0.01
b = uwreal([5.3, 0.23], 2) # 5.3 +/- 0.23
b = uwreal([5.3, 0.23], "Varwitherror2") # 5.3 +/- 0.23
c = uwreal(rand(2000), 3)
c = uwreal(rand(2000), "Whitenoiseensemble")
x = [a+b+sin(c), a-b+cos(c), c-b/a]
x = [a+b+sin(c), a-b+cos(c), c-b/a]
M = [1.0 0.2 0.1
M = [1.0 0.2 0.1
...
@@ -845,17 +952,27 @@ M = [1.0 0.2 0.1
...
@@ -845,17 +952,27 @@ M = [1.0 0.2 0.1
mcov = cov(x)
mcov = cov(x)
d = tr(mcov * M)
d = tr(mcov * M)
println("Betterbezero:", d -trcov(M, x))
println("Betterbezero:", d -trcov(M, x))
# Case of Monte Carlo data
An optional parameter `wpm` can be used to choose the summation window for the relevant autocorrelation functions. The situation is completely analogous to the case of error analysis of single variables.
Returns the value of tauint for the ensemble `id`. It is assumed that `uwerr` has been run on the variable and that `id` contributes to the observable `a`. Otherwise an error message is printed.
Returns the value of tauint for the ensemble `mcid`. It is assumed that `uwerr` has been run on the variable and that `mcid` contributes to the observable `a`. Otherwise an error message is printed. `mcid` can be either an `Int64` (the proper ensemble ID), or a `String` (the ensemble tag).
```@example
```@example
using ADerrors # hide
using ADerrors # hide
# Generate some correlated data
# Generate some correlated data
...
@@ -90,9 +90,9 @@ for i in 2:1000
...
@@ -90,9 +90,9 @@ for i in 2:1000
end
end
end
end
a = uwreal(x.^2, 666)
a = uwreal(x.^2, "Somesimpleensemble")
uwerr(a)
uwerr(a)
println("Erroranalysisresult:", a, "(tauint=", taui(a, 666), ")")
println("Erroranalysisresult:", a, "(tauint=", taui(a, "Somesimpleensemble"), ")")
```
```
"""
"""
function taui(a::uwreal,mcid::Int64)
function taui(a::uwreal,mcid::Int64)
...
@@ -105,9 +105,9 @@ function taui(a::uwreal, mcid::Int64)
...
@@ -105,9 +105,9 @@ function taui(a::uwreal, mcid::Int64)
end
end
"""
"""
dtaui(a::uwreal, id::Int64)
dtaui(a::uwreal, mcid)
Returns an estimate on the error of tauint for the ensemble `id`. It is assumed that `uwerr` has been run on the variable and that `id` contributes to the observable `a`. Otherwise an error message is printed.
Returns an estimate on the error of tauint for the ensemble `mcid`. It is assumed that `uwerr` has been run on the variable and that `mcid` contributes to the observable `a`. Otherwise an error message is printed.
@@ -137,9 +137,9 @@ function dtaui(a::uwreal, mcid::Int64)
...
@@ -137,9 +137,9 @@ function dtaui(a::uwreal, mcid::Int64)
end
end
"""
"""
window(a::uwreal, id::Int64)
window(a::uwreal, mcid)
Returns the summation window for the ensemble `id`. It is assumed that `uwerr` has been run on the variable and that `id` contributes to the observable `a`. Otherwise an error message is printed.
Returns the summation window for the ensemble `mcid`. It is assumed that `uwerr` has been run on the variable and that `mcid` contributes to the observable `a`. Otherwise an error message is printed.
```@example
```@example
using ADerrors # hide
using ADerrors # hide
# Generate some correlated data
# Generate some correlated data
...
@@ -153,10 +153,10 @@ for i in 2:1000
...
@@ -153,10 +153,10 @@ for i in 2:1000
end
end
end
end
a = uwreal(x.^2, 666)
a = uwreal(x.^2, "Somesimpleensemble")
uwerr(a)
uwerr(a)
println("Erroranalysisresult:", a,
println("Erroranalysisresult:", a,
"(window=", window(a, 666), ")")
"(window=", window(a, "Somesimpleensemble"), ")")
```
```
"""
"""
function window(a::uwreal,mcid::Int64)
function window(a::uwreal,mcid::Int64)
...
@@ -169,9 +169,9 @@ function window(a::uwreal, mcid::Int64)
...
@@ -169,9 +169,9 @@ function window(a::uwreal, mcid::Int64)
end
end
"""
"""
rho(a::uwreal, id::Int64)
rho(a::uwreal, mcid)
Returns the normalized autocorrelation function of `a` for the ensemble `id`. It is assumed that `uwerr` has been run on the variable and that `id` contributes to the observable `a`. Otherwise an error message is printed.
Returns the normalized autocorrelation function of `a` for the ensemble `mcid`. It is assumed that `uwerr` has been run on the variable and that `mcid` contributes to the observable `a`. Otherwise an error message is printed.
```@example
```@example
using ADerrors # hide
using ADerrors # hide
# Generate some correlated data
# Generate some correlated data
...
@@ -185,9 +185,9 @@ for i in 2:1000
...
@@ -185,9 +185,9 @@ for i in 2:1000
end
end
end
end
a = uwreal(x.^2, 666)
a = uwreal(x.^2, "Somesimpleensemble")
uwerr(a)
uwerr(a)
v = rho(a, 666)
v = rho(a, "Somesimpleensemble")
for i in 1:length(v)
for i in 1:length(v)
println(i, "", v[i])
println(i, "", v[i])
end
end
...
@@ -203,9 +203,9 @@ function rho(a::uwreal, mcid::Int64)
...
@@ -203,9 +203,9 @@ function rho(a::uwreal, mcid::Int64)
end
end
"""
"""
rho(a::uwreal, id::Int64)
drho(a::uwreal, mcid)
Returns an estimate of the error on the normalized autocorrelation function of `a` for the ensemble `id`. It is assumed that `uwerr` has been run on the variable and that `id` contributes to the observable `a`. Otherwise an error message is printed.
Returns an estimate of the error on the normalized autocorrelation function of `a` for the ensemble `mcid`. It is assumed that `uwerr` has been run on the variable and that `mcid` contributes to the observable `a`. Otherwise an error message is printed.
```@example
```@example
using ADerrors # hide
using ADerrors # hide
# Generate some correlated data
# Generate some correlated data
...
@@ -219,10 +219,10 @@ for i in 2:1000
...
@@ -219,10 +219,10 @@ for i in 2:1000
end
end
end
end
a = uwreal(x.^2, 666)
a = uwreal(x.^2, "Somesimpleensemble")
uwerr(a)
uwerr(a)
v = rho(a, 666)
v = rho(a, "Somesimpleensemble")
dv = drho(a, 666)
dv = drho(a, "Somesimpleensemble")
for i in 1:length(v)
for i in 1:length(v)
println(i, "", v[i], "+/-", dv[i])
println(i, "", v[i], "+/-", dv[i])
end
end
...
@@ -278,15 +278,33 @@ function read_bdio(fb, ws::wspace, mapids::Dict{Int64, Int64})
...
@@ -278,15 +278,33 @@ function read_bdio(fb, ws::wspace, mapids::Dict{Int64, Int64})
@@ -341,24 +365,21 @@ Write out a detailed information on the error of `a`.
...
@@ -341,24 +365,21 @@ Write out a detailed information on the error of `a`.
## Arguments
## Arguments
Optionally one can pass as a keyword argument (`io`) the `IO` stream to write to and a dictionary (`names`) that translates ensemble `ID`s into more human friendly `Strings`
Optionally one can pass as a keyword argument (`io`) the `IO` stream to write to.
## Example
## Example
```@example
```@example
using ADerrors # hide
using ADerrors # hide
a = uwreal(rand(2000), 120)
a = uwreal(rand(2000), "EnsembleA12")
b = uwreal([1.2, 0.023], 121)
b = uwreal([1.2, 0.023], "EnsembleXYZ")
c = uwreal([5.2, 0.03], 122)
c = uwreal([5.2, 0.03], "EnsembleRRR")
d = a + b - c
d = a + b - c
uwerr(d)
uwerr(d)
bnm = Dict{Int64, String}()
details(d)
bnm[120] = "Veryimportantensemble"
bnm[122] = "H12BK87"
details(d, bnm)
```
```
"""
"""
function details(a::uwreal,ws::wspace,io::IO=stdout,names::Dict{Int64,String}=Dict{Int64,String}())
function details(a::uwreal,ws::wspace,io::IO=stdout)
if(length(a.prop)==0)
if(length(a.prop)==0)
print(a.mean)
print(a.mean)
...
@@ -390,7 +411,7 @@ function details(a::uwreal, ws::wspace, io::IO=stdout, names::Dict{Int64, String
...
@@ -390,7 +411,7 @@ function details(a::uwreal, ws::wspace, io::IO=stdout, names::Dict{Int64, String
Returns a vector of `uwreal` such that their mean values are `avgs[:]` and their covariance is `Mcov[:,:]`. In order to construct these observables `n=length(avgs)` ensemble ID are used. These have to be specified in the vector `ids[:]`.
Returns a vector of `uwreal` such that their mean values are `avgs[:]` and their covariance is `Mcov[:,:]`. In order to construct these observables `n=length(avgs)` ensemble ID are used. These are generated either from the string `str` or have to be specified in the vector `ids[:]`.
Given a ``\chi^2(p, d)``, function of the fit parameters `p[:]` and the data `d[:]`, this routine return the fit parameters as `uwreal` type and optionally, the expected value of ``\chi^2(p, d)``.
Given a ``\chi^2(p, d)``, function of the fit parameters `p[:]` and the data `d[:]`, this routine return the fit parameters as `uwreal` type and optionally, the expected value of ``\chi^2(p, d)``.
...
@@ -215,6 +230,7 @@ Given a ``\chi^2(p, d)``, function of the fit parameters `p[:]` and the data `d[
...
@@ -215,6 +230,7 @@ Given a ``\chi^2(p, d)``, function of the fit parameters `p[:]` and the data `d[
where the function ``f_i(p)`` is an arbitrary function of the fit parameters. In simple words, the expected ``\chi^2(p, d)`` is determined assuming that the function ``\chi^2(p, d)`` is quadratic in the data.
where the function ``f_i(p)`` is an arbitrary function of the fit parameters. In simple words, the expected ``\chi^2(p, d)`` is determined assuming that the function ``\chi^2(p, d)`` is quadratic in the data.
- `xp`: A vector of `Float64`. The value of the fit parameters at the minima.
- `xp`: A vector of `Float64`. The value of the fit parameters at the minima.
- `data`: A vector of `uwreal`. The data whose fluctuations enter in the evaluation of the `chisq`.
- `data`: A vector of `uwreal`. The data whose fluctuations enter in the evaluation of the `chisq`.
- `wpm`: `Dict{Int64,Vector{Float64}}` or `Dict{String,Vector{Float64}}`. The criteria to determine the summation window. See the documentation on `uwerr` function for more details.
- `W`: A matrix. The weights that enter in the evaluation of the `chisq` function. If a vector is passed, the matrix is assumed to be diagonal (i.e. **uncorrelated** fit). If no weights are passed, the routines assumes that `W` is diagonal with entries given by the inverse errors squared of the data (i.e. the `chisq` is weighted with the errors of the data).
- `W`: A matrix. The weights that enter in the evaluation of the `chisq` function. If a vector is passed, the matrix is assumed to be diagonal (i.e. **uncorrelated** fit). If no weights are passed, the routines assumes that `W` is diagonal with entries given by the inverse errors squared of the data (i.e. the `chisq` is weighted with the errors of the data).
- `chi_exp`: Bool type. If false, do not compute the expected ``\chi^2(p, d)``.
- `chi_exp`: Bool type. If false, do not compute the expected ``\chi^2(p, d)``.