causalgo

command module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2026 License: MIT Imports: 3 Imported by: 0

README ΒΆ

CausalGoβ„’: Causal Analysis Library in Go

Pure Go implementation of causal discovery algorithms - SCICβ„’, SURD, VarSelect

GitHub Release Go Version Go Reference GitHub Actions Go Report Card codecov License GitHub Stars GitHub Issues


High-performance library for causal analysis and discovery in Go. Implements original SCICβ„’ (Signed Causal Information Components) algorithm for directional causality, information-theoretic SURD algorithm, and LASSO-based VarSelect for inferring causal relationships from observational time series data. Validated on real turbulent flow datasets from Nature Communications 2024.

Features ✨

  • 🎯 SCICβ„’ Algorithm - Signed Causal Information Components for directional causality (~95% test coverage)
  • 🧠 SURD Algorithm - Synergistic-Unique-Redundant Decomposition (97.2% test coverage)
  • πŸ“Š Information Theory - Entropy, mutual information, conditional entropy
  • πŸ” VarSelect - LASSO-based variable selection for causal ordering
  • πŸ“ MATLAB Support - Native .mat file reading (v5, v7.3 HDF5)
  • πŸ“ˆ Visualization - Publication-quality plots (PNG/SVG/PDF export)
  • βœ… Validated - 100% match with Python reference on real turbulence data
  • ⚑ Fast - Optimized histograms and entropy calculations
  • πŸ”§ Flexible - Configurable bins, smoothing, thresholds
  • πŸ§ͺ Well-Tested - Extensive validation on synthetic and real datasets
  • πŸ“¦ Pure Go - No CGO dependencies, cross-platform

Algorithms

Algorithm Status Test Coverage Description
SCICβ„’ βœ… Implemented ~95% Signed Causal Information Components (original contribution)
SURD βœ… Implemented 97.2% Information-theoretic decomposition (Nature 2024)
VarSelect βœ… Implemented ~85% LASSO-based recursive variable selection

Requirements

  • Go 1.25+

Installation πŸ“¦

go get github.com/causalgo/causalgo

Quick Start πŸš€

SCICβ„’ - Directional Causality Analysis
package main

import (
    "fmt"
    "math/rand"

    "github.com/causalgo/causalgo/scic"
)

func main() {
    // Generate sample data: Y = 2*X1 - 3*X2 + noise
    n := 1000
    rng := rand.New(rand.NewSource(42))

    Y := make([]float64, n)
    X := make([][]float64, 2)
    X[0] = make([]float64, n) // X1: facilitative effect
    X[1] = make([]float64, n) // X2: inhibitory effect

    for i := 0; i < n; i++ {
        x1, x2 := rng.Float64()*10, rng.Float64()*10
        X[0][i], X[1][i] = x1, x2
        Y[i] = 2*x1 - 3*x2 + rng.NormFloat64()*0.5
    }

    // Configure and run SCIC analysis
    config := scic.DefaultConfig()
    config.BootstrapN = 100 // Enable bootstrap confidence

    result, err := scic.Decompose(Y, X, config)
    if err != nil {
        panic(err)
    }

    // Analyze directional causality
    fmt.Printf("X1 direction: %.2f (facilitative)\n", result.Directions["0"])
    fmt.Printf("X2 direction: %.2f (inhibitory)\n", result.Directions["1"])
    fmt.Printf("Conflict index: %.2f\n", result.Conflicts["0,1"])
    fmt.Printf("X1 confidence: %.2f\n", result.Confidence["0"])
    fmt.Printf("X2 confidence: %.2f\n", result.Confidence["1"])

    // SURD components also available
    fmt.Printf("Total causality: R=%.1f%% U=%.1f%% S=%.1f%%\n",
        result.TotalR*100, result.TotalU*100, result.TotalS*100)
}
SURD - Causal Decomposition
package main

import (
    "fmt"
    "github.com/causalgo/causalgo/surd"
)

func main() {
    // Time series data: [samples x variables]
    // First column = target, rest = agents
    data := [][]float64{
        {1.0, 0.5, 0.3},  // sample 0
        {2.0, 1.5, 0.7},  // sample 1
        {1.5, 1.0, 0.5},  // sample 2
        // ... more samples
    }

    // Number of histogram bins for each variable
    bins := []int{10, 10, 10}

    // Run SURD decomposition
    result, err := surd.DecomposeFromData(data, bins)
    if err != nil {
        panic(err)
    }

    // Analyze causality components
    fmt.Printf("Unique causality:      %+v\n", result.Unique)
    fmt.Printf("Redundant causality:   %+v\n", result.Redundant)
    fmt.Printf("Synergistic causality: %+v\n", result.Synergistic)
    fmt.Printf("Information leak:      %.4f\n", result.InfoLeak)
}
VarSelect - Causal Ordering
package main

import (
    "fmt"
    "math/rand"

    "github.com/causalgo/causalgo/varselect"
    "gonum.org/v1/gonum/mat"
)

func main() {
    // Create synthetic data (100 samples, 3 variables)
    data := mat.NewDense(100, 3, nil)
    for i := 0; i < 100; i++ {
        x := rand.Float64()
        data.Set(i, 0, x)
        data.Set(i, 1, x*0.8+rand.Float64()*0.2)
        data.Set(i, 2, x*0.5+data.At(i, 1)*0.5+rand.Float64()*0.1)
    }

    // Configure variable selection
    selector := varselect.New(varselect.Config{
        Lambda:    0.1,    // LASSO regularization
        Tolerance: 1e-5,   // Convergence threshold
        MaxIter:   1000,   // Maximum iterations
    })

    // Discover causal order
    result, err := selector.Fit(data)
    if err != nil {
        panic(err)
    }

    fmt.Println("Causal Order:", result.Order)
    fmt.Println("Adjacency Matrix:", result.Adjacency)
}

Advanced Usage 🧠

Working with MATLAB Data
package main

import (
    "github.com/causalgo/causalgo/matdata"
    "github.com/causalgo/causalgo/surd"
)

func main() {
    // Load MATLAB .mat file (v5 or v7.3 HDF5)
    data, err := matdata.LoadMatrixTransposed("data.mat", "X")
    if err != nil {
        panic(err)
    }

    // Prepare with time lag for causal analysis
    Y, err := matdata.PrepareWithLag(data, targetIdx=0, lag=10)
    if err != nil {
        panic(err)
    }

    // Run SURD decomposition
    bins := make([]int, len(Y[0]))
    for i := range bins {
        bins[i] = 10
    }

    result, _ := surd.DecomposeFromData(Y, bins)

    // Analyze causality...
}
Visualization
package main

import (
    "github.com/causalgo/causalgo/surd"
    "github.com/causalgo/causalgo/visualization"
)

func main() {
    // Run SURD decomposition
    result, _ := surd.DecomposeFromData(data, bins)

    // Create plot with custom options
    opts := visualization.PlotOptions{
        Title:      "Causal Decomposition",
        Width:      10.0,  // inches
        Height:     6.0,
        Threshold:  0.01,  // Filter small values
        ShowLeak:   true,
        ShowLabels: true,
    }

    plot, _ := visualization.PlotSURD(result, opts)

    // Save to file (auto-detects format from extension)
    visualization.SavePlot(plot, "results.png", 10, 6)  // PNG
    visualization.SavePlot(plot, "results.svg", 10, 6)  // SVG
    visualization.SavePlot(plot, "results.pdf", 10, 6)  // PDF
}
CLI Visualization Tool
# Generate XOR synergy example
go run cmd/visualize/main.go --system xor --output surd_xor.png

# Custom dataset with parameters
go run cmd/visualize/main.go \
  --system duplicated \
  --samples 100000 \
  --bins 10 \
  --output redundancy.svg

Available systems: xor (synergy), duplicated (redundancy), independent (unique)

Example Plots

Redundancy (Duplicated Input)
Unique (Independent Inputs)
Synergy (XOR System)

Package Structure

Following Go 2025 best practices (gonum-style: public packages at root, no pkg/ directory):

causalgo/
β”œβ”€β”€ surd/                      # SURD algorithm (97.2% coverage) β€” PUBLIC API
β”‚   β”œβ”€β”€ surd.go               # Synergistic-Unique-Redundant Decomposition
β”‚   └── example_test.go       # Testable examples
β”œβ”€β”€ scic/                      # SCICβ„’ algorithm (~95% coverage) β€” PUBLIC API
β”‚   β”œβ”€β”€ scic.go               # Signed Causal Information Components
β”‚   └── example_test.go       # 18 professional testable examples
β”œβ”€β”€ varselect/                 # VarSelect algorithm (~85% coverage) β€” PUBLIC API
β”‚   └── varselect.go          # LASSO-based causal ordering
β”œβ”€β”€ matdata/                   # MATLAB utilities β€” PUBLIC API
β”‚   β”œβ”€β”€ matdata.go            # Native .mat file reading (v5, v7.3 HDF5)
β”‚   └── example_test.go       # Usage examples
β”œβ”€β”€ visualization/             # Plotting β€” PUBLIC API
β”‚   β”œβ”€β”€ plot.go               # SURD/SCIC bar charts
β”‚   └── export.go             # Multi-format export (PNG/SVG/PDF)
β”œβ”€β”€ regression/                # Regression models
β”‚   β”œβ”€β”€ regression.go         # Regressor interface
β”‚   └── lasso.go              # LASSO implementation
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ entropy/              # Information theory (97.6% coverage)
β”‚   β”‚   └── entropy.go        # Shannon entropy, MI, conditional MI
β”‚   β”œβ”€β”€ histogram/            # N-dimensional histograms (98.7% coverage)
β”‚   β”‚   └── histogram.go      # NDHistogram with smoothing
β”‚   β”œβ”€β”€ comparison/           # Algorithm comparison tests
β”‚   └── validation/           # SURD validation against Python reference
β”œβ”€β”€ cmd/
β”‚   └── visualize/            # CLI visualization tool
└── testdata/
    └── matlab/               # Real turbulence datasets

Validation πŸ§ͺ

SCICβ„’ Validation

SCICβ„’ algorithm validated on canonical systems and real-world datasets:

Dataset Samples Variables Directionality Sign Stability
XOR System 100,000 3 βœ… Correct > 0.95
Duplicated Input 100,000 3 βœ… Correct > 0.95
Inhibitor System 100,000 3 βœ… Correct > 0.95
U-Shaped 100,000 3 βœ… Correct > 0.90
Energy Cascade 21,759 5 βœ… Correct > 0.85
SURD Validation

SURD implementation validated against Python reference from Nature Communications 2024:

Dataset Samples Variables Match InfoLeak
Energy Cascade 21,759 5 βœ… 100% < 0.01
Inner-Outer Flow 2.4M 2 βœ… 100% ~0.997
XOR (synthetic) 10,000 3 βœ… 100% < 0.001

Run validation tests:

go test -v ./internal/validation/...  # SURD validation
go test -v ./scic/...                 # SCIC validation

Testing

# Run all tests
go test -v ./...

# Run with race detector
go test -v -race ./...

# Run with coverage
go test -coverprofile=coverage.out -covermode=atomic -v ./...
go tool cover -html=coverage.out

# Run benchmarks
go test -bench=. -run=^Benchmark ./...

Performance

Optimized for both small-scale analysis and large time series:

Operation Samples Time Memory
SURD (3 vars) 10,000 ~1-2 ms ~5 MB
SURD (5 vars) 21,759 ~879 ms ~50 MB
Inner-Outer (2 vars) 2.4M ~95-135 ms ~200 MB

When to Use Each Algorithm

Use SCICβ„’ when:
  • Need directional causality (positive/negative effects)
  • Working with complex nonlinear systems
  • Need confidence estimates (bootstrap sign stability)
  • Want to detect conflicting relationships
  • Need regime detection in non-monotonic systems (DirectionProfile)
  • Care about magnitude AND direction of causal effects
  • Time complexity: O(n Γ— p Γ— B) where B = bootstrap samples
Use SURD when:
  • System may be nonlinear
  • Need to detect synergy (joint effects)
  • Need to detect redundancy (overlapping information)
  • Have fewer variables (<10)
  • Want information-theoretic decomposition
  • Time complexity: O(n Γ— 2^p) where p = number of agents
Use VarSelect when:
  • System is primarily linear
  • Need fast variable screening (10+ variables)
  • Want interpretable regression weights
  • Need causal ordering
  • Time complexity: O(n Γ— pΒ²)
Hybrid Approach:
  1. Use VarSelect to screen many variables
  2. Apply SCICβ„’ for directional analysis of top-k variables
  3. Use SURD for synergy/redundancy decomposition if needed

Documentation

Contributing

We welcome contributions! See CONTRIBUTING.md for:

  • Git workflow (feature/bugfix/hotfix branches)
  • Commit message conventions
  • Code quality standards
  • Pull request process

Community

Citation

If using the SURD algorithm, please cite:

@article{martinez2024decomposing,
  title={Decomposing causality into its synergistic, unique, and redundant components},
  author={Mart{\'\i}nez-S{\'a}nchez, {\'A}lvaro and Arranz, Gonzalo and Lozano-Dur{\'a}n, Adri{\'a}n},
  journal={Nature Communications},
  volume={15},
  pages={9296},
  year={2024},
  doi={10.1038/s41467-024-53373-4}
}

License

MIT License - see LICENSE for details.

Contact


Built with ❀️ using Go and Gonum

Documentation ΒΆ

The Go Gopher

There is no documentation for this package.

Directories ΒΆ

Path Synopsis
cmd
visualize command
Package main provides CLI tool for visualizing SURD decomposition results.
Package main provides CLI tool for visualizing SURD decomposition results.
examples
visualization command
Package main demonstrates visualization of SURD decomposition results.
Package main demonstrates visualization of SURD decomposition results.
internal
comparison
Package comparison provides utilities for comparing VarSelect and SURD algorithms.
Package comparison provides utilities for comparing VarSelect and SURD algorithms.
entropy
Package entropy provides information-theoretic functions for causal analysis.
Package entropy provides information-theoretic functions for causal analysis.
histogram
Package histogram provides N-dimensional histogram construction for causal analysis.
Package histogram provides N-dimensional histogram construction for causal analysis.
validation
Package validation provides reference examples and generators for SURD validation.
Package validation provides reference examples and generators for SURD validation.
Package matdata provides utilities for loading MATLAB .mat files.
Package matdata provides utilities for loading MATLAB .mat files.
Package regression provides interfaces and implementations for regression models
Package regression provides interfaces and implementations for regression models
Package scic implements SCIC: Signed Causal Information Components.
Package scic implements SCIC: Signed Causal Information Components.
Package surd implements SURD: Synergistic-Unique-Redundant Decomposition of causality.
Package surd implements SURD: Synergistic-Unique-Redundant Decomposition of causality.
Package varselect implements recursive variable selection for causal ordering.
Package varselect implements recursive variable selection for causal ordering.
Package visualization provides plotting and visualization utilities for SURD results.
Package visualization provides plotting and visualization utilities for SURD results.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL