Lightweight, offline-first AI math assistant for Windows PCs without GPU.
Runs entirely on CPU · Uses <15MB model · Zero cloud API calls required
| Feature | Details |
|---|---|
| 🖼 Image Upload | Upload PNG/JPG of handwritten equations |
| ✏️ Drawing Canvas | Draw equations directly in browser |
| 📷 Webcam Capture | Point camera at paper, capture frame |
| ⌨️ Text Input | Type equations with quick-solve |
| 🔢 Digit Recognition | EMNIST-trained CNN via ONNX |
| ➕ Operator Recognition | +, −, ×, ÷, =, ^, √, (, ) |
| 📐 Step-by-Step Solving | Full derivation with SymPy |
| 📊 Confidence Scores | Per-symbol and aggregate confidence |
| 💾 History | SQLite-backed solution history |
| 🌙 Dark Mode | Scientific dark theme |
- Windows 10 or 11
- Python 3.9 or later (download)
- No GPU required
- No Docker required
git clone https://github.com/yourname/neurocalc
cd neurocalc
start.batThat's it. The script will:
- Create a Python virtual environment
- Install all dependencies
- Launch the server at
http://localhost:8000 - Open your browser automatically
neurocalc/
│
├── backend/
│ ├── main.py ← FastAPI app entry point
│ ├── api/
│ │ └── routes.py ← All API endpoints
│ ├── preprocessing/
│ │ └── image_preprocessor.py ← CV pipeline
│ ├── recognition/
│ │ ├── cnn_model.py ← CNN architecture + symbol classes
│ │ ├── onnx_engine.py ← ONNX CPU inference
│ │ └── recognizer.py ← Full recognition pipeline
│ ├── parsing/
│ │ └── expression_parser.py ← String → SymPy
│ ├── solver/
│ │ └── equation_solver.py ← Step-by-step solver
│ └── database/
│ └── db.py ← SQLite operations
│
├── frontend/
│ └── index.html ← Single-file React-free UI
│
├── ml/
│ └── train_cnn.py ← Training + ONNX export script
│
├── models/
│ └── neurocalc_cnn.onnx ← Trained model (generated by train_cnn.py)
│
├── tests/
│ └── test_neurocalc.py ← pytest unit tests
│
├── requirements.txt
├── start.bat ← Windows one-click launch
├── start.sh ← Linux/macOS launch
└── README.md
All endpoints are under http://localhost:8000/api/
Health check and model status.
Response:
{
"status": "ok",
"version": "1.0.0",
"mode": "CPU-only",
"model_loaded": true
}Recognize a handwritten equation from an image.
Request: multipart/form-data
file— image file (PNG, JPG, BMP)
Response:
{
"equation": "2x + 4 = 10",
"tokens": [
{ "symbol": "2", "bbox": [10, 5, 30, 40], "confidence": 0.94 },
{ "symbol": "x", "bbox": [42, 5, 62, 40], "confidence": 0.87 }
],
"confidence": 0.91,
"inference_ms": 48.2
}Parse and solve an equation string.
Request body:
{
"equation": "x^2 - 5*x + 6 = 0",
"show_steps": true
}Response:
{
"equation": "x^2 - 5*x + 6 = 0",
"result": "2, 3",
"solutions": ["2", "3"],
"steps": [
{ "step": 1, "description": "Write the equation", "expression": "x**2 - 5*x + 6 = 0", "latex": "x^{2} - 5 x + 6 = 0" },
{ "step": 2, "description": "Identify coefficients: a=1, b=-5, c=6", "expression": "1x² + -5x + 6 = 0", "latex": "..." },
{ "step": 3, "description": "Calculate discriminant Δ = b² - 4ac", "expression": "Δ = 25 - 24 = 1", "latex": "..." },
{ "step": 4, "description": "Apply quadratic formula", "expression": "x = (5 ± 1) / 2", "latex": "..." },
{ "step": 5, "description": "Solution", "expression": "x = 2, x = 3", "latex": "x = 2, x = 3" }
],
"latex": "2, 3",
"solve_ms": 12.3
}One-shot: recognize image then solve.
Request: multipart/form-data — file
Response: Combined predict + solve response.
Process a webcam frame with frame-skipping support.
Request body:
{
"frame": "<base64-encoded-image>",
"skip_frames": 3
}Response:
{
"equation": "3x = 9",
"confidence": 0.78,
"skipped": false
}Retrieve recent solution history.
Response:
{
"history": [
{
"id": 42,
"equation": "sqrt(144)",
"result": "12",
"steps": [...],
"created_at": "2024-01-15T14:23:01"
}
]
}| Type | Examples |
|---|---|
| Arithmetic | 2 + 3 * 4, 100 / 5 - 8 |
| Fractions | 3/4 + 1/6, 12/8 |
| Powers | 2**10, x^3 |
| Roots | sqrt(144), sqrt(x+1) |
| Linear | 2x + 4 = 10, 3y - 7 = 2 |
| Quadratic | x^2 - 5x + 6 = 0 |
| Cubic | x^3 - 6x^2 + 11x - 6 = 0 |
| Simplification | expand((x+1)^2), factor(x^2-1) |
| Calculus | diff(x^3, x), d/dx(sin(x)) |
Input (1×28×28)
→ Conv2d(1→16) + BN + ReLU → MaxPool (14×14)
→ Conv2d(16→32) + BN + ReLU → MaxPool (7×7)
→ Conv2d(32→64) + BN + ReLU → AdaptiveAvgPool (4×4)
→ Linear(1024→128) + ReLU + Dropout(0.3)
→ Linear(128→26) ← output classes
~600K parameters · <5MB ONNX · <15MB quantized
0-9 digits · + - * / = operators · x y z variables
( ) brackets · ^ sqrt . , math symbols · < >
# Install training deps (optional)
pip install torch torchvision onnx
# Train on EMNIST (auto-downloads dataset)
python ml/train_cnn.py --epochs 20 --export
# Export existing weights to ONNX only
python ml/train_cnn.py --export-onlyIf no ONNX model is found, NeuroCalc uses a lightweight rule-based fallback classifier based on pixel density heuristics. Recognition accuracy is reduced but the system still functions for demos and testing the solve pipeline.
| Metric | Value |
|---|---|
| Model size | <5MB (ONNX), <2MB (quantized) |
| Startup time | ~2 seconds |
| Inference per symbol | <30ms on CPU |
| Memory usage | ~80MB RAM |
| Python dependencies | 8 packages |
| External API calls | Zero |
# Activate venv first
venv\Scripts\activate
# Run all tests
python -m pytest tests/ -v
# Run specific module
python -m pytest tests/test_neurocalc.py::TestEquationSolver -vpip install pyinstaller
pyinstaller --onefile --name neurocalc backend/main.pyThe resulting dist/neurocalc.exe runs without Python installed.
Edit backend/main.py to change:
port=8000— server portworkers=1— CPU workers (keep at 1 for low RAM)
MIT License — free to use, modify, and distribute.
- SymPy — symbolic math engine
- ONNX Runtime — CPU inference
- OpenCV — image preprocessing
- EMNIST Dataset — training data
- FastAPI — API framework
- KaTeX — LaTeX rendering in browser