Skip to content

nick-developer/constrained_data_simulator

Repository files navigation

EquationSolver — Large-Scale Linear & Non-Linear System Solver

A high-performance C++ DLL exposable as a Python package that solves systems of equations defined using Excel-style formulas and DP-syntax variable declarations.


Features

Capability Details
Variable syntax DP(name) where name ≤ 20 chars
Variable types NUMERIC, BOOLEAN, DATE, TEXT
Excel anchoring Each variable maps to a cell/range e.g. Sheet1!B2
Formula engine 40+ Excel-compatible functions (IF, SUM, SQRT, ROUND, MAX, MIN, AND, OR, CONCATENATE, DATE, YEAR…)
Linear solver Eigen FullPivLU / BDC SVD (exact + least-squares)
Non-linear solver Levenberg-Marquardt with numerical Jacobian + random restarts
Fallback Adaptive gradient descent
Propagation Topological constraint propagation pins assigned variables before solving
LOOCV Leave-One-Out Cross-Validation identifies conflicting constraints
Excel output Results, Solver_Summary, Solver_Constraints, LOOCV_Diagnosis sheets
Python API Full pybind11 bindings — import equationsolver as es

Build

Prerequisites

sudo apt install g++ cmake libeigen3-dev
pip install pybind11 numpy openpyxl

Compile

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

The Python extension equationsolver.cpython-*.so and shared library libequationsolver_dll.so are generated in build/.

Install as Python package

pip install . --no-build-isolation

Variable Definition Syntax

One variable per line. Comments start with #.

DP(name)  TYPE  ExcelRef  [optional_bounds]
Field Description Example
DP(name) Variable name, ≤ 20 chars DP(money_spent)
TYPE NUMERIC / BOOLEAN / DATE / TEXT NUMERIC
ExcelRef Cell or range in workbook Sheet1!B2 or Finance!A1:A100
[lo,hi] Optional numeric bounds [0, 1000000]

Example — variables.txt

# Financial variables
DP(revenue)        NUMERIC  Finance!B2   [0, 10000000]
DP(cost_of_goods)  NUMERIC  Finance!B3   [0, 10000000]
DP(gross_profit)   NUMERIC  Finance!B4
DP(tax_rate)       NUMERIC  Finance!B7   [0.0, 0.50]
DP(net_income)     NUMERIC  Finance!B9
DP(is_profitable)  BOOLEAN  Finance!B10
DP(report_date)    DATE     Finance!B12
DP(currency)       TEXT     Finance!B11

Constraint / Formula Syntax

One formula per line. Identical to Excel formula syntax.

Supported operators

Operator Meaning
= Equality constraint
<= , >= Inequality constraints
< , > Strict inequality
<> Not-equal (used as expression)

Supported functions

ABS, SQRT, POW, EXP, LN, LOG, ROUND, ROUNDDOWN, ROUNDUP, FLOOR, CEILING, MOD, MAX, MIN, SUM, AVERAGE, COUNT, INT, TRUNC, SIGN, SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2, DEGREES, RADIANS, PI, RAND, RANDBETWEEN, IF, AND, OR, NOT, ISNUMBER, ISBLANK, ISERROR, CONCATENATE, CONCAT, LEFT, RIGHT, MID, LEN, TRIM, UPPER, LOWER, VALUE, TEXT, TODAY, DATE, YEAR, MONTH, DAY

Example — constraints.txt

# Accounting identities
DP(gross_profit) = DP(revenue) - DP(cost_of_goods)
DP(net_income)   = DP(gross_profit) * (1 - DP(tax_rate))
DP(is_profitable) = IF(DP(net_income) > 0, TRUE, FALSE)

# Business rules
DP(cost_of_goods) = 0.45 * DP(revenue)
DP(tax_rate)      = 0.28
DP(revenue)       = 1000000

# Inequality constraints
DP(net_income) >= 0
DP(tax_rate)   <= 0.5

