{"id":50996112,"url":"https://github.com/pgmpy/ci-tests","last_synced_at":"2026-06-20T09:33:35.058Z","repository":{"id":363612485,"uuid":"1264126882","full_name":"pgmpy/ci-tests","owner":"pgmpy","description":"High performance Rust implementation of conditional independence tests with extensions in Python, R, and JS","archived":false,"fork":false,"pushed_at":"2026-06-09T16:23:01.000Z","size":537,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T17:25:40.778Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/pgmpy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-09T15:29:16.000Z","updated_at":"2026-06-09T16:23:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pgmpy/ci-tests","commit_stats":null,"previous_names":["pgmpy/ci-tests"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pgmpy/ci-tests","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgmpy%2Fci-tests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgmpy%2Fci-tests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgmpy%2Fci-tests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgmpy%2Fci-tests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pgmpy","download_url":"https://codeload.github.com/pgmpy/ci-tests/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgmpy%2Fci-tests/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34565240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-20T09:33:32.634Z","updated_at":"2026-06-20T09:33:35.049Z","avatar_url":"https://github.com/pgmpy.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Conditional Independence Testing\n\n[![CI](https://img.shields.io/github/actions/workflow/status/GiPHouse/Conditional-Independence-Testing/rust.yml?branch=main\u0026logo=github\u0026label=CI)](https://github.com/GiPHouse/Conditional-Independence-Testing/actions)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/GiPHouse/Conditional-Independence-Testing/blob/main/LICENSE)\n\nA fast, multi-language library for **conditional independence (CI) testing**: deciding\nwhether two variables $X$ and $Y$ are independent given a (possibly empty) set of\nconditioning variables $Z$ — written $X \\perp Y \\mid Z$. CI tests are a fundamental building\nblock of constraint-based causal discovery and of structure learning for probabilistic\ngraphical models.\n\nEvery test is implemented once in a dependency-light **Rust core** (`ci-core`) and exposed\nthrough thin, idiomatic bindings for **Python, R, and JavaScript/WebAssembly**. \n\n## Quick Start\n\nEach binding compiles the Rust core from source, so you need a Rust toolchain installed\n(via [rustup](https://rustup.rs)). In every language a test takes the observation vectors\n`x` and `y` and a conditioning matrix `z` whose columns are the conditioning variables;\npass a zero-column matrix for an unconditional test.\n\n### Python\n\nBuild and install the package from the repository root:\n\n```bash\npip install maturin\nmaturin develop -m crates/ci-python/Cargo.toml\n```\n\n```python\nimport numpy as np\nfrom ci_python import ChiSquared\n\nx = np.array([1.0, 1.0, 2.0, 2.0, 1.0, 1.0, 2.0, 2.0])\ny = np.array([1.0, 2.0, 1.0, 2.0, 1.0, 2.0, 1.0, 2.0])\n\ntest = ChiSquared(boolean=False, significance_level=0.05)\n\n# Unconditional: pass an (n, 0) matrix for an empty conditioning set\np_value, statistic, dof = test.run_test(x, y, np.empty((len(x), 0)))\nprint(f\"p={p_value:.4f}, chi2={statistic:.4f}, df={dof}\")\n\n# Conditional: each column of z is one conditioning variable\nz = np.array([[1.0]] * 4 + [[2.0]] * 4)\np_value, statistic, dof = test.run_test(x, y, z)\n```\n\nContinuous tests (`PearsonCorrelation`, `PearsonEquivalence`) share the same interface but\nreturn `(p_value, coefficient)`. In boolean mode (`boolean=True`) every test returns just a\n`bool` independence verdict.\n\n### R\n\nInstall the package from the repository root:\n\n```r\n# install.packages(\"devtools\")\ndevtools::install(\"crates/ci-r\")\n```\n\n```r\nlibrary(cir)\n\nx \u003c- c(1, 1, 2, 2, 1, 1, 2, 2)\ny \u003c- c(1, 2, 1, 2, 1, 2, 1, 2)\n\n# Unconditional: a 0-column matrix is an empty conditioning set\nz \u003c- matrix(nrow = length(x), ncol = 0)\nresult \u003c- chi_squared_test(x, y, z, boolean = FALSE, significance_level = 0.05)\ncat(\"p =\", result$p_value, \" chi2 =\", result$statistic, \" df =\", result$df, \"\\n\")\n\n# Conditional: each column of z is one conditioning variable\nz \u003c- matrix(c(1, 1, 1, 1, 2, 2, 2, 2), ncol = 1)\nresult \u003c- chi_squared_test(x, y, z, boolean = FALSE, significance_level = 0.05)\n\n# Boolean mode returns only an independence verdict\nverdict \u003c- pearson_correlation_test(x, y, z, boolean = TRUE, significance_level = 0.05)\ncat(\"independent:\", verdict$independent, \"\\n\")\n```\n\nEach function returns a named list with a `kind` field: `\"statistic\"` (with `p_value`,\n`statistic`, `df`), `\"pvalue\"` (with `p_value`, `coefficient`), or `\"boolean\"` (with\n`independent`).\n\n### JavaScript\n\nBuild the WebAssembly package with [wasm-pack](https://rustwasm.github.io/wasm-pack/); the\noutput is written to `crates/ci-js/pkg`:\n\n```bash\nwasm-pack build crates/ci-js --target web      # for browsers\nwasm-pack build crates/ci-js --target nodejs   # for Node.js\n```\n\n```js\nimport init, { chi_squared_test } from \"./pkg/ci_js.js\";\n\nawait init(); // load the WebAssembly module (web target)\n\nconst x = new Float64Array([1, 1, 2, 2, 1, 1, 2, 2]);\nconst y = new Float64Array([1, 2, 1, 2, 1, 2, 1, 2]);\n\n// Unconditional: pass an empty Float64Array; z_rows = z_cols = 0\nconst [pValue, statistic, dof] = chi_squared_test(new Float64Array(0), 0, 0, x, y, false, 0.05);\nconsole.log(`p=${pValue.toFixed(4)}, chi2=${statistic.toFixed(4)}, df=${dof}`);\n\n// Conditional: z is a row-major flattened (z_rows x z_cols) matrix\nconst z = new Float64Array([1, 1, 1, 1, 2, 2, 2, 2]);\nconst [pCond] = chi_squared_test(z, 8, 1, x, y, false, 0.05);\n```\n\nThe conditioning matrix is passed flattened (`z_flat`, `z_rows`, `z_cols`) because\nWebAssembly has no native 2-D array type. Discrete tests return `[p_value, statistic, dof]`,\ncontinuous tests return `[p_value, coefficient]`, and boolean mode returns a `bool`.\n\n## Available Tests\n\n| Test | Data type | Numeric output |\n|---|---|---|\n| `chi_squared` | Discrete | `(p_value, statistic, dof)` |\n| `log_likelihood` (G-test) | Discrete | `(p_value, statistic, dof)` |\n| `cressie_read` | Discrete | `(p_value, statistic, dof)` |\n| `freeman_tukey` | Discrete | `(p_value, statistic, dof)` |\n| `modified_likelihood` | Discrete | `(p_value, statistic, dof)` |\n| `pearson_correlation` | Continuous | `(p_value, coefficient)` |\n| `pearson_equivalence` | Continuous | `(p_value, coefficient)` |\n\n- **Conditioning.** Every test accepts a conditioning matrix `Z` (each column is one\n  conditioning variable). For conditional discrete tests the statistic is summed over the\n  strata defined by `Z`; for continuous tests the partial correlation is taken on the\n  regression residuals.\n- **Discrete family.** The discrete tests are members of the power-divergence family and\n  differ only in the $\\lambda$ parameter: `chi_squared` ($1$), `log_likelihood` ($0$),\n  `cressie_read` ($2/3$), `freeman_tukey` ($-1/2$), `modified_likelihood` ($-1$).\n- **Boolean mode.** With `boolean=true`, a test returns a single independence verdict at the\n  given `significance_level` instead of the numeric tuple.\n- **Equivalence test.** `pearson_equivalence` is an equivalence (TOST) test: it additionally\n  takes a `delta_threshold` and declares independence when the partial correlation lies\n  within that margin of zero.\n- **Naming.** Python exposes these as classes (`ChiSquared`, `LogLikelihood`, …); R and\n  JavaScript expose them as functions with a `_test` suffix (`chi_squared_test`, …).\n\n## Package Structure \u0026 Contributing\n\n```\nci-core     Rust core: all test implementations and the CITest trait\nci-python   Python bindings (PyO3)        -\u003e import ci_python\nci-r        R package (extendr)           -\u003e library(cir)\nci-js       JavaScript / WASM (wasm-pack)\n```\n\nAll bindings are thin wrappers that depend only on `ci-core`, so the statistics live in a\nsingle place. The Rust core can also be used directly as a crate. Full API documentation is\npublished at \u003chttps://giphouse.github.io/Conditional-Independence-Testing/\u003e.\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for environment setup,\ncoding standards, and how to add a new test. Before opening a PR:\n\n```bash\ncargo fmt --all\ncargo clippy --workspace --all-targets -- -D warnings\ncargo test --workspace\n```\n\n## License\n\nLicensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgmpy%2Fci-tests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpgmpy%2Fci-tests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgmpy%2Fci-tests/lists"}