### Install Pragmastat Source: https://pragmastat.dev/py Install the library using pip. ```bash pip install pragmastat==14.0.1 ``` -------------------------------- ### Install Pragmastat via Go Source: https://pragmastat.dev/go Use the go get command to add the specific version of the library to your project. ```bash go get github.com/AndreyAkinshin/pragmastat/go/v14@v14.0.1 ``` -------------------------------- ### Sample Usage Examples Source: https://pragmastat.dev/sample Basic usage examples for selecting elements from a list and the identity case where selecting all elements returns the original order. ```text Rng("demo-sample").Sample([1, 2, 3, 4, 5], 3) ``` ```text r.Sample(x, n) = x ``` -------------------------------- ### Install Pragmastat from GitHub Source: https://pragmastat.dev/r Use the remotes package to install the Pragmastat library from the specified GitHub repository and subdirectory. ```R install.packages("remotes") # If 'remotes' is not installed remotes::install_github("AndreyAkinshin/pragmastat", subdir = "r/pragmastat", ref = "v14.0.1") library(pragmastat) ``` -------------------------------- ### Pragmastat Library Usage Demonstration Source: https://pragmastat.dev/go A complete example demonstrating one-sample and two-sample statistics, confirmatory comparisons, random number generation, and distribution sampling. Helper functions are used to handle errors during measurement and sample creation. ```go package main import ( "fmt" "log" pragmastat "github.com/AndreyAkinshin/pragmastat/go/v14" ) func mustM(val pragmastat.Measurement, err error) pragmastat.Measurement { if err != nil { log.Fatal(err) } return val } func mustB(val pragmastat.Bounds, err error) pragmastat.Bounds { if err != nil { log.Fatal(err) } return val } func mustS(val *pragmastat.Sample, err error) *pragmastat.Sample { if err != nil { log.Fatal(err) } return val } func mustT(val *pragmastat.Threshold, err error) *pragmastat.Threshold { if err != nil { log.Fatal(err) } return val } func mustP(val []pragmastat.Projection, err error) []pragmastat.Projection { if err != nil { log.Fatal(err) } return val } func main() { // --- One-Sample --- xVals := make([]float64, 200) for i := range xVals { xVals[i] = float64(i + 1) } x := mustS(pragmastat.NewSample(xVals)) fmt.Println(mustM(x.Center()).Value) // 100.5 fmt.Println(mustB(x.CenterBounds(1e-3))) // [86;115] fmt.Println(mustM(x.Spread()).Value) // 59 fmt.Println(mustB(x.SpreadBoundsWithSeed(1e-3, "demo"))) // [44;87] // --- Two-Sample --- sxVals := make([]float64, 200) for i := range sxVals { sxVals[i] = float64(i + 1) } syVals := make([]float64, 200) for i := range syVals { syVals[i] = float64(i + 101) } sx := mustS(pragmastat.NewSample(sxVals)) sy := mustS(pragmastat.NewSample(syVals)) fmt.Println(mustM(sx.Shift(sy)).Value) // -100 fmt.Println(mustB(sx.ShiftBounds(sy, 1e-3))) // [-120;-80] fmt.Println(mustM(sx.Ratio(sy)).Value) // 0.5008354224706336 fmt.Println(mustB(sx.RatioBounds(sy, 1e-3))) // [0.4066666666666668;0.5958333333333332] fmt.Println(mustM(sx.Disparity(sy)).Value) // -1.694915254237288 fmt.Println(mustB(sx.DisparityBoundsWithSeed(sy, 1e-3, "demo"))) // [-3.1025641025641026;-0.8494623655913979] // --- Confirmatory Comparison --- th1 := mustT(pragmastat.NewThreshold(pragmastat.MetricCenter, pragmastat.NewNumberMeasurement(50), 1e-3)) proj1 := mustP(pragmastat.Compare1(sx, []*pragmastat.Threshold{th1})) fmt.Println(proj1[0].Verdict) // greater th2 := mustT(pragmastat.NewThreshold(pragmastat.MetricShift, pragmastat.NewNumberMeasurement(0), 1e-3)) proj2 := mustP(pragmastat.Compare2(sx, sy, []*pragmastat.Threshold{th2})) fmt.Println(proj2[0].Verdict) // less // --- Randomization --- rng := pragmastat.NewRngFromString("demo-uniform") fmt.Println(rng.UniformFloat64()) // 0.2640554428629759 fmt.Println(rng.UniformFloat64()) // 0.9348534835582796 rng = pragmastat.NewRngFromString("demo-uniform-int") fmt.Println(rng.UniformInt64(0, 100)) // 41 rng = pragmastat.NewRngFromString("demo-sample") fmt.Println(pragmastat.RngSample(rng, []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 3)) // [3 8 9] rng = pragmastat.NewRngFromString("demo-resample") fmt.Println(pragmastat.RngResample(rng, []float64{1, 2, 3, 4, 5}, 7)) // [3 1 3 2 4 1 2] rng = pragmastat.NewRngFromString("demo-shuffle") fmt.Println(pragmastat.RngShuffle(rng, []float64{1, 2, 3, 4, 5})) // [4 2 3 5 1] // --- Distributions --- rng = pragmastat.NewRngFromString("demo-dist-additive") fmt.Println(pragmastat.NewAdditive(0, 1).Sample(rng)) // 0.1741044867956819 rng = pragmastat.NewRngFromString("demo-dist-multiplic") fmt.Println(pragmastat.NewMultiplic(0, 1).Sample(rng)) // 1.1273244602673853 rng = pragmastat.NewRngFromString("demo-dist-exp") fmt.Println(pragmastat.NewExp(1).Sample(rng)) // 0.6589065267276553 rng = pragmastat.NewRngFromString("demo-dist-power") fmt.Println(pragmastat.NewPower(1, 2).Sample(rng)) // 1.023677535537084 rng = pragmastat.NewRngFromString("demo-dist-uniform") fmt.Println(pragmastat.NewUniform(0, 10).Sample(rng)) // 6.54043657816832 } ``` -------------------------------- ### Install Pragmastat via Cargo Source: https://pragmastat.dev/rs Add the library to your project using the cargo command-line tool. ```bash cargo add pragmastat@14.0.1 ``` -------------------------------- ### Install Pragmastat via npm Source: https://pragmastat.dev/ts Use this command to add the library to your project dependencies. ```bash npm i pragmastat@14.0.1 ``` -------------------------------- ### Pragmastat Library Demonstration Source: https://pragmastat.dev/rs A comprehensive example covering one-sample and two-sample statistics, confirmatory comparisons, random number generation, probability distributions, and unit system management. ```rust use pragmastat::distributions::{Additive, Distribution, Exp, Multiplic, Power, Uniform}; use pragmastat::*; fn main() { // --- One-Sample (Sample-based API) --- let x = Sample::new((1..=200).map(|i| i as f64).collect()).unwrap(); println!("{}", center(&x).unwrap().value); // 100.5 let bounds = center_bounds(&x, 1e-3).unwrap(); println!("{{lower: {}, upper: {}}}", bounds.lower, bounds.upper); // {lower: 86, upper: 115} println!("{}", spread(&x).unwrap().value); // 59 let bounds = spread_bounds_with_seed(&x, 1e-3, "demo").unwrap(); println!("{{lower: {}, upper: {}}}", bounds.lower, bounds.upper); // {lower: 44, upper: 87} // --- Two-Sample (Sample-based API) --- let x = Sample::new((1..=200).map(|i| i as f64).collect()).unwrap(); let y = Sample::new((101..=300).map(|i| i as f64).collect()).unwrap(); println!("{}", shift(&x, &y).unwrap().value); // -100 let bounds = shift_bounds(&x, &y, 1e-3).unwrap(); println!("{{lower: {}, upper: {}}}", bounds.lower, bounds.upper); // {lower: -120, upper: -80} println!("{}", ratio(&x, &y).unwrap().value); // 0.5008354224706334 let bounds = ratio_bounds(&x, &y, 1e-3).unwrap(); println!("{{lower: {}, upper: {}}}", bounds.lower, bounds.upper); // {lower: 0.4066666666666668, upper: 0.5958333333333332} println!("{}", disparity(&x, &y).unwrap().value); // -1.694915254237288 let bounds = disparity_bounds_with_seed(&x, &y, 1e-3, "demo").unwrap(); println!("{{lower: {}, upper: {}}}", bounds.lower, bounds.upper); // {lower: -3.1025641025641026, upper: -0.8494623655913979} // --- Confirmatory Comparison --- let th = Threshold::new(Metric::Center, Measurement::number(50.0), 1e-3).unwrap(); println!("{}", compare1(&x, &[th]).unwrap()[0].verdict().as_str()); // greater let th = Threshold::new(Metric::Shift, Measurement::number(0.0), 1e-3).unwrap(); println!("{}", compare2(&x, &y, &[th]).unwrap()[0].verdict().as_str()); // less // --- Randomization --- let mut rng = Rng::from_string("demo-uniform"); println!("{}", rng.uniform_f64()); // 0.2640554428629759 println!("{}", rng.uniform_f64()); // 0.9348534835582796 let mut rng = Rng::from_string("demo-uniform-int"); println!("{}", rng.uniform_i64(0, 100)); // 41 let mut rng = Rng::from_string("demo-sample"); println!( "{:?}", rng.sample(&[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 3) ); // [3.0, 8.0, 9.0] let mut rng = Rng::from_string("demo-resample"); println!("{:?}", rng.resample(&[1.0, 2.0, 3.0, 4.0, 5.0], 7)); // [3.0, 1.0, 3.0, 2.0, 4.0, 1.0, 2.0] let mut rng = Rng::from_string("demo-shuffle"); println!("{:?}", rng.shuffle(&[1.0, 2.0, 3.0, 4.0, 5.0])); // [4.0, 2.0, 3.0, 5.0, 1.0] // --- Distributions --- let mut rng = Rng::from_string("demo-dist-additive"); println!("{}", Additive::new(0.0, 1.0).sample(&mut rng)); // 0.17410448679568188 let mut rng = Rng::from_string("demo-dist-multiplic"); println!("{}", Multiplic::new(0.0, 1.0).sample(&mut rng)); // 1.1273244602673853 let mut rng = Rng::from_string("demo-dist-exp"); println!("{}", Exp::new(1.0).sample(&mut rng)); // 0.6589065267276553 let mut rng = Rng::from_string("demo-dist-power"); println!("{}", Power::new(1.0, 2.0).sample(&mut rng)); // 1.023677535537084 let mut rng = Rng::from_string("demo-dist-uniform"); println!("{}", Uniform::new(0.0, 10.0).sample(&mut rng)); // 6.54043657816832 // --- Unit system --- let ms = MeasurementUnit::new("ms", "Time", "ms", "Millisecond", 1_000_000); let ns = MeasurementUnit::new("ns", "Time", "ns", "Nanosecond", 1); let s = Sample::with_unit(vec![1.0, 2.0, 3.0], ms).unwrap(); let converted = s.convert_to(&ns).unwrap(); println!("Converted: {:?}", converted.values()); // [1000000.0, 2000000.0, 3000000.0] let registry = UnitRegistry::standard(); let unit = registry.resolve("number").unwrap(); println!("Resolved: {}", unit.full_name()); // Number } ``` -------------------------------- ### Pragmastat Library Usage Demo Source: https://pragmastat.dev/kt Comprehensive examples covering one-sample and two-sample statistics, confirmatory comparisons, custom measurement units, randomization, and probability distributions. ```kotlin package dev.pragmastat.demo import dev.pragmastat.* import dev.pragmastat.distributions.* fun main() { // --- One-Sample --- val x = Sample.of((1..200).map { it.toDouble() }) println(center(x)) // 100.5 println(spread(x)) // 59.0 println(centerBounds(x, Probability(1e-3))) // Bounds(lower=86.0, upper=115.0, unit=...) println(spreadBounds(x, Probability(1e-3), "demo")) // Bounds(lower=44.0, upper=87.0, unit=...) // --- Two-Sample --- val sx = Sample.of((1..200).map { it.toDouble() }) val sy = Sample.of((101..300).map { it.toDouble() }) println(shift(sx, sy)) // -100.0 println(shiftBounds(sx, sy, Probability(1e-3))) // Bounds(lower=-120.0, upper=-80.0, unit=...) println(ratio(sx, sy)) // 0.5008354224706336 println(ratioBounds(sx, sy, Probability(1e-3))) // Bounds(lower=0.4066..., upper=0.5958..., unit=...) println(disparity(sx, sy)) // -1.694915254237288 println(disparityBounds(sx, sy, Probability(1e-3), "demo")) // Bounds(lower=-3.1025..., upper=-0.8494..., unit=...) // --- Confirmatory Comparison --- println(compare1(sx, listOf(Threshold(Metric.Center, Measurement(50.0), Probability(1e-3))))[0].verdict.toId()) // greater println(compare2(sx, sy, listOf(Threshold(Metric.Shift, Measurement(0.0), Probability(1e-3))))[0].verdict.toId()) // less // --- Custom units --- val ns = MeasurementUnit("ns", "Time", "ns", "Nanosecond", 1) val us = MeasurementUnit("us", "Time", "us", "Microsecond", 1000) val ms = MeasurementUnit("ms", "Time", "ms", "Millisecond", 1_000_000) val registry = UnitRegistry.standard() registry.register(ns) registry.register(us) registry.register(ms) val timeSample = Sample.of(listOf(100.0, 200.0, 300.0, 400.0, 500.0), ns) println(center(timeSample)) // 300 ns println(center(timeSample.convertTo(us))) // 0.3 us // --- Randomization --- var rng = Rng("demo-uniform") println(rng.uniformDouble()) // 0.2640554428629759 println(rng.uniformDouble()) // 0.9348534835582796 rng = Rng("demo-uniform-int") println(rng.uniformInt(0, 100)) // 41 rng = Rng("demo-sample") println(rng.sample(listOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), 3)) // [3.0, 8.0, 9.0] rng = Rng("demo-resample") println(rng.resample(listOf(1.0, 2.0, 3.0, 4.0, 5.0), 7)) // [3.0, 1.0, 3.0, 2.0, 4.0, 1.0, 2.0] rng = Rng("demo-shuffle") println(rng.shuffle(listOf(1.0, 2.0, 3.0, 4.0, 5.0))) // [4.0, 2.0, 3.0, 5.0, 1.0] // --- Distributions --- rng = Rng("demo-dist-additive") println(Additive(0.0, 1.0).sample(rng)) // 0.17410448679568188 rng = Rng("demo-dist-multiplic") println(Multiplic(0.0, 1.0).sample(rng)) // 1.1273244602673853 rng = Rng("demo-dist-exp") println(Exp(1.0).sample(rng)) // 0.6589065267276553 rng = Rng("demo-dist-power") println(Power(1.0, 2.0).sample(rng)) // 1.023677535537084 rng = Rng("demo-dist-uniform") println(Uniform(0.0, 10.0).sample(rng)) // 6.54043657816832 } ``` -------------------------------- ### Compare1 Usage Examples Source: https://pragmastat.dev/compare1 Demonstrates comparing a sample against Center and Spread metrics with defined thresholds. ```text Compare1([1..10], [(Center, 20, 1e-3)]) ``` ```text Compare1([1..10], [(Spread, 0.1, 1e-3)]) ``` -------------------------------- ### Pragmastat Library Usage Demo Source: https://pragmastat.dev/r Comprehensive examples demonstrating one-sample and two-sample metrics, confirmatory comparisons, sample-based interfaces, randomization, and distribution sampling. ```R library(pragmastat) # --- One-Sample (legacy vector interface) --- x <- 1:200 print(center(x)) # 100.5 bounds <- center_bounds(x, 1e-3) print(paste("[", bounds$lower, ", ", bounds$upper, "]", sep = "")) # [86, 115] print(spread(x)) # 59 bounds <- spread_bounds(x, 1e-3, seed = "demo") print(paste("[", bounds$lower, ", ", bounds$upper, "]", sep = "")) # [44, 87] # --- Two-Sample (legacy vector interface) --- x <- 1:200 y <- 101:300 print(shift(x, y)) # -100 bounds <- shift_bounds(x, y, 1e-3) print(paste("[", bounds$lower, ", ", bounds$upper, "]", sep = "")) # [-120, -80] print(ratio(x, y)) # 0.500835 bounds <- ratio_bounds(x, y, 1e-3) print(paste("[", bounds$lower, ", ", bounds$upper, "]", sep = "")) # [0.406666666666667, 0.595833333333333] print(disparity(x, y)) # -1.694915 bounds <- disparity_bounds(x, y, 1e-3, seed = "demo") print(paste("[", bounds$lower, ", ", bounds$upper, "]", sep = "")) # [-3.1025641025641, -0.849462365591398] # --- Confirmatory Comparison --- sx <- Sample$new(x) t1 <- list(list(metric = METRIC_CENTER, value = Measurement$new(50), misrate = 1e-3)) print(compare1(sx, t1)[[1]]$verdict) # "greater" sy <- Sample$new(y) t2 <- list(list(metric = METRIC_SHIFT, value = Measurement$new(0), misrate = 1e-3)) print(compare2(sx, sy, t2)[[1]]$verdict) # "less" # --- Sample-based interface --- sx <- Sample$new(1:200) m <- center(sx) print(paste("center:", m$value, "unit:", m$unit$id)) b <- center_bounds(sx, 1e-3) print(paste("center_bounds: [", b$lower, ", ", b$upper, "] unit:", b$unit$id, sep = "")) sx <- Sample$new(1:200) sy <- Sample$new(101:300) m <- shift(sx, sy) print(paste("shift:", m$value, "unit:", m$unit$id)) m <- ratio(sx, sy) print(paste("ratio:", m$value, "unit:", m$unit$id)) # --- Randomization --- r <- rng("demo-uniform") print(r$uniform_float()) # 0.2640554 print(r$uniform_float()) # 0.9348535 r <- rng("demo-uniform-int") print(r$uniform_int(0, 100)) # 41 r <- rng("demo-sample") print(r$sample(0:9, 3)) # 3 8 9 r <- rng("demo-resample") print(r$resample(c(1, 2, 3, 4, 5), 7)) # 3 1 3 2 4 1 2 r <- rng("demo-shuffle") print(r$shuffle(c(1, 2, 3, 4, 5))) # 4 2 3 5 1 # --- Distributions --- r <- rng("demo-dist-additive") dist <- dist_additive(0, 1) print(dist$sample(r)) # 0.1741045 r <- rng("demo-dist-multiplic") dist <- dist_multiplic(0, 1) print(dist$sample(r)) # 1.127324 r <- rng("demo-dist-exp") dist <- dist_exp(1) print(dist$sample(r)) # 0.6589065 r <- rng("demo-dist-power") dist <- dist_power(1, 2) print(dist$sample(r)) # 1.023678 r <- rng("demo-dist-uniform") dist <- dist_uniform(0, 10) print(dist$sample(r)) # 6.540437 ``` -------------------------------- ### Install Pragmastat via Build Systems Source: https://pragmastat.dev/kt Configuration snippets for adding Pragmastat as a dependency in Maven and Gradle projects. ```xml dev.pragmastat pragmastat 14.0.1 ``` ```groovy implementation 'dev.pragmastat:pragmastat:14.0.1' ``` ```kotlin implementation("dev.pragmastat:pragmastat:14.0.1") ``` -------------------------------- ### Shuffle Usage Examples Source: https://pragmastat.dev/shuffle Basic usage of the Shuffle method for generating a shuffled copy of an array. ```text Rng("demo-shuffle").Shuffle([1, 2, 3, 4, 5]) ``` ```text r.Shuffle(x) ``` -------------------------------- ### Center Estimator Namespace Setup Source: https://pragmastat.dev/center Required imports and namespace declaration for the Pragmastat Center estimator implementation. ```csharp using Pragmastat.Internal; using Pragmastat.Randomization; namespace Pragmastat.Algorithms; ``` -------------------------------- ### Violation Schema Examples Source: https://pragmastat.dev/assumptions Standardized JSON format for reporting assumption violations. ```json { "id": "positivity", "subject": "x" } ``` ```json { "id": "domain", "subject": "misrate" } ``` -------------------------------- ### Reproducible Shuffle with Seed Source: https://pragmastat.dev/shuffle Example of passing a seeded generator to ensure reproducible results. ```text Shuffle(data, Rng("experiment-1")) ``` -------------------------------- ### Comparison Entry Points Source: https://pragmastat.dev/compare1 Public methods for executing comparisons, enforcing metric compatibility constraints. ```csharp public static IReadOnlyList Compare1(Sample x, IReadOnlyList thresholds, string? seed) { Assertion.NonWeighted("x", x); Assertion.NotNullOrEmpty("thresholds", thresholds); Assertion.ItemNotNull("thresholds", thresholds); foreach (var threshold in thresholds) { if (threshold.Metric is Metric.Shift or Metric.Ratio or Metric.Disparity) throw new ArgumentException( $"Metric {threshold.Metric} is not supported by Compare1. Use Compare2 instead.", nameof(thresholds)); } foreach (var threshold in thresholds) { if (!threshold.Value.NominalValue.IsFinite()) throw new ArgumentOutOfRangeException(nameof(thresholds), "threshold.Value must be finite"); } var normalizedValues = new Measurement[thresholds.Count]; for (int i = 0; i < thresholds.Count; i++) { var spec = GetSpec(Compare1Specs, thresholds[i].Metric); normalizedValues[i] = spec.ValidateAndNormalize(thresholds[i], x, null); } return Execute(Compare1Specs, x, null, thresholds, normalizedValues, seed); } public static IReadOnlyList Compare2( Sample x, Sample y, IReadOnlyList thresholds, string? seed) { Assertion.NonWeighted("x", x); Assertion.NonWeighted("y", y); Assertion.CompatibleUnits(x, y); Assertion.NotNullOrEmpty("thresholds", thresholds); Assertion.ItemNotNull("thresholds", thresholds); foreach (var threshold in thresholds) { if (threshold.Metric is Metric.Center or Metric.Spread) throw new ArgumentException( $"Metric {threshold.Metric} is not supported by Compare2. Use Compare1 instead.", nameof(thresholds)); } ``` -------------------------------- ### Compare2 Algorithm Implementation Source: https://pragmastat.dev/compare2 Core logic for validating inputs, normalizing metrics, and executing the comparison projection. ```csharp public static IReadOnlyList Compare2( Sample x, Sample y, IReadOnlyList thresholds, string? seed) { Assertion.NonWeighted("x", x); Assertion.NonWeighted("y", y); Assertion.CompatibleUnits(x, y); Assertion.NotNullOrEmpty("thresholds", thresholds); Assertion.ItemNotNull("thresholds", thresholds); foreach (var threshold in thresholds) { if (threshold.Metric is Metric.Center or Metric.Spread) throw new ArgumentException( $"Metric {threshold.Metric} is not supported by Compare2. Use Compare1 instead.", nameof(thresholds)); } foreach (var threshold in thresholds) { if (!threshold.Value.NominalValue.IsFinite()) throw new ArgumentOutOfRangeException(nameof(thresholds), "threshold.Value must be finite"); } var normalizedValues = new Measurement[thresholds.Count]; for (int i = 0; i < thresholds.Count; i++) { var spec = GetSpec(Compare2Specs, thresholds[i].Metric); normalizedValues[i] = spec.ValidateAndNormalize(thresholds[i], x, y); } return Execute(Compare2Specs, x, y, thresholds, normalizedValues, seed); } private static MetricSpec GetSpec(MetricSpec[] specs, Metric metric) { foreach (var spec in specs) if (spec.Metric == metric) return spec; throw new ArgumentException($"No spec found for metric {metric}"); } private static IReadOnlyList Execute( MetricSpec[] canonicalSpecs, Sample x, Sample? y, IReadOnlyList thresholds, Measurement[] normalizedValues, string? seed) { var results = new Projection[thresholds.Count]; var byMetric = thresholds .Select((t, i) => (t, i, normalizedValues[i])) .GroupBy(item => item.t.Metric) .ToDictionary(g => g.Key, g => g.ToList()); foreach (var spec in canonicalSpecs) { if (!byMetric.TryGetValue(spec.Metric, out var entries)) continue; var estimate = spec.Estimate(x, y); foreach (var (threshold, inputIndex, normalizedValue) in entries) { var bounds = (seed != null && spec.SeededBounds != null) ? spec.SeededBounds(x, y, threshold.Misrate, seed) : spec.Bounds(x, y, threshold.Misrate); var verdict = ComputeVerdict(bounds, normalizedValue); results[inputIndex] = new Projection(threshold, estimate, bounds, verdict); } } return results; } private static ComparisonVerdict ComputeVerdict(Bounds bounds, Measurement normalizedThreshold) { double t = normalizedThreshold.NominalValue; if (bounds.Lower > t) return ComparisonVerdict.Greater; if (bounds.Upper < t) return ComparisonVerdict.Less; return ComparisonVerdict.Inconclusive; } } ``` -------------------------------- ### Input Preparation Helpers Source: https://pragmastat.dev/spread Utility methods for copying and validating input data, including an optional sorting step. ```csharp private static double[] CopyAndSort(IReadOnlyList values) { var a = new double[values.Count]; for (int i = 0; i < a.Length; i++) { double v = values[i]; if (double.IsNaN(v)) throw new ArgumentException("NaN not allowed.", nameof(values)); a[i] = v; } Array.Sort(a); return a; } private static double[] CopyTrusted(IReadOnlyList values) { // Trust caller that values are sorted; still copy to array for fast indexed access. var a = new double[values.Count]; for (int i = 0; i < a.Length; i++) { double v = values[i]; if (double.IsNaN(v)) throw new ArgumentException("NaN not allowed.", nameof(values)); a[i] = v; } return a; } ``` -------------------------------- ### Sample Algorithm Implementation Source: https://pragmastat.dev/sample Pseudocode for the selection sampling algorithm that performs a single pass over the data. ```text seen = 0, selected = 0 for each element x at position i: if uniform() < (k - selected) / (n - seen): output x selected += 1 seen += 1 ``` -------------------------------- ### Implement Ratio Estimation in C# Source: https://pragmastat.dev/ratio Computes quantiles of pairwise ratios by delegating to the Shift algorithm in log-space. Requires input samples to be strictly positive. ```csharp namespace Pragmastat.Algorithms; using System; using System.Collections.Generic; using System.Linq; using Pragmastat.Exceptions; using Pragmastat.Internal; /// /// Computes quantiles of pairwise ratios via log-transformation and ShiftImpl delegation. /// Ratio(x, y) = exp(Shift(log(x), log(y))) /// internal static class RatioImpl { /// /// Computes quantiles of all pairwise ratios { x_i / y_j }. /// Time: O((m + n) * log(precision)) per quantile. Space: O(m + n). /// /// /// Log-transformation preserves sort order for positive values. /// /// First sample (must be strictly positive). /// Second sample (must be strictly positive). /// Probabilities in [0, 1]. /// If true, assumes x and y are already sorted in ascending order. /// Quantile values for each probability in p. public static double[] Estimate(IReadOnlyList x, IReadOnlyList y, double[] p, bool assumeSorted = false) { // Log-transform both samples (includes positivity check) var logX = MathExtensions.Log(x, Subject.X); var logY = MathExtensions.Log(y, Subject.Y); // Delegate to ShiftImpl in log-space var logResult = ShiftImpl.Estimate(logX, logY, p, assumeSorted); // Exp-transform back to ratio-space return logResult.Select(v => Math.Exp(v)).ToArray(); } } ``` -------------------------------- ### Compute Pairwise Quantiles and Bounds in C# Source: https://pragmastat.dev/center-bounds Provides methods to find the k-th smallest pairwise average and calculate lower and upper bounds for a sorted input list. ```csharp using System.Diagnostics; namespace Pragmastat.Algorithms; /// /// Efficiently computes quantiles from all pairwise averages (x[i] + x[j]) / 2 for i ≤ j. /// Uses binary search with counting function to avoid materializing all N(N+1)/2 pairs. /// internal static class CenterQuantilesImpl { private static bool IsSorted(IReadOnlyList list) { for (int i = 1; i < list.Count; i++) if (list[i] < list[i - 1]) return false; return true; } /// /// Relative epsilon for floating-point comparisons in binary search convergence. /// private const double RelativeEpsilon = 1e-14; /// /// Compute specified quantile from pairwise averages. /// /// Sorted input array. /// 1-based rank of the desired quantile. /// The k-th smallest pairwise average. public static double Quantile(IReadOnlyList sorted, long k) { Debug.Assert( IsSorted(sorted), "CenterQuantilesImpl.Quantile: input must be sorted"); int n = sorted.Count; if (n == 0) throw new ArgumentException("Input cannot be empty", nameof(sorted)); long totalPairs = (long)n * (n + 1) / 2; if (k < 1 || k > totalPairs) throw new ArgumentOutOfRangeException(nameof(k), $"k must be in range [1, {totalPairs}]"); if (n == 1) return sorted[0]; return FindExactQuantile(sorted, k); } /// /// Compute both lower and upper bounds from pairwise averages. /// /// Sorted input array. /// Rank of lower bound (1-based). /// Rank of upper bound (1-based). /// Lower and upper quantiles. public static (double Lo, double Hi) Bounds(IReadOnlyList sorted, long marginLo, long marginHi) { Debug.Assert( IsSorted(sorted), "CenterQuantilesImpl.Bounds: input must be sorted"); int n = sorted.Count; if (n == 0) throw new ArgumentException("Input cannot be empty", nameof(sorted)); long totalPairs = (long)n * (n + 1) / 2; marginLo = Max(1, Min(marginLo, totalPairs)); marginHi = Max(1, Min(marginHi, totalPairs)); double lo = FindExactQuantile(sorted, marginLo); double hi = FindExactQuantile(sorted, marginHi); return (Min(lo, hi), Max(lo, hi)); } /// /// Count pairwise averages ≤ target value. /// private static long CountPairsLessOrEqual(IReadOnlyList sorted, double target) { int n = sorted.Count; long count = 0; // j is not reset: as i increases, threshold decreases monotonically int j = n - 1; for (int i = 0; i < n; i++) { double threshold = 2 * target - sorted[i]; while (j >= 0 && sorted[j] > threshold) j--; if (j >= i) count += j - i + 1; } return count; } /// /// Find exact k-th pairwise average using selection algorithm. /// private static double FindExactQuantile(IReadOnlyList sorted, long k) { int n = sorted.Count; long totalPairs = (long)n * (n + 1) / 2; if (n == 1) return sorted[0]; if (k == 1) return sorted[0]; if (k == totalPairs) return sorted[n - 1]; double lo = sorted[0]; double hi = sorted[n - 1]; const double eps = RelativeEpsilon; var candidates = new List(n); while (hi - lo > eps * Max(1.0, Max(Abs(lo), Abs(hi)))) { double mid = 0.5 * lo + 0.5 * hi; long countLessOrEqual = CountPairsLessOrEqual(sorted, mid); if (countLessOrEqual >= k) hi = mid; else lo = mid; } double target = 0.5 * lo + 0.5 * hi; for (int i = 0; i < n; i++) { double threshold = 2 * target - sorted[i]; int left = i; int right = n; while (left < right) { int m = (left + right) / 2; if (sorted[m] < threshold - eps) left = m + 1; else right = m; } if (left < n && left >= i && Abs(sorted[left] - threshold) < eps * Max(1.0, Abs(threshold))) candidates.Add(0.5 * sorted[i] + 0.5 * sorted[left]); if (left > i) { double avgBefore = 0.5 * sorted[i] + 0.5 * sorted[left - 1]; if (avgBefore <= target + eps) candidates.Add(avgBefore); } } if (candidates.Count == 0) return target; candidates.Sort(); foreach (double candidate in candidates) { long countAtCandidate = CountPairsLessOrEqual(sorted, candidate); if (countAtCandidate >= k) return candidate; } return target; } } ``` -------------------------------- ### Perform Statistical Analysis and Randomization Source: https://pragmastat.dev/py Demonstrates one-sample and two-sample metrics, confirmatory comparisons, random number generation, and sampling from various distributions. ```python from pragmastat import ( Metric, Rng, Sample, Threshold, center, center_bounds, compare1, compare2, disparity, disparity_bounds, ratio, ratio_bounds, shift, shift_bounds, spread, spread_bounds, ) from pragmastat.distributions import Additive, Exp, Multiplic, Power, Uniform def main(): # --- One-Sample --- x = Sample(list(range(1, 201))) result = center(x) print(result.value) # 100.5 bounds = center_bounds(x, 1e-3) print(f"Bounds(lower={bounds.lower}, upper={bounds.upper})") # Bounds(lower=86.0, upper=115.0) print(spread(x).value) # 59.0 bounds = spread_bounds(x, 1e-3, seed="demo") print(f"Bounds(lower={bounds.lower}, upper={bounds.upper})") # Bounds(lower=44.0, upper=87.0) # --- Two-Sample --- x = Sample(list(range(1, 201))) y = Sample(list(range(101, 301))) print(shift(x, y).value) # -100.0 bounds = shift_bounds(x, y, 1e-3) print(f"Bounds(lower={bounds.lower}, upper={bounds.upper})") # Bounds(lower=-120.0, upper=-80.0) print(ratio(x, y).value) # 0.5008354224706334 bounds = ratio_bounds(x, y, 1e-3) print( f"Bounds(lower={bounds.lower}, upper={bounds.upper})" ) # Bounds(lower=0.4066666666666668, upper=0.5958333333333332) print(disparity(x, y).value) # -1.694915254237288 bounds = disparity_bounds(x, y, 1e-3, seed="demo") print( f"Bounds(lower={bounds.lower}, upper={bounds.upper})" ) # Bounds(lower=-3.1025641025641026, upper=-0.8494623655913979) # --- Confirmatory Comparison --- x = Sample(list(range(1, 201))) projection = compare1(x, [Threshold(Metric.CENTER, 50.0, 1e-3)])[0] print(projection.verdict.value) # greater x = Sample(list(range(1, 201))) y = Sample(list(range(101, 301))) projection = compare2(x, y, [Threshold(Metric.SHIFT, 0.0, 1e-3)])[0] print(projection.verdict.value) # less # --- Randomization --- rng = Rng("demo-uniform") print(rng.uniform_float()) # 0.2640554428629759 print(rng.uniform_float()) # 0.9348534835582796 rng = Rng("demo-uniform-int") print(rng.uniform_int(0, 100)) # 41 rng = Rng("demo-sample") print(rng.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)) # [3, 8, 9] rng = Rng("demo-resample") print(rng.resample([1, 2, 3, 4, 5], 7)) # [3, 1, 3, 2, 4, 1, 2] rng = Rng("demo-shuffle") print(rng.shuffle([1, 2, 3, 4, 5])) # [4, 2, 3, 5, 1] # --- Distributions --- rng = Rng("demo-dist-additive") print(Additive(0, 1).sample(rng)) # 0.17410448679568188 rng = Rng("demo-dist-multiplic") print(Multiplic(0, 1).sample(rng)) # 1.1273244602673853 rng = Rng("demo-dist-exp") print(Exp(1).sample(rng)) # 0.6589065267276553 rng = Rng("demo-dist-power") print(Power(1, 2).sample(rng)) # 1.023677535537084 rng = Rng("demo-dist-uniform") print(Uniform(0, 10).sample(rng)) # 6.54043657816832 if __name__ == "__main__": main() ```