Skip to content

Add multi-value QCA with direct cube minimisation - #18

Merged
DiogoRibeiro7 merged 6 commits into
mainfrom
feat/multivalue-qca
Aug 11, 2026
Merged

Add multi-value QCA with direct cube minimisation#18
DiogoRibeiro7 merged 6 commits into
mainfrom
feat/multivalue-qca

Conversation

@DiogoRibeiro7

@DiogoRibeiro7 DiogoRibeiro7 commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Categorical conditions with more than two levels, minimised as multi-value cubes rather than reduced to Boolean indicators.

result = MVQCA(consistency=0.8).fit(data, outcome="Y", conditions=["regime", "wealth"])
result.domain            # regime{0,1,2}, wealth{0,1}
result.summary_frame("parsimonious")

The workflow mirrors FSQCA/CSQCA deliberately: moving between them is a change of estimator, not of method.

Why not Boolean dummies

Encoding A{0,1,2} as three indicators does not preserve the semantics. The binary space contains points such as A_0 = A_1 = 1 — a case in two mutually exclusive categories at once, corresponding to no configuration at all — and the minimiser is free to build implicants across them, producing terms that look valid and describe nothing. Recovering a multi-value expression afterwards needs exactly the mutual-exclusivity constraints the encoding discarded.

The cube algebra is therefore implemented directly. Merging generalises the binary rule: two cubes agreeing on every condition but one merge into a cube whose set at that condition is the union. Because they agree everywhere else, the merged cube covers exactly their union and nothing more — the property the binary rule relies on, unchanged. Tests assert that directly, and that every cube covers only real configurations.

One solver, one guarantee

Rather than write a second exact solver, the branch-and-bound was extracted into solve_minimum_cover, which works on coverage sets. The binary engine and the multi-value engine now share one verified implementation; all 45 existing exactness and chart tests passed unchanged through the refactor.

Verified by exhaustive enumeration for levels (2,2), (3,2), (2,3) and (3,3), and against the binary minimiser for every three-condition problem.

Agreement with R

R supports multi-value and writes regime[2]. Truth tables and parsimonious solutions match exactly. The conservative solution can differ in representation:

R:      regime[2] + regime[1]*wealth[1]
setqca: regime{2} + regime{1,2}*wealth{1}

Same coverage, same cost (2 terms, 3 literals) — both minimal. R writes single-value literals only, so its regime[1]*wealth[1] is a proper subset of regime{1,2}*wealth{1} and is therefore not a prime implicant. Parity tests compare cost and coverage rather than text, which is the comparison that carries meaning.

Levels are inferred from the data but can be declared, because an unobserved-but-possible level is a remainder and changes the parsimonious solution.

562 tests at 100% coverage; mypy strict and docs build clean.


Summary by cubic

Introduce multi-value QCA (MVQCA) with direct cube minimisation so categorical conditions are handled correctly without boolean dummies. Share one exact cover solver across binary and multi-value; solutions match R in cost and coverage.

  • New Features

    • MVQCA estimator, MultiValueDomain, and MultiValueTruthTable with mixed‑radix indexing and direct cube merging.
    • Conservative and parsimonious solutions; summary_frame() includes consistency and coverage.
    • Levels inferred from data, with optional declarations to account for unobserved remainders.
    • Parity with R: truth tables and parsimonious solutions match; conservative solutions match in coverage and cost.
    • Docs: new “Multi-value QCA” guide and nav entry; API exported at setqca root.
  • Refactors

    • Extracted shared exact cover solver solve_minimum_cover and updated binary minimiser to use it, reducing duplication while preserving exactness (existing tests unchanged).

Written for commit 878d7ca. Summary will update on new commits.

Review in cubic

@DiogoRibeiro7
DiogoRibeiro7 merged commit 41b6a2d into main Aug 11, 2026
14 of 15 checks passed
@DiogoRibeiro7
DiogoRibeiro7 deleted the feat/multivalue-qca branch August 11, 2026 09:20
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant