blackbox2c 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. blackbox2c-0.1.0/CHANGELOG.md +80 -0
  2. blackbox2c-0.1.0/LICENSE +21 -0
  3. blackbox2c-0.1.0/MANIFEST.in +8 -0
  4. blackbox2c-0.1.0/PKG-INFO +298 -0
  5. blackbox2c-0.1.0/README.md +257 -0
  6. blackbox2c-0.1.0/blackbox2c/__init__.py +91 -0
  7. blackbox2c-0.1.0/blackbox2c/analysis.py +446 -0
  8. blackbox2c-0.1.0/blackbox2c/cli.py +302 -0
  9. blackbox2c-0.1.0/blackbox2c/codegen.py +318 -0
  10. blackbox2c-0.1.0/blackbox2c/config.py +111 -0
  11. blackbox2c-0.1.0/blackbox2c/converter.py +350 -0
  12. blackbox2c-0.1.0/blackbox2c/exporters.py +755 -0
  13. blackbox2c-0.1.0/blackbox2c/optimizer.py +245 -0
  14. blackbox2c-0.1.0/blackbox2c/surrogate.py +217 -0
  15. blackbox2c-0.1.0/blackbox2c.egg-info/PKG-INFO +298 -0
  16. blackbox2c-0.1.0/blackbox2c.egg-info/SOURCES.txt +37 -0
  17. blackbox2c-0.1.0/blackbox2c.egg-info/dependency_links.txt +1 -0
  18. blackbox2c-0.1.0/blackbox2c.egg-info/entry_points.txt +2 -0
  19. blackbox2c-0.1.0/blackbox2c.egg-info/requires.txt +14 -0
  20. blackbox2c-0.1.0/blackbox2c.egg-info/top_level.txt +1 -0
  21. blackbox2c-0.1.0/examples/feature_selection_example.py +261 -0
  22. blackbox2c-0.1.0/examples/iris_example.py +254 -0
  23. blackbox2c-0.1.0/examples/multi_format_export.py +359 -0
  24. blackbox2c-0.1.0/examples/temperature_regression.py +359 -0
  25. blackbox2c-0.1.0/pyproject.toml +110 -0
  26. blackbox2c-0.1.0/requirements.txt +2 -0
  27. blackbox2c-0.1.0/setup.cfg +4 -0
  28. blackbox2c-0.1.0/tests/__init__.py +3 -0
  29. blackbox2c-0.1.0/tests/test_analysis.py +301 -0
  30. blackbox2c-0.1.0/tests/test_cli.py +238 -0
  31. blackbox2c-0.1.0/tests/test_codegen.py +164 -0
  32. blackbox2c-0.1.0/tests/test_config.py +82 -0
  33. blackbox2c-0.1.0/tests/test_converter.py +238 -0
  34. blackbox2c-0.1.0/tests/test_exporters.py +648 -0
  35. blackbox2c-0.1.0/tests/test_optimizer.py +135 -0
  36. blackbox2c-0.1.0/tests/test_regression.py +394 -0
  37. blackbox2c-0.1.0/tests/test_reproducibility.py +151 -0
  38. blackbox2c-0.1.0/tests/test_surrogate.py +135 -0
  39. blackbox2c-0.1.0/tests/test_target_param.py +239 -0
@@ -0,0 +1,80 @@
1
+ # Changelog
2
+
3
+ All notable changes to BlackBox2C will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-04-15
9
+
10
+ ### Fixed
11
+ - **`pyproject.toml`**: `project.dependencies` was incorrectly formatted as a TOML table instead of an array of PEP 508 strings, preventing installation (`pip install` failed with `configuration error`).
12
+ - **Regression detection**: `SurrogateExtractor` and `Converter` used a fragile `_estimator_type` instance-attribute check that failed for ensemble regressors (`RandomForestRegressor`, `GradientBoostingRegressor`) in scikit-learn ≥ 1.8. Replaced with `sklearn.base.is_regressor()` with a safe fallback for non-conformant mock models.
13
+ - **Build system**: Removed `setuptools_scm` from build dependencies (was unused; no git tag versioning configured) and dropped legacy `setup.py` that duplicated `pyproject.toml` metadata.
14
+
15
+ ### Changed
16
+ - Promoted from beta (`0.1.0b1`) to stable (`0.1.0`).
17
+ - Development Status classifier updated to `5 - Production/Stable`.
18
+ - Added `[tool.setuptools.packages.find]` section to `pyproject.toml` for explicit package discovery.
19
+
20
+ ---
21
+
22
+ ## [0.1.0b1] - 2025-07-01
23
+
24
+ ### Added
25
+ - **Multi-format export**: Support for C, C++11, Arduino, and MicroPython
26
+ - **Regression support**: Full support for regression models (DecisionTreeRegressor, RandomForestRegressor, GradientBoostingRegressor)
27
+ - **Feature analysis**: Automatic feature importance analysis with `FeatureSensitivityAnalyzer`
28
+ - **Factory pattern**: Easy exporter creation with `create_exporter()`
29
+ - **Comprehensive tests**: 128 tests covering all functionality
30
+ - **Complete examples**: 4 full examples demonstrating all features
31
+
32
+ ### Features
33
+ - Convert scikit-learn models to optimized embedded code
34
+ - Support for classification and regression tasks
35
+ - Automatic task detection (classification vs regression)
36
+ - Surrogate model extraction for complex models (SVM, Neural Networks)
37
+ - Rule optimization with configurable levels (low, medium, high)
38
+ - Fixed-point arithmetic support for resource-constrained devices
39
+ - Memory budget management
40
+ - Code size estimation
41
+ - Fidelity calculation
42
+
43
+ ### Exporters
44
+ - **C Exporter**: Standard C code with if-else logic
45
+ - **C++ Exporter**: Modern C++11 with classes, templates, and STL
46
+ - **Arduino Exporter**: Optimized for Arduino boards with PROGMEM support
47
+ - **MicroPython Exporter**: Pure Python for microcontrollers
48
+
49
+ ### Examples
50
+ - `iris_example.py`: Classification with multiple models
51
+ - `temperature_regression.py`: Regression with 5 use cases
52
+ - `feature_selection_example.py`: Feature importance analysis
53
+ - `multi_format_export.py`: Export to all formats
54
+
55
+ ### Documentation
56
+ - Comprehensive README with quick start guide
57
+ - API documentation in docstrings
58
+ - Complete examples with explanations
59
+ - Troubleshooting guide
60
+
61
+ ### Tests
62
+ - 128 tests (100% passing)
63
+ - ~90% code coverage
64
+ - Unit tests for all modules
65
+ - Integration tests
66
+ - Edge case tests
67
+
68
+ ## [Unreleased]
69
+
70
+ ### Planned
71
+ - Command-line interface (CLI) enhancements
72
+ - Additional optimization algorithms (Quine-McCluskey, BDD)
73
+ - Hardware-specific optimizations (SIMD, vectorization)
74
+ - Quantization-aware training integration
75
+ - Automated benchmarking on real hardware
76
+
77
+ ---
78
+
79
+ [0.1.0]: https://github.com/AxelSkrauba/BlackBox2C/releases/tag/v0.1.0
80
+ [0.1.0b1]: https://github.com/AxelSkrauba/BlackBox2C/releases/tag/v0.1.0b1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BlackBox2C
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ include CHANGELOG.md
5
+ recursive-include examples *.py
6
+ recursive-include tests *.py
7
+ recursive-exclude * __pycache__
8
+ recursive-exclude * *.py[co]
@@ -0,0 +1,298 @@
1
+ Metadata-Version: 2.4
2
+ Name: blackbox2c
3
+ Version: 0.1.0
4
+ Summary: Convert ML models to optimized code for embedded systems
5
+ Author: Axel Skrauba
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/AxelSkrauba/BlackBox2C
8
+ Project-URL: Documentation, https://axelskrauba.github.io/BlackBox2C
9
+ Project-URL: Repository, https://github.com/AxelSkrauba/BlackBox2C
10
+ Project-URL: Bug Tracker, https://github.com/AxelSkrauba/BlackBox2C/issues
11
+ Keywords: machine-learning,embedded-systems,code-generation,tinyml,arduino,micropython
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Classifier: Topic :: Software Development :: Code Generators
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Software Development :: Embedded Systems
24
+ Classifier: Operating System :: OS Independent
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: numpy>=1.21.0
29
+ Requires-Dist: scikit-learn>=1.0.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
33
+ Requires-Dist: black>=23.0.0; extra == "dev"
34
+ Requires-Dist: flake8>=6.0.0; extra == "dev"
35
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
36
+ Requires-Dist: mkdocs>=1.5.0; extra == "dev"
37
+ Requires-Dist: mkdocs-material>=9.0.0; extra == "dev"
38
+ Provides-Extra: viz
39
+ Requires-Dist: matplotlib>=3.5.0; extra == "viz"
40
+ Dynamic: license-file
41
+
42
+ # BlackBox2C
43
+
44
+ **Convert scikit-learn models to native embedded code — C, C++, Arduino, MicroPython**
45
+
46
+ [![Tests](https://github.com/AxelSkrauba/BlackBox2C/actions/workflows/ci.yml/badge.svg)](https://github.com/AxelSkrauba/BlackBox2C/actions)
47
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
49
+ [![Version](https://img.shields.io/badge/version-0.1.0-blue)](CHANGELOG.md)
50
+
51
+ BlackBox2C converts any trained scikit-learn model into a minimal if-else decision tree in your
52
+ target language. The generated code has **zero runtime dependencies**, runs on any microcontroller
53
+ with a C compiler, and fits in a few hundred bytes of FLASH.
54
+
55
+ ---
56
+
57
+ ## How It Works
58
+
59
+ 1. **Surrogate extraction** — A lightweight `DecisionTree` is trained to mimic any black-box model
60
+ (Random Forest, SVM, MLP, etc.) by generating synthetic boundary samples and labeling them with
61
+ the original model's predictions.
62
+ 2. **Rule optimization** — Redundant branches are pruned and similar leaves are merged to minimize
63
+ code size.
64
+ 3. **Code generation** — The optimized tree is serialized as a pure if-else function in the target
65
+ language.
66
+
67
+ ---
68
+
69
+ ## Supported Models and Targets
70
+
71
+ | Input models | Output formats |
72
+ |---|---|
73
+ | Any scikit-learn estimator with `predict()` | Pure C (C99) |
74
+ | Decision Tree, Random Forest, SVM, MLP... | C++11 (class + namespace) |
75
+ | Classification and Regression tasks | Arduino (`.h` with PROGMEM) |
76
+ | | MicroPython (`.py` module) |
77
+
78
+ ---
79
+
80
+ ## Installation
81
+
82
+ ```bash
83
+ # From source (development)
84
+ pip install -e .
85
+
86
+ # With dev dependencies (pytest, mkdocs, etc.)
87
+ pip install -e ".[dev]"
88
+ ```
89
+
90
+ Requirements: Python 3.8+, NumPy >= 1.21, scikit-learn >= 1.0.
91
+
92
+ ---
93
+
94
+ ## Quick Start
95
+
96
+ ### Classification
97
+
98
+ ```python
99
+ from sklearn.ensemble import RandomForestClassifier
100
+ from sklearn.datasets import load_iris
101
+ from blackbox2c import convert
102
+
103
+ iris = load_iris()
104
+ model = RandomForestClassifier(n_estimators=50, random_state=42)
105
+ model.fit(iris.data, iris.target)
106
+
107
+ # Convert to C (default target)
108
+ c_code = convert(
109
+ model,
110
+ iris.data,
111
+ feature_names=list(iris.feature_names),
112
+ class_names=list(iris.target_names),
113
+ max_depth=5,
114
+ )
115
+ print(c_code)
116
+ ```
117
+
118
+ Generated output:
119
+
120
+ ```c
121
+ /*
122
+ * Auto-generated C code by BlackBox2C
123
+ * - Input features: 4
124
+ * - Output classes: 3
125
+ * - Precision: 8-bit
126
+ */
127
+ #include <stdint.h>
128
+
129
+ #define setosa 0
130
+ #define versicolor 1
131
+ #define virginica 2
132
+
133
+ uint8_t predict(float features[4]) {
134
+ if (features[2] <= 2.449999f) {
135
+ return 0;
136
+ } else {
137
+ if (features[3] <= 1.750000f) {
138
+ return 1;
139
+ } else {
140
+ return 2;
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### Export to Other Formats
147
+
148
+ ```python
149
+ # Arduino .h file
150
+ arduino_code = convert(model, iris.data, target='arduino')
151
+
152
+ # C++ class
153
+ cpp_code = convert(model, iris.data, target='cpp')
154
+
155
+ # MicroPython module
156
+ mp_code = convert(model, iris.data, target='micropython')
157
+ ```
158
+
159
+ ### Regression
160
+
161
+ ```python
162
+ from sklearn.ensemble import GradientBoostingRegressor
163
+ from sklearn.datasets import load_diabetes
164
+ from blackbox2c import convert
165
+
166
+ data = load_diabetes()
167
+ model = GradientBoostingRegressor(random_state=42)
168
+ model.fit(data.data, data.target)
169
+
170
+ c_code = convert(model, data.data, max_depth=5)
171
+ # Generates: float predict(float features[10]) { ... }
172
+ ```
173
+
174
+ ### Feature Analysis
175
+
176
+ ```python
177
+ from blackbox2c.analysis import FeatureSensitivityAnalyzer
178
+
179
+ analyzer = FeatureSensitivityAnalyzer(n_repeats=10, random_state=42)
180
+ results = analyzer.analyze(model, X_train, y_train, feature_names=feature_names)
181
+ print(results.summary())
182
+
183
+ # Get top 3 most important features by index
184
+ top3 = results.get_top_features(3)
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Configuration
190
+
191
+ ```python
192
+ from blackbox2c import Converter, ConversionConfig
193
+
194
+ config = ConversionConfig(
195
+ max_depth=5, # Surrogate tree depth (1-10, default 5)
196
+ optimize_rules='medium', # 'low' | 'medium' | 'high'
197
+ use_fixed_point=False, # Use integer arithmetic instead of float
198
+ precision=8, # Bit width for fixed-point: 8 | 16 | 32
199
+ function_name='predict', # Name of the generated function
200
+ n_samples=10000, # Synthetic samples for surrogate training
201
+ feature_threshold=None, # Auto-select N most important features
202
+ memory_budget_kb=None, # Auto-tune params to fit a KB budget
203
+ )
204
+
205
+ converter = Converter(config)
206
+ code = converter.convert(model, X_train, target='arduino')
207
+ metrics = converter.get_metrics()
208
+ # {'fidelity': 0.97, 'complexity': {...}, 'size_estimate': {...}}
209
+ ```
210
+
211
+ ---
212
+
213
+ ## CLI
214
+
215
+ ```bash
216
+ # Convert a pickled model to C
217
+ blackbox2c convert model.pkl X_train.npy -o output.c
218
+
219
+ # Export to Arduino
220
+ blackbox2c convert model.pkl X_train.npy -t arduino -o predict.h
221
+
222
+ # Analyze feature importance
223
+ blackbox2c analyze model.pkl X_train.npy --top-n 5
224
+
225
+ # Export a decision tree directly (no surrogate extraction)
226
+ blackbox2c export model.pkl -f cpp -o predictor.hpp
227
+
228
+ # Help
229
+ blackbox2c --help
230
+ blackbox2c convert --help
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Benchmarks
236
+
237
+ ```bash
238
+ python benchmarks/benchmark_classic_datasets.py --output results.md
239
+ ```
240
+
241
+ Covers Iris, Wine, Diabetes, and California Housing with Decision Trees, Random Forests, SVMs,
242
+ and Neural Networks. Metrics: fidelity, estimated FLASH size, tree depth, conversion time.
243
+
244
+ > **Note**: Code size figures are estimates from BlackBox2C's built-in size estimator,
245
+ > not measurements on real hardware.
246
+
247
+ ---
248
+
249
+ ## Project Structure
250
+
251
+ ```
252
+ blackbox2c/
253
+ ├── blackbox2c/
254
+ │ ├── __init__.py # Public API: convert(), Converter, ConversionConfig
255
+ │ ├── converter.py # Main orchestration pipeline
256
+ │ ├── config.py # ConversionConfig dataclass
257
+ │ ├── surrogate.py # Surrogate tree extraction
258
+ │ ├── codegen.py # C code generation
259
+ │ ├── optimizer.py # Rule pruning and merging
260
+ │ ├── exporters.py # C++, Arduino, MicroPython exporters
261
+ │ ├── analysis.py # Feature sensitivity analysis
262
+ │ └── cli.py # Command-line interface
263
+ ├── tests/ # 167 tests, >91% coverage
264
+ ├── benchmarks/ # Classic dataset benchmarks
265
+ ├── examples/ # End-to-end usage examples
266
+ └── docs/ # MkDocs documentation source
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Comparison with Alternatives
272
+
273
+ | Feature | BlackBox2C | emlearn | MicroMLGen | TFLite Micro |
274
+ |---|---|---|---|---|
275
+ | Any sklearn model | ✅ | ⚠️ Trees only | ⚠️ Trees only | ❌ TF only |
276
+ | Pure if-else output | ✅ | ✅ | ✅ | ❌ |
277
+ | C++ / Arduino / MicroPython | ✅ | ⚠️ Partial | ❌ | ⚠️ Partial |
278
+ | Feature selection built-in | ✅ | ❌ | ❌ | ❌ |
279
+ | Memory budget control | ✅ | ❌ | ❌ | ⚠️ |
280
+ | Zero runtime dependencies | ✅ | ✅ | ✅ | ❌ |
281
+
282
+ ---
283
+
284
+ ## Roadmap (v0.2)
285
+
286
+ - Quine-McCluskey and BDD rule optimization
287
+ - Hardware-validated benchmarks on real MCUs
288
+ - Quantization-aware training integration
289
+
290
+ ---
291
+
292
+ ## License
293
+
294
+ MIT — see [LICENSE](LICENSE).
295
+
296
+ ## Contributing
297
+
298
+ Issues and PRs welcome at [github.com/AxelSkrauba/BlackBox2C](https://github.com/AxelSkrauba/BlackBox2C).
@@ -0,0 +1,257 @@
1
+ # BlackBox2C
2
+
3
+ **Convert scikit-learn models to native embedded code — C, C++, Arduino, MicroPython**
4
+
5
+ [![Tests](https://github.com/AxelSkrauba/BlackBox2C/actions/workflows/ci.yml/badge.svg)](https://github.com/AxelSkrauba/BlackBox2C/actions)
6
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
8
+ [![Version](https://img.shields.io/badge/version-0.1.0-blue)](CHANGELOG.md)
9
+
10
+ BlackBox2C converts any trained scikit-learn model into a minimal if-else decision tree in your
11
+ target language. The generated code has **zero runtime dependencies**, runs on any microcontroller
12
+ with a C compiler, and fits in a few hundred bytes of FLASH.
13
+
14
+ ---
15
+
16
+ ## How It Works
17
+
18
+ 1. **Surrogate extraction** — A lightweight `DecisionTree` is trained to mimic any black-box model
19
+ (Random Forest, SVM, MLP, etc.) by generating synthetic boundary samples and labeling them with
20
+ the original model's predictions.
21
+ 2. **Rule optimization** — Redundant branches are pruned and similar leaves are merged to minimize
22
+ code size.
23
+ 3. **Code generation** — The optimized tree is serialized as a pure if-else function in the target
24
+ language.
25
+
26
+ ---
27
+
28
+ ## Supported Models and Targets
29
+
30
+ | Input models | Output formats |
31
+ |---|---|
32
+ | Any scikit-learn estimator with `predict()` | Pure C (C99) |
33
+ | Decision Tree, Random Forest, SVM, MLP... | C++11 (class + namespace) |
34
+ | Classification and Regression tasks | Arduino (`.h` with PROGMEM) |
35
+ | | MicroPython (`.py` module) |
36
+
37
+ ---
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ # From source (development)
43
+ pip install -e .
44
+
45
+ # With dev dependencies (pytest, mkdocs, etc.)
46
+ pip install -e ".[dev]"
47
+ ```
48
+
49
+ Requirements: Python 3.8+, NumPy >= 1.21, scikit-learn >= 1.0.
50
+
51
+ ---
52
+
53
+ ## Quick Start
54
+
55
+ ### Classification
56
+
57
+ ```python
58
+ from sklearn.ensemble import RandomForestClassifier
59
+ from sklearn.datasets import load_iris
60
+ from blackbox2c import convert
61
+
62
+ iris = load_iris()
63
+ model = RandomForestClassifier(n_estimators=50, random_state=42)
64
+ model.fit(iris.data, iris.target)
65
+
66
+ # Convert to C (default target)
67
+ c_code = convert(
68
+ model,
69
+ iris.data,
70
+ feature_names=list(iris.feature_names),
71
+ class_names=list(iris.target_names),
72
+ max_depth=5,
73
+ )
74
+ print(c_code)
75
+ ```
76
+
77
+ Generated output:
78
+
79
+ ```c
80
+ /*
81
+ * Auto-generated C code by BlackBox2C
82
+ * - Input features: 4
83
+ * - Output classes: 3
84
+ * - Precision: 8-bit
85
+ */
86
+ #include <stdint.h>
87
+
88
+ #define setosa 0
89
+ #define versicolor 1
90
+ #define virginica 2
91
+
92
+ uint8_t predict(float features[4]) {
93
+ if (features[2] <= 2.449999f) {
94
+ return 0;
95
+ } else {
96
+ if (features[3] <= 1.750000f) {
97
+ return 1;
98
+ } else {
99
+ return 2;
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### Export to Other Formats
106
+
107
+ ```python
108
+ # Arduino .h file
109
+ arduino_code = convert(model, iris.data, target='arduino')
110
+
111
+ # C++ class
112
+ cpp_code = convert(model, iris.data, target='cpp')
113
+
114
+ # MicroPython module
115
+ mp_code = convert(model, iris.data, target='micropython')
116
+ ```
117
+
118
+ ### Regression
119
+
120
+ ```python
121
+ from sklearn.ensemble import GradientBoostingRegressor
122
+ from sklearn.datasets import load_diabetes
123
+ from blackbox2c import convert
124
+
125
+ data = load_diabetes()
126
+ model = GradientBoostingRegressor(random_state=42)
127
+ model.fit(data.data, data.target)
128
+
129
+ c_code = convert(model, data.data, max_depth=5)
130
+ # Generates: float predict(float features[10]) { ... }
131
+ ```
132
+
133
+ ### Feature Analysis
134
+
135
+ ```python
136
+ from blackbox2c.analysis import FeatureSensitivityAnalyzer
137
+
138
+ analyzer = FeatureSensitivityAnalyzer(n_repeats=10, random_state=42)
139
+ results = analyzer.analyze(model, X_train, y_train, feature_names=feature_names)
140
+ print(results.summary())
141
+
142
+ # Get top 3 most important features by index
143
+ top3 = results.get_top_features(3)
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Configuration
149
+
150
+ ```python
151
+ from blackbox2c import Converter, ConversionConfig
152
+
153
+ config = ConversionConfig(
154
+ max_depth=5, # Surrogate tree depth (1-10, default 5)
155
+ optimize_rules='medium', # 'low' | 'medium' | 'high'
156
+ use_fixed_point=False, # Use integer arithmetic instead of float
157
+ precision=8, # Bit width for fixed-point: 8 | 16 | 32
158
+ function_name='predict', # Name of the generated function
159
+ n_samples=10000, # Synthetic samples for surrogate training
160
+ feature_threshold=None, # Auto-select N most important features
161
+ memory_budget_kb=None, # Auto-tune params to fit a KB budget
162
+ )
163
+
164
+ converter = Converter(config)
165
+ code = converter.convert(model, X_train, target='arduino')
166
+ metrics = converter.get_metrics()
167
+ # {'fidelity': 0.97, 'complexity': {...}, 'size_estimate': {...}}
168
+ ```
169
+
170
+ ---
171
+
172
+ ## CLI
173
+
174
+ ```bash
175
+ # Convert a pickled model to C
176
+ blackbox2c convert model.pkl X_train.npy -o output.c
177
+
178
+ # Export to Arduino
179
+ blackbox2c convert model.pkl X_train.npy -t arduino -o predict.h
180
+
181
+ # Analyze feature importance
182
+ blackbox2c analyze model.pkl X_train.npy --top-n 5
183
+
184
+ # Export a decision tree directly (no surrogate extraction)
185
+ blackbox2c export model.pkl -f cpp -o predictor.hpp
186
+
187
+ # Help
188
+ blackbox2c --help
189
+ blackbox2c convert --help
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Benchmarks
195
+
196
+ ```bash
197
+ python benchmarks/benchmark_classic_datasets.py --output results.md
198
+ ```
199
+
200
+ Covers Iris, Wine, Diabetes, and California Housing with Decision Trees, Random Forests, SVMs,
201
+ and Neural Networks. Metrics: fidelity, estimated FLASH size, tree depth, conversion time.
202
+
203
+ > **Note**: Code size figures are estimates from BlackBox2C's built-in size estimator,
204
+ > not measurements on real hardware.
205
+
206
+ ---
207
+
208
+ ## Project Structure
209
+
210
+ ```
211
+ blackbox2c/
212
+ ├── blackbox2c/
213
+ │ ├── __init__.py # Public API: convert(), Converter, ConversionConfig
214
+ │ ├── converter.py # Main orchestration pipeline
215
+ │ ├── config.py # ConversionConfig dataclass
216
+ │ ├── surrogate.py # Surrogate tree extraction
217
+ │ ├── codegen.py # C code generation
218
+ │ ├── optimizer.py # Rule pruning and merging
219
+ │ ├── exporters.py # C++, Arduino, MicroPython exporters
220
+ │ ├── analysis.py # Feature sensitivity analysis
221
+ │ └── cli.py # Command-line interface
222
+ ├── tests/ # 167 tests, >91% coverage
223
+ ├── benchmarks/ # Classic dataset benchmarks
224
+ ├── examples/ # End-to-end usage examples
225
+ └── docs/ # MkDocs documentation source
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Comparison with Alternatives
231
+
232
+ | Feature | BlackBox2C | emlearn | MicroMLGen | TFLite Micro |
233
+ |---|---|---|---|---|
234
+ | Any sklearn model | ✅ | ⚠️ Trees only | ⚠️ Trees only | ❌ TF only |
235
+ | Pure if-else output | ✅ | ✅ | ✅ | ❌ |
236
+ | C++ / Arduino / MicroPython | ✅ | ⚠️ Partial | ❌ | ⚠️ Partial |
237
+ | Feature selection built-in | ✅ | ❌ | ❌ | ❌ |
238
+ | Memory budget control | ✅ | ❌ | ❌ | ⚠️ |
239
+ | Zero runtime dependencies | ✅ | ✅ | ✅ | ❌ |
240
+
241
+ ---
242
+
243
+ ## Roadmap (v0.2)
244
+
245
+ - Quine-McCluskey and BDD rule optimization
246
+ - Hardware-validated benchmarks on real MCUs
247
+ - Quantization-aware training integration
248
+
249
+ ---
250
+
251
+ ## License
252
+
253
+ MIT — see [LICENSE](LICENSE).
254
+
255
+ ## Contributing
256
+
257
+ Issues and PRs welcome at [github.com/AxelSkrauba/BlackBox2C](https://github.com/AxelSkrauba/BlackBox2C).