{"id":44617266,"url":"https://github.com/causalgo/causalgo","last_synced_at":"2026-02-14T13:11:27.420Z","repository":{"id":297612590,"uuid":"997328225","full_name":"causalgo/causalgo","owner":"causalgo","description":"Go library for causal inference with original SCIC algorithm for directional causality analysis. Includes SURD (information-theoretic) and VarSelect (LASSO-based) methods. High-performance, production-ready.","archived":false,"fork":false,"pushed_at":"2025-11-26T15:19:19.000Z","size":57083,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-29T03:56:50.171Z","etag":null,"topics":["algorithms","causal-discovery","causal-inference","data-science","golang","information-theory","lasso-regression","scic","scientific-computing","surd"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/causalgo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-06T10:43:06.000Z","updated_at":"2025-11-26T15:12:17.000Z","dependencies_parsed_at":"2025-06-06T12:33:06.661Z","dependency_job_id":"813ef4ef-3009-4bcb-bd81-9af690fdce92","html_url":"https://github.com/causalgo/causalgo","commit_stats":null,"previous_names":["causalgo/causalgo"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/causalgo/causalgo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/causalgo%2Fcausalgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/causalgo%2Fcausalgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/causalgo%2Fcausalgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/causalgo%2Fcausalgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/causalgo","download_url":"https://codeload.github.com/causalgo/causalgo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/causalgo%2Fcausalgo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29444142,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T12:43:28.304Z","status":"ssl_error","status_checked_at":"2026-02-14T12:43:14.160Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","causal-discovery","causal-inference","data-science","golang","information-theory","lasso-regression","scic","scientific-computing","surd"],"created_at":"2026-02-14T13:11:26.786Z","updated_at":"2026-02-14T13:11:27.415Z","avatar_url":"https://github.com/causalgo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CausalGo™: Causal Analysis Library in Go\n\n\u003e **Pure Go implementation of causal discovery algorithms** - SCIC™, SURD, VarSelect\n\n[![GitHub Release](https://img.shields.io/github/v/release/causalgo/causalgo?include_prereleases\u0026style=flat-square\u0026logo=github\u0026color=blue)](https://github.com/causalgo/causalgo/releases/latest)\n[![Go Version](https://img.shields.io/badge/Go-1.25%2B-00ADD8?style=flat-square\u0026logo=go)](https://go.dev/dl/)\n[![Go Reference](https://pkg.go.dev/badge/github.com/causalgo/causalgo.svg)](https://pkg.go.dev/github.com/causalgo/causalgo)\n[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/causalgo/causalgo/go.yml?branch=main\u0026style=flat-square\u0026logo=github-actions\u0026label=CI)](https://github.com/causalgo/causalgo/actions)\n[![Go Report Card](https://goreportcard.com/badge/github.com/causalgo/causalgo?style=flat-square)](https://goreportcard.com/report/github.com/causalgo/causalgo)\n[![codecov](https://img.shields.io/codecov/c/github/causalgo/causalgo?style=flat-square\u0026logo=codecov)](https://codecov.io/gh/causalgo/causalgo)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)\n[![GitHub Stars](https://img.shields.io/github/stars/causalgo/causalgo?style=flat-square\u0026logo=github)](https://github.com/causalgo/causalgo/stargazers)\n[![GitHub Issues](https://img.shields.io/github/issues/causalgo/causalgo?style=flat-square\u0026logo=github)](https://github.com/causalgo/causalgo/issues)\n\n---\n\nHigh-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.\n\n## Features ✨\n\n- 🎯 **SCIC™ Algorithm** - Signed Causal Information Components for directional causality (~95% test coverage)\n- 🧠 **SURD Algorithm** - Synergistic-Unique-Redundant Decomposition (97.2% test coverage)\n- 📊 **Information Theory** - Entropy, mutual information, conditional entropy\n- 🔍 **VarSelect** - LASSO-based variable selection for causal ordering\n- 📁 **MATLAB Support** - Native .mat file reading (v5, v7.3 HDF5)\n- 📈 **Visualization** - Publication-quality plots (PNG/SVG/PDF export)\n- ✅ **Validated** - 100% match with Python reference on real turbulence data\n- ⚡ **Fast** - Optimized histograms and entropy calculations\n- 🔧 **Flexible** - Configurable bins, smoothing, thresholds\n- 🧪 **Well-Tested** - Extensive validation on synthetic and real datasets\n- 📦 **Pure Go** - No CGO dependencies, cross-platform\n\n## Algorithms\n\n| Algorithm | Status | Test Coverage | Description |\n|-----------|--------|---------------|-------------|\n| **SCIC™** | ✅ Implemented | ~95% | Signed Causal Information Components (original contribution) |\n| **SURD** | ✅ Implemented | 97.2% | Information-theoretic decomposition ([Nature 2024](https://doi.org/10.1038/s41467-024-53373-4)) |\n| **VarSelect** | ✅ Implemented | ~85% | LASSO-based recursive variable selection |\n\n## Requirements\n\n- Go 1.25+\n\n## Installation 📦\n\n```bash\ngo get github.com/causalgo/causalgo\n```\n\n## Quick Start 🚀\n\n### SCIC™ - Directional Causality Analysis\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"math/rand\"\n\n    \"github.com/causalgo/causalgo/scic\"\n)\n\nfunc main() {\n    // Generate sample data: Y = 2*X1 - 3*X2 + noise\n    n := 1000\n    rng := rand.New(rand.NewSource(42))\n\n    Y := make([]float64, n)\n    X := make([][]float64, 2)\n    X[0] = make([]float64, n) // X1: facilitative effect\n    X[1] = make([]float64, n) // X2: inhibitory effect\n\n    for i := 0; i \u003c n; i++ {\n        x1, x2 := rng.Float64()*10, rng.Float64()*10\n        X[0][i], X[1][i] = x1, x2\n        Y[i] = 2*x1 - 3*x2 + rng.NormFloat64()*0.5\n    }\n\n    // Configure and run SCIC analysis\n    config := scic.DefaultConfig()\n    config.BootstrapN = 100 // Enable bootstrap confidence\n\n    result, err := scic.Decompose(Y, X, config)\n    if err != nil {\n        panic(err)\n    }\n\n    // Analyze directional causality\n    fmt.Printf(\"X1 direction: %.2f (facilitative)\\n\", result.Directions[\"0\"])\n    fmt.Printf(\"X2 direction: %.2f (inhibitory)\\n\", result.Directions[\"1\"])\n    fmt.Printf(\"Conflict index: %.2f\\n\", result.Conflicts[\"0,1\"])\n    fmt.Printf(\"X1 confidence: %.2f\\n\", result.Confidence[\"0\"])\n    fmt.Printf(\"X2 confidence: %.2f\\n\", result.Confidence[\"1\"])\n\n    // SURD components also available\n    fmt.Printf(\"Total causality: R=%.1f%% U=%.1f%% S=%.1f%%\\n\",\n        result.TotalR*100, result.TotalU*100, result.TotalS*100)\n}\n```\n\n### SURD - Causal Decomposition\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/causalgo/causalgo/surd\"\n)\n\nfunc main() {\n    // Time series data: [samples x variables]\n    // First column = target, rest = agents\n    data := [][]float64{\n        {1.0, 0.5, 0.3},  // sample 0\n        {2.0, 1.5, 0.7},  // sample 1\n        {1.5, 1.0, 0.5},  // sample 2\n        // ... more samples\n    }\n\n    // Number of histogram bins for each variable\n    bins := []int{10, 10, 10}\n\n    // Run SURD decomposition\n    result, err := surd.DecomposeFromData(data, bins)\n    if err != nil {\n        panic(err)\n    }\n\n    // Analyze causality components\n    fmt.Printf(\"Unique causality:      %+v\\n\", result.Unique)\n    fmt.Printf(\"Redundant causality:   %+v\\n\", result.Redundant)\n    fmt.Printf(\"Synergistic causality: %+v\\n\", result.Synergistic)\n    fmt.Printf(\"Information leak:      %.4f\\n\", result.InfoLeak)\n}\n```\n\n### VarSelect - Causal Ordering\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"math/rand\"\n\n    \"github.com/causalgo/causalgo/varselect\"\n    \"gonum.org/v1/gonum/mat\"\n)\n\nfunc main() {\n    // Create synthetic data (100 samples, 3 variables)\n    data := mat.NewDense(100, 3, nil)\n    for i := 0; i \u003c 100; i++ {\n        x := rand.Float64()\n        data.Set(i, 0, x)\n        data.Set(i, 1, x*0.8+rand.Float64()*0.2)\n        data.Set(i, 2, x*0.5+data.At(i, 1)*0.5+rand.Float64()*0.1)\n    }\n\n    // Configure variable selection\n    selector := varselect.New(varselect.Config{\n        Lambda:    0.1,    // LASSO regularization\n        Tolerance: 1e-5,   // Convergence threshold\n        MaxIter:   1000,   // Maximum iterations\n    })\n\n    // Discover causal order\n    result, err := selector.Fit(data)\n    if err != nil {\n        panic(err)\n    }\n\n    fmt.Println(\"Causal Order:\", result.Order)\n    fmt.Println(\"Adjacency Matrix:\", result.Adjacency)\n}\n```\n\n## Advanced Usage 🧠\n\n### Working with MATLAB Data\n\n```go\npackage main\n\nimport (\n    \"github.com/causalgo/causalgo/matdata\"\n    \"github.com/causalgo/causalgo/surd\"\n)\n\nfunc main() {\n    // Load MATLAB .mat file (v5 or v7.3 HDF5)\n    data, err := matdata.LoadMatrixTransposed(\"data.mat\", \"X\")\n    if err != nil {\n        panic(err)\n    }\n\n    // Prepare with time lag for causal analysis\n    Y, err := matdata.PrepareWithLag(data, targetIdx=0, lag=10)\n    if err != nil {\n        panic(err)\n    }\n\n    // Run SURD decomposition\n    bins := make([]int, len(Y[0]))\n    for i := range bins {\n        bins[i] = 10\n    }\n\n    result, _ := surd.DecomposeFromData(Y, bins)\n\n    // Analyze causality...\n}\n```\n\n### Visualization\n\n```go\npackage main\n\nimport (\n    \"github.com/causalgo/causalgo/surd\"\n    \"github.com/causalgo/causalgo/visualization\"\n)\n\nfunc main() {\n    // Run SURD decomposition\n    result, _ := surd.DecomposeFromData(data, bins)\n\n    // Create plot with custom options\n    opts := visualization.PlotOptions{\n        Title:      \"Causal Decomposition\",\n        Width:      10.0,  // inches\n        Height:     6.0,\n        Threshold:  0.01,  // Filter small values\n        ShowLeak:   true,\n        ShowLabels: true,\n    }\n\n    plot, _ := visualization.PlotSURD(result, opts)\n\n    // Save to file (auto-detects format from extension)\n    visualization.SavePlot(plot, \"results.png\", 10, 6)  // PNG\n    visualization.SavePlot(plot, \"results.svg\", 10, 6)  // SVG\n    visualization.SavePlot(plot, \"results.pdf\", 10, 6)  // PDF\n}\n```\n\n### CLI Visualization Tool\n\n```bash\n# Generate XOR synergy example\ngo run cmd/visualize/main.go --system xor --output surd_xor.png\n\n# Custom dataset with parameters\ngo run cmd/visualize/main.go \\\n  --system duplicated \\\n  --samples 100000 \\\n  --bins 10 \\\n  --output redundancy.svg\n```\n\nAvailable systems: `xor` (synergy), `duplicated` (redundancy), `independent` (unique)\n\n### Example Plots\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"docs/images/surd_redundant.png\" width=\"250\"/\u003e\u003cbr/\u003e\u003cb\u003eRedundancy\u003c/b\u003e (Duplicated Input)\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"docs/images/surd_unique.png\" width=\"250\"/\u003e\u003cbr/\u003e\u003cb\u003eUnique\u003c/b\u003e (Independent Inputs)\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"docs/images/surd_synergy.png\" width=\"250\"/\u003e\u003cbr/\u003e\u003cb\u003eSynergy\u003c/b\u003e (XOR System)\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Package Structure\n\nFollowing Go 2025 best practices (gonum-style: public packages at root, no `pkg/` directory):\n\n```\ncausalgo/\n├── surd/                      # SURD algorithm (97.2% coverage) — PUBLIC API\n│   ├── surd.go               # Synergistic-Unique-Redundant Decomposition\n│   └── example_test.go       # Testable examples\n├── scic/                      # SCIC™ algorithm (~95% coverage) — PUBLIC API\n│   ├── scic.go               # Signed Causal Information Components\n│   └── example_test.go       # 18 professional testable examples\n├── varselect/                 # VarSelect algorithm (~85% coverage) — PUBLIC API\n│   └── varselect.go          # LASSO-based causal ordering\n├── matdata/                   # MATLAB utilities — PUBLIC API\n│   ├── matdata.go            # Native .mat file reading (v5, v7.3 HDF5)\n│   └── example_test.go       # Usage examples\n├── visualization/             # Plotting — PUBLIC API\n│   ├── plot.go               # SURD/SCIC bar charts\n│   └── export.go             # Multi-format export (PNG/SVG/PDF)\n├── regression/                # Regression models\n│   ├── regression.go         # Regressor interface\n│   └── lasso.go              # LASSO implementation\n├── internal/\n│   ├── entropy/              # Information theory (97.6% coverage)\n│   │   └── entropy.go        # Shannon entropy, MI, conditional MI\n│   ├── histogram/            # N-dimensional histograms (98.7% coverage)\n│   │   └── histogram.go      # NDHistogram with smoothing\n│   ├── comparison/           # Algorithm comparison tests\n│   └── validation/           # SURD validation against Python reference\n├── cmd/\n│   └── visualize/            # CLI visualization tool\n└── testdata/\n    └── matlab/               # Real turbulence datasets\n```\n\n## Validation 🧪\n\n### SCIC™ Validation\n\nSCIC™ algorithm validated on canonical systems and real-world datasets:\n\n| Dataset | Samples | Variables | Directionality | Sign Stability |\n|---------|---------|-----------|----------------|----------------|\n| XOR System | 100,000 | 3 | ✅ Correct | \u003e 0.95 |\n| Duplicated Input | 100,000 | 3 | ✅ Correct | \u003e 0.95 |\n| Inhibitor System | 100,000 | 3 | ✅ Correct | \u003e 0.95 |\n| U-Shaped | 100,000 | 3 | ✅ Correct | \u003e 0.90 |\n| Energy Cascade | 21,759 | 5 | ✅ Correct | \u003e 0.85 |\n\n### SURD Validation\n\nSURD implementation validated against Python reference from [Nature Communications 2024](https://doi.org/10.1038/s41467-024-53373-4):\n\n| Dataset | Samples | Variables | Match | InfoLeak |\n|---------|---------|-----------|-------|----------|\n| Energy Cascade | 21,759 | 5 | ✅ 100% | \u003c 0.01 |\n| Inner-Outer Flow | 2.4M | 2 | ✅ 100% | ~0.997 |\n| XOR (synthetic) | 10,000 | 3 | ✅ 100% | \u003c 0.001 |\n\nRun validation tests:\n```bash\ngo test -v ./internal/validation/...  # SURD validation\ngo test -v ./scic/...                 # SCIC validation\n```\n\n## Testing\n\n```bash\n# Run all tests\ngo test -v ./...\n\n# Run with race detector\ngo test -v -race ./...\n\n# Run with coverage\ngo test -coverprofile=coverage.out -covermode=atomic -v ./...\ngo tool cover -html=coverage.out\n\n# Run benchmarks\ngo test -bench=. -run=^Benchmark ./...\n```\n\n## Performance\n\nOptimized for both small-scale analysis and large time series:\n\n| Operation | Samples | Time | Memory |\n|-----------|---------|------|--------|\n| SURD (3 vars) | 10,000 | ~1-2 ms | ~5 MB |\n| SURD (5 vars) | 21,759 | ~879 ms | ~50 MB |\n| Inner-Outer (2 vars) | 2.4M | ~95-135 ms | ~200 MB |\n\n## When to Use Each Algorithm\n\n### Use SCIC™ when:\n- Need **directional causality** (positive/negative effects)\n- Working with **complex nonlinear systems**\n- Need **confidence estimates** (bootstrap sign stability)\n- Want to detect **conflicting relationships**\n- Need **regime detection** in non-monotonic systems (DirectionProfile)\n- Care about **magnitude AND direction** of causal effects\n- Time complexity: O(n × p × B) where B = bootstrap samples\n\n### Use SURD when:\n- System may be **nonlinear**\n- Need to detect **synergy** (joint effects)\n- Need to detect **redundancy** (overlapping information)\n- Have **fewer variables** (\u003c10)\n- Want **information-theoretic decomposition**\n- Time complexity: O(n × 2^p) where p = number of agents\n\n### Use VarSelect when:\n- System is primarily **linear**\n- Need **fast variable screening** (10+ variables)\n- Want **interpretable regression weights**\n- Need **causal ordering**\n- Time complexity: O(n × p²)\n\n### Hybrid Approach:\n1. Use **VarSelect** to screen many variables\n2. Apply **SCIC™** for directional analysis of top-k variables\n3. Use **SURD** for synergy/redundancy decomposition if needed\n\n## Documentation\n\n- **Examples**: See [examples in godoc](https://pkg.go.dev/github.com/causalgo/causalgo)\n- **SCIC Guide**: [docs/SCIC.md](docs/SCIC.md) — Quick start, configuration, interpreting results\n- **SCIC Examples**: [scic/example_test.go](scic/example_test.go) — 18 professional testable examples\n- **SURD Paper**: [docs/SURD_paper.md](docs/SURD_paper.md) — Reference implementation details\n- **Visualization**: [visualization/](visualization/)\n- **MATLAB Integration**: [matdata/](matdata/)\n\n## Contributing\n\nWe welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for:\n- Git workflow (feature/bugfix/hotfix branches)\n- Commit message conventions\n- Code quality standards\n- Pull request process\n\n## Community\n\n- **Code of Conduct**: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)\n- **Security Policy**: [SECURITY.md](SECURITY.md)\n- **Changelog**: [CHANGELOG.md](CHANGELOG.md)\n- **Roadmap**: [ROADMAP.md](ROADMAP.md)\n- **Issues**: [GitHub Issues](https://github.com/causalgo/causalgo/issues)\n\n## Citation\n\nIf using the SURD algorithm, please cite:\n\n```bibtex\n@article{martinez2024decomposing,\n  title={Decomposing causality into its synergistic, unique, and redundant components},\n  author={Mart{\\'\\i}nez-S{\\'a}nchez, {\\'A}lvaro and Arranz, Gonzalo and Lozano-Dur{\\'a}n, Adri{\\'a}n},\n  journal={Nature Communications},\n  volume={15},\n  pages={9296},\n  year={2024},\n  doi={10.1038/s41467-024-53373-4}\n}\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n## Contact\n\n- **Maintainer**: Andrey Kolkov - a.kolkov@gmail.com\n- **GitHub**: [https://github.com/causalgo/causalgo](https://github.com/causalgo/causalgo)\n- **Issues**: [https://github.com/causalgo/causalgo/issues](https://github.com/causalgo/causalgo/issues)\n\n---\n\n**Built with ❤️ using Go and Gonum**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcausalgo%2Fcausalgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcausalgo%2Fcausalgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcausalgo%2Fcausalgo/lists"}