Python API

import equationsolver as es

# Create solver
solver = es.Solver()

# Load inputs
solver.load_variables_from_file("variables.txt")
solver.load_constraints_from_file("constraints.txt")

# Or inline
solver.load_variables_from_text("""
    DP(x)  NUMERIC  Sheet1!A1
    DP(y)  NUMERIC  Sheet1!B1
""")
solver.load_constraints_from_text("""
    DP(x)^2 + DP(y)^2 = 25
    DP(x) + DP(y) = 7
""")

# Optionally seed initial guesses
solver.set_initial_value("x", 3.0)
solver.set_initial_value("y", 4.0)

# Tune solver (optional)
solver.max_iterations = 5000
solver.tolerance      = 1e-9
solver.restarts       = 15
solver.verbose        = True

# Solve
message = solver.solve()
print(solver.get_status())           # "OPTIMAL" | "PARTIAL" | "INFEASIBLE" | "ERROR"
print(solver.get_residual_norm())    # float
print(solver.get_variable_values())  # dict {name: value}

# Constraint report
for c in solver.get_constraint_report():
    print(c['id'], c['formula'], c['satisfied'], c['residual'])

# Write Excel output
solver.write_excel("output.xlsx")

When no solution exists — LOOCV

if solver.get_status() in ("PARTIAL", "INFEASIBLE"):
    report = solver.get_loocv_report()
    print("Conflicting constraint IDs:", report['conflicting'])
    print("Diagnosis:", report['diagnosis'])
    solver.write_excel("output.xlsx")  # includes LOOCV_Diagnosis sheet

Solver Algorithm

Input: Variables V, Constraints C

Phase 0 — Topological Propagation
  While any DP(x) = <fully-resolved-expr> exists:
    Pin x = eval(expr), remove from free set

Phase 1 — Classify System
  If all formulas are linear → Eigen SVD/LU
  Else → Levenberg-Marquardt (nonlinear)

Phase 2 — Iterative Solve (with random restarts)
  Newton-LM:
    Compute numerical Jacobian J (O(n) perturbations)
    Solve (JᵀJ + λI) Δx = -Jᵀr  (Levenberg-Marquardt)
    Update x, adapt λ based on gain ratio
  If Newton-LM fails → gradient descent fallback

Phase 3 — Verification
  Check all constraints: |lhs - rhs| < tolerance

Phase 4 — LOOCV (only if Phase 3 fails)
  For each constraint i:
    Solve system with constraint i removed
    If solvable → constraint i is conflicting
  Pairwise removal to find minimal conflict set
  Write diagnosis to Excel LOOCV_Diagnosis sheet

Excel Output Sheets

Sheet Contents
<original sheets> Solved values written to their anchored cells
Solver_Summary Variable name / ref / type / solved value
Solver_Constraints ID / formula / satisfied (green/red) / residual
LOOCV_Diagnosis Conflicting vs satisfied constraints (only on failure)

Project Structure

solverlib/
├── include/
│   ├── variable.hpp       — Variable & Constraint type definitions
│   ├── expr_parser.hpp    — Excel formula AST & evaluator
│   ├── input_parser.hpp   — DP syntax & formula file parsers
│   ├── solver_engine.hpp  — SolverEngine, LOOCV, SolveResult
│   └── excel_writer.hpp   — openpyxl-backed Excel output
├── src/
│   ├── expr_parser.cpp    — Recursive-descent parser + 40+ builtins
│   ├── input_parser.cpp   — Variable and constraint parsers
│   ├── solver_engine.cpp  — Newton-LM, linear, GD, LOOCV
│   └── excel_writer.cpp   — xlsx generation via Python subprocess
├── python/
│   └── bindings.cpp       — pybind11 module definition
├── tests/
│   └── demo.py            — 8 test suites + simulated data generation
├── CMakeLists.txt
├── setup.py
└── README.md

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors