fomtools 0.0.2__tar.gz → 0.0.3__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.
- {fomtools-0.0.2 → fomtools-0.0.3}/.github/workflows/docs.yml +9 -13
- {fomtools-0.0.2 → fomtools-0.0.3}/.gitignore +5 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/AGENTS.md +26 -0
- fomtools-0.0.3/CONTRIBUTING.md +34 -0
- fomtools-0.0.3/Makefile +13 -0
- {fomtools-0.0.2/fomtools.egg-info → fomtools-0.0.3}/PKG-INFO +50 -9
- {fomtools-0.0.2 → fomtools-0.0.3}/README.md +42 -7
- fomtools-0.0.3/docs/api/canonicalizer.md +38 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/docs/api/codegen.md +4 -0
- fomtools-0.0.3/docs/api/constraint.md +8 -0
- fomtools-0.0.3/docs/api/index.md +44 -0
- fomtools-0.0.3/docs/api/linearexpression.md +6 -0
- fomtools-0.0.3/docs/api/proxablefunctions.md +35 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/docs/api/solvers.md +4 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/docs/api/steps.md +4 -1
- fomtools-0.0.3/docs/api/verifier.md +7 -0
- fomtools-0.0.3/docs/assets/logo/favicon-16.png +0 -0
- fomtools-0.0.3/docs/assets/logo/favicon-32.png +0 -0
- fomtools-0.0.3/docs/assets/logo/favicon-48.png +0 -0
- fomtools-0.0.3/docs/assets/logo/favicon.svg +1 -0
- fomtools-0.0.3/docs/assets/logo/icon-512.png +0 -0
- fomtools-0.0.3/docs/assets/logo/icon-dark.svg +1 -0
- fomtools-0.0.3/docs/assets/logo/icon-mono.svg +1 -0
- fomtools-0.0.3/docs/assets/logo/icon-small.svg +1 -0
- fomtools-0.0.3/docs/assets/logo/icon.svg +1 -0
- fomtools-0.0.3/docs/assets/logo/logo-dark.svg +1 -0
- fomtools-0.0.3/docs/assets/logo/logo-mono.svg +1 -0
- fomtools-0.0.3/docs/assets/logo/logo.svg +1 -0
- fomtools-0.0.3/docs/get_started.md +140 -0
- fomtools-0.0.3/docs/index.md +149 -0
- fomtools-0.0.3/docs/quick_start.md +177 -0
- fomtools-0.0.3/docs/stylesheets/extra.css +85 -0
- {fomtools-0.0.2/docs/tutorials → fomtools-0.0.3/docs/tutorials/codegen}/_recorded_timings.json +2 -2
- fomtools-0.0.3/docs/tutorials/codegen/control.md +91 -0
- fomtools-0.0.3/docs/tutorials/codegen/control.py +294 -0
- fomtools-0.0.3/docs/tutorials/codegen/lasso.md +66 -0
- fomtools-0.0.3/docs/tutorials/codegen/lasso.py +231 -0
- fomtools-0.0.3/docs/tutorials/codegen/network.md +87 -0
- fomtools-0.0.3/docs/tutorials/codegen/network.py +305 -0
- fomtools-0.0.3/docs/tutorials/codegen/nnls.md +65 -0
- fomtools-0.0.3/docs/tutorials/codegen/nnls.py +206 -0
- fomtools-0.0.3/docs/tutorials/codegen/portfolio.md +80 -0
- fomtools-0.0.3/docs/tutorials/codegen/portfolio.py +259 -0
- fomtools-0.0.3/docs/tutorials/codegen.md +45 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/docs/tutorials/cvxpygen.md +26 -14
- fomtools-0.0.3/docs/tutorials/cvxpygen_mpc.py +188 -0
- fomtools-0.0.3/docs/tutorials/helper_functions/codegen_benchmarks.py +144 -0
- fomtools-0.0.3/docs/tutorials/helper_functions/control.py +190 -0
- fomtools-0.0.3/docs/tutorials/helper_functions/lasso.py +116 -0
- fomtools-0.0.3/docs/tutorials/helper_functions/network.py +164 -0
- fomtools-0.0.3/docs/tutorials/helper_functions/nnls.py +85 -0
- fomtools-0.0.3/docs/tutorials/helper_functions/pepit_runner.py +411 -0
- fomtools-0.0.3/docs/tutorials/helper_functions/portfolio.py +94 -0
- fomtools-0.0.3/docs/tutorials/index.md +21 -0
- fomtools-0.0.3/docs/tutorials/verification/control.py +606 -0
- fomtools-0.0.3/docs/tutorials/verification/lasso.py +477 -0
- fomtools-0.0.3/docs/tutorials/verification/network.py +656 -0
- fomtools-0.0.3/docs/tutorials/verification/nnls.py +591 -0
- fomtools-0.0.3/docs/tutorials/verification/portfolio.py +387 -0
- fomtools-0.0.3/docs/tutorials/verification.md +29 -0
- {fomtools-0.0.2/docs/tutorials → fomtools-0.0.3/docs/user_guide}/codegen.md +42 -15
- fomtools-0.0.3/docs/user_guide/index.md +246 -0
- fomtools-0.0.3/docs/user_guide/sdp.md +76 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/canonicalizers/canonicalizer.py +10 -9
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/canonicalizers/mip.py +18 -18
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/canonicalizers/obbt_handler.py +4 -4
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/canonicalizers/sdp.py +17 -17
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/canonicalizers/simulator.py +23 -22
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/__init__.py +12 -12
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/__init__.py +10 -10
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/budget.py +1 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/claude_sdk.py +4 -4
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/cli_driver.py +9 -9
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/cli_specs.py +7 -7
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/codex_sdk.py +5 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/driver.py +8 -8
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/pidev_sdk.py +6 -6
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/prompts.py +1 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/sdk_base.py +11 -11
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/stub.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/cli.py +1 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/config.py +29 -17
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/emit.py +2 -2
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/examples.py +7 -7
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/extract.py +5 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/extract_scheduled.py +10 -10
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/extract_unrolled.py +8 -8
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/factorize.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/generate.py +13 -13
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/ir.py +26 -26
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/kernel_rules.py +1 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/objective.py +6 -6
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/oracle.py +10 -10
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/postprocess.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/schedule.py +13 -13
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/spec.py +2 -2
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/targets/base.py +7 -7
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/targets/embedded_c.py +8 -8
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/targets/large_scale_cuda.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/constraint.py +13 -13
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/cvxpygen/__init__.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/cvxpygen/api.py +4 -4
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/cvxpygen/builders.py +21 -21
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/cvxpygen/glue.py +2 -2
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/cvxpygen/interface.py +5 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/cvxpygen/qpdata.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/cvxpygen/scaling.py +1 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/iteratetrajectory.py +5 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/linearexpression.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/__init__.py +28 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/elastic_net.py +44 -23
- fomtools-0.0.3/fomtools/proxable_functions/hinge_loss.py +111 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/huber_loss.py +38 -30
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/ind_affine.py +48 -34
- fomtools-0.0.3/fomtools/proxable_functions/ind_ball_l1.py +105 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/ind_ball_linf.py +44 -11
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/ind_box.py +47 -24
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/ind_half_space.py +37 -14
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/ind_nonnegative.py +34 -10
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/ind_nonpositive.py +33 -10
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/ind_point.py +40 -16
- fomtools-0.0.3/fomtools/proxable_functions/ind_polyhedral.py +119 -0
- fomtools-0.0.3/fomtools/proxable_functions/ind_simplex.py +92 -0
- fomtools-0.0.3/fomtools/proxable_functions/labeled_hinge_loss.py +124 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/least_squares.py +35 -21
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/linear.py +30 -17
- fomtools-0.0.3/fomtools/proxable_functions/norm_inf.py +120 -0
- fomtools-0.0.3/fomtools/proxable_functions/norm_l1.py +143 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/quadratic.py +46 -25
- fomtools-0.0.3/fomtools/proxable_functions/soft_nonnegative.py +120 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/sq_l2_norm.py +19 -13
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/sum_negative.py +33 -22
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/sum_positive.py +34 -18
- fomtools-0.0.3/fomtools/proxable_functions/total_variation_1d.py +157 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/sets/__init__.py +5 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/sets/affine_subspace.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/sets/ball.py +4 -4
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/sets/box.py +10 -10
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/sets/polyhedron.py +4 -4
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/sets/set.py +12 -12
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/gurobi.py +15 -15
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/highs.py +16 -16
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/stepdecomposers/sdp_step_decomposer.py +1 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/stepdecomposers/simulator_step_decomposer.py +19 -18
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/stepdecomposers/step_decomposer.py +46 -42
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/affine.py +7 -6
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/lin_prog.py +5 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/quad_prog.py +5 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/relu.py +6 -6
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/saturated_linear.py +6 -6
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/soft_threshold.py +3 -3
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/step.py +6 -6
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/matrix_utils.py +2 -2
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/verifier.py +79 -46
- {fomtools-0.0.2 → fomtools-0.0.3/fomtools.egg-info}/PKG-INFO +50 -9
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools.egg-info/SOURCES.txt +51 -12
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools.egg-info/requires.txt +10 -1
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools.egg-info/scm_file_list.json +52 -13
- fomtools-0.0.3/fomtools.egg-info/scm_version.json +8 -0
- fomtools-0.0.3/mkdocs.yml +112 -0
- fomtools-0.0.3/overrides/main.html +11 -0
- fomtools-0.0.3/overrides/partials/logo.html +3 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/pyproject.toml +12 -1
- fomtools-0.0.3/scripts/export_marimo.py +142 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/skills/README.md +2 -2
- fomtools-0.0.3/tests/test_export_marimo.py +206 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/uv.lock +35 -2
- fomtools-0.0.2/docs/api/canonicalizer.md +0 -8
- fomtools-0.0.2/docs/api/constraint.md +0 -5
- fomtools-0.0.2/docs/api/linearexpression.md +0 -1
- fomtools-0.0.2/docs/api/proxablefunctions.md +0 -45
- fomtools-0.0.2/docs/api/verifier.md +0 -2
- fomtools-0.0.2/docs/api.md +0 -11
- fomtools-0.0.2/docs/index.md +0 -101
- fomtools-0.0.2/docs/installation.md +0 -41
- fomtools-0.0.2/docs/tutorials/control.py +0 -343
- fomtools-0.0.2/docs/tutorials/cvxpygen_mpc.py +0 -147
- fomtools-0.0.2/docs/tutorials/lasso.py +0 -303
- fomtools-0.0.2/docs/tutorials/network.py +0 -377
- fomtools-0.0.2/docs/tutorials/nnls.py +0 -292
- fomtools-0.0.2/docs/tutorials/nnls_verification.py +0 -183
- fomtools-0.0.2/docs/tutorials/portfolio.py +0 -290
- fomtools-0.0.2/docs/tutorials.md +0 -18
- fomtools-0.0.2/fomtools/proxable_functions/hinge_loss.py +0 -72
- fomtools-0.0.2/fomtools/proxable_functions/ind_ball_l1.py +0 -67
- fomtools-0.0.2/fomtools/proxable_functions/ind_polyhedral.py +0 -86
- fomtools-0.0.2/fomtools/proxable_functions/ind_simplex.py +0 -56
- fomtools-0.0.2/fomtools/proxable_functions/labeled_hinge_loss.py +0 -74
- fomtools-0.0.2/fomtools/proxable_functions/norm_inf.py +0 -80
- fomtools-0.0.2/fomtools/proxable_functions/norm_l1.py +0 -109
- fomtools-0.0.2/fomtools/proxable_functions/soft_nonnegative.py +0 -85
- fomtools-0.0.2/fomtools/proxable_functions/total_variation_1d.py +0 -93
- fomtools-0.0.2/fomtools.egg-info/scm_version.json +0 -8
- fomtools-0.0.2/mkdocs.yml +0 -53
- fomtools-0.0.2/wrangler.toml +0 -5
- {fomtools-0.0.2 → fomtools-0.0.3}/.github/workflows/ci.yml +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/.github/workflows/claude-code-review.yml +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/.github/workflows/claude.yml +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/.github/workflows/release.yml +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/.github/workflows/update-skill.yml +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/.pre-commit-config.yaml +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/CLAUDE.md +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/LICENSE +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/docs/javascripts/mathjax.js +0 -0
- /fomtools-0.0.2/docs/tutorials/codegen_speedup_results.md → /fomtools-0.0.3/docs/tutorials/codegen/speedup_results.md +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/canonicalizers/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/agent/agents.yaml +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/dedup.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/harness.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/targets/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/targets/large_scale_openmp.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/codegen/wrapper.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/nn/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/nn/layers.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/proxable_functions/proximal_operator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/clarabel.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/cuclarabel.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/factory.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/mip_solver.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/sdp_solver.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/solvers/solver.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/stepdecomposers/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/stepdecomposers/mip_step_decomposer.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/steps/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/convex_hull_cuts.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/dict_utils.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/envelopes.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/math_utils.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/range_utils.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools/utils/sparse_utils.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools.egg-info/dependency_links.txt +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools.egg-info/entry_points.txt +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/fomtools.egg-info/top_level.txt +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/setup.cfg +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/skills/fomtools/SKILL.md +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/skills/fomtools/references/api.md +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/skills/fomtools/references/codegen.md +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/skills/fomtools/references/cvxpygen.md +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/skills/update-prompt.md +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/__init__.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/conftest.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/boxqp/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/cgqp/large_scale_cuda/fom_solver.cu +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/cgqp/large_scale_openmp/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/cvxpygen_qp/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/cvxpygen_qp_objective/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/dr/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/fista/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/fista_objective/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/halpern/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/indef_kkt/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/ista/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/ista/large_scale_cuda/fom_solver.cu +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/ista/large_scale_openmp/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/ista_objective/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/ista_objective/large_scale_cuda/fom_solver.cu +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/mpc/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/pdhg_lp/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/pdhg_lp/large_scale_cuda/fom_solver.cu +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/scheduled/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/scheduled_objective/embedded_c/fom_solver.c +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/golden/scheduled_objective/large_scale_cuda/fom_solver.cu +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_agent_budget.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_agent_integration.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_agent_notes.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cli.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_codegen_dispatch.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_bounds.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_builders.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_dispatch.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_e2e.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_glue.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_objective.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_preflight.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_qpdata.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_register.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_scaling.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_cvxpygen_scheduled.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_dedup.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_dr_pipeline.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_editable_linsolve.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_editable_ops.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_emit_scaffold.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_examples_scale.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_factorize.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_fista_pipeline.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_float32.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_indefinite_kkt.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_ir_extraction.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_large_scale.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_objective_termination.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_oracle.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_pdhg_pipeline.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_postprocess.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_profiling.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_satlin_mpc.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_scheduled_ir.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_scheduled_pipeline.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_spec_roundtrip.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_static_constraints.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_stationarity_gate.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_stub_pipeline.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_termination_interval.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_unrolled_emission.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_unrolled_ir.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/codegen/test_wrapper_roundtrip.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/conftest.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/cvxpy.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/examples/comparison_lasso.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/examples/cut_experiment.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_LP_pdhg.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_add_constraint.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_affine_simulator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_audit_regressions.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_boxpgd_sdp_mip.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_complementarity.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_convex_hull_cuts.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_copy_isolation.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_docs_examples.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_douglas_rachford.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_fixed_point_ista.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_fixed_point_nnls.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_ind_ball_l1.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_ind_polyhedral.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_ind_simplex.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_inf_norm_sdp.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_infinite_bounds.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_ista.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_ista_sdp_mip.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_iterate_trajectory.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_l1_obj_norm.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_linear_program.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_linearexpression.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_linsolve_simulator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_mincost_flow.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_mip_solution_consistency.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_nn_verify_jax.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_nn_verify_torch.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_nnls_sdp_mip.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_norm_inf.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_obbt_handler.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_objective_bounds.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_partial_relu.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_partial_relu_sdp_sim.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_placeholder.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_portfolio.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_prox_decomposer.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_quadratic_program.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_range_functions.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_relu_simulator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_satlin.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_satlin_simulator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sdp_canonicalizer.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sdp_cuts.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sdp_hull.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sdp_inequality.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sdp_nnls.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sdp_selector.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sets.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_simulator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_soft_threshold_simulator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_solve_kwargs.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_solver_boundary.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sparse_utils.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_stack.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_subproblem_simulator.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_sum_squares.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_total_variation_1d.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_two_norm_mip.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_vec_LUhat.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_verifier.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_verifier_ista.py +0 -0
- {fomtools-0.0.2 → fomtools-0.0.3}/tests/test_warm_start.py +0 -0
|
@@ -4,7 +4,7 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
branches: [ main ]
|
|
6
6
|
pull_request:
|
|
7
|
-
branches: [ main ]
|
|
7
|
+
branches: [ main, documentation ]
|
|
8
8
|
|
|
9
9
|
permissions:
|
|
10
10
|
contents: write
|
|
@@ -54,13 +54,10 @@ jobs:
|
|
|
54
54
|
- name: Export marimo notebooks
|
|
55
55
|
env:
|
|
56
56
|
GRB_LICENSE_FILE: ${{ github.workspace }}/gurobi.lic
|
|
57
|
-
run:
|
|
58
|
-
for file in docs/tutorials/*.py; do
|
|
59
|
-
marimo export html "$file" -o "${file%.py}.html"
|
|
60
|
-
done
|
|
57
|
+
run: python scripts/export_marimo.py --force
|
|
61
58
|
|
|
62
59
|
- name: Verify html generation
|
|
63
|
-
run: ls docs/tutorials
|
|
60
|
+
run: ls -R docs/tutorials
|
|
64
61
|
|
|
65
62
|
- name: Configure Git Credentials
|
|
66
63
|
run: |
|
|
@@ -79,11 +76,10 @@ jobs:
|
|
|
79
76
|
mkdocs-material-
|
|
80
77
|
|
|
81
78
|
- name: Build MkDocs site
|
|
82
|
-
run: mkdocs build
|
|
79
|
+
run: mkdocs build --strict
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
command: deploy
|
|
81
|
+
# Pull requests only build the site; pushes to main publish it to the gh-pages
|
|
82
|
+
# branch, which GitHub Pages serves at https://stellatogrp.github.io/fomtools/
|
|
83
|
+
- name: Deploy to GitHub Pages
|
|
84
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
85
|
+
run: mkdocs gh-deploy --force
|
|
@@ -82,3 +82,29 @@ execution of the CUDA checks; `FOMTOOLS_CODEGEN_BACKEND` selects the agent.
|
|
|
82
82
|
- When the public API or docs change, the `update-skill` workflow refreshes
|
|
83
83
|
`skills/fomtools/`; check its output rather than editing the skill by hand
|
|
84
84
|
in the same PR.
|
|
85
|
+
|
|
86
|
+
## Tutorial math notation
|
|
87
|
+
|
|
88
|
+
All `mo.md` cells in `docs/tutorials/` (verification and codegen notebooks) use one notation per concept, following Boyd-style conventions. Keep new notebooks in sync with this table.
|
|
89
|
+
|
|
90
|
+
| Concept | Write | Never |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| Reals, ones | `\mathbf{R}`, `\mathbf{R}^n_+`, `\mathbf{1}` | `{\bf R}`, `\R`, `\mathbb{R}` |
|
|
93
|
+
| Transpose | `A^T` | `A^\top` |
|
|
94
|
+
| Calligraphic | `\mathcal{X}` | `{\cal X}` |
|
|
95
|
+
| Problem keywords | `\text{minimize}`, `\text{maximize}`, `\text{subject to}` | `\textnormal{...}` |
|
|
96
|
+
| Delimiters | inline `$...$`, display `$$...$$`, problems and updates as bare `\begin{array}{ll}`/`{rcl}` | `\(...\)`, `\[...\]` |
|
|
97
|
+
| Soft-thresholding | `\mathbf{soft}_{\lambda\eta}` (`soft_threshold` step) | `{\cal T}_\lambda`, `S_\lambda` |
|
|
98
|
+
| Projection | `\Pi_C`: `\Pi_{\mathbf{R}^n_+}` (`relu` step), `\Pi_{[l,u]}` (`satlin` step / `IndBox`) | `\mathbf{ReLU}`, `\mathbf{prox}_{\mathbb{I}_C}` |
|
|
99
|
+
| Proximal operator | `\mathbf{prox}_f` | `\operatorname{prox}` |
|
|
100
|
+
|
|
101
|
+
Norms always carry a subscript: `\|v\|_2`, `\|v\|_\infty` (never `\lVert v \rVert` or a bare `\|v\|`).
|
|
102
|
+
Define soft-thresholding where it is first used: `\mathbf{soft}_\kappa(v)_i = \mathbf{sign}(v_i)\max\{|v_i| - \kappa, 0\}`, applied element-wise.
|
|
103
|
+
Matplotlib labels (`label=`, `xlabel`, `ylabel`, `title`) are rendered by mathtext, not KaTeX: write `\geq`/`\leq` there (mathtext rejects `\ge`/`\le`), and keep `\|v\|_2` norms.
|
|
104
|
+
|
|
105
|
+
Symbol roles: `x` problem parameter in `\mathcal{X}`; `z` decision variable and primal iterate, `z^0 \in \mathcal{Z}`, `z^\star` solution; `v, w` dual or auxiliary iterates; `y` (lasso) or `w` (NNLS) for the un-extrapolated proximal output of a momentum method, matching the helper code; `k` iteration, `K` horizon, `\eta` step size, `L` smoothness constant, `r^k` residual, `R` PEP initial radius.
|
|
106
|
+
Search-box bounds are `x_\mathrm{lb}, x_\mathrm{ub}` and `z^0_\mathrm{lb}, z^0_\mathrm{ub}`; problem-data bounds keep `_{\min}, _{\max}`. Code names such as `x_lb` or `s0_samples` appear only in backticks in prose. When a math letter differs from the code name, say so once.
|
|
107
|
+
|
|
108
|
+
Iterations are written `k \to k+1` for `k = 0, 1, \dots`. A momentum coefficient `\beta_k` uses the same index as the helper code (slot `k` uses `beta_k`, and `k` starts at 1), so the update reads `z^{k+1} = w^{k+1} + \beta_{k+1}(w^{k+1} - w^k)` with `\beta_1 = 0`. Use "Nesterov-type momentum" for `\beta_k = (k-1)/(k+2)` and reserve "FISTA" for the `t_k` schedule `\beta_k = (t_{k-1}-1)/t_k`.
|
|
109
|
+
|
|
110
|
+
Known clashes kept on purpose because both uses are standard: control input `u_t` vs. OSQP upper bound `u(x)`, LQR weight `R` vs. PEP radius `R`, and `\mu` as network cost, portfolio return, or strong-convexity constant.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Contributing to FOMTools
|
|
2
|
+
|
|
3
|
+
## Development setup
|
|
4
|
+
|
|
5
|
+
Follow the environment instructions in [docs/get_started.md](docs/get_started.md) to create a
|
|
6
|
+
virtual environment and install `fomtools` in editable mode with its `dev` and `docs` extras.
|
|
7
|
+
|
|
8
|
+
Install the pre-commit hooks once per clone:
|
|
9
|
+
|
|
10
|
+
pre-commit install
|
|
11
|
+
|
|
12
|
+
## Tests and linting
|
|
13
|
+
|
|
14
|
+
pytest # Run the test suite
|
|
15
|
+
ruff check # Check code style
|
|
16
|
+
ruff format # Auto-format
|
|
17
|
+
pre-commit run --all-files # Run all hooks
|
|
18
|
+
|
|
19
|
+
## Previewing the documentation
|
|
20
|
+
|
|
21
|
+
Install the documentation dependencies and start the local MkDocs server:
|
|
22
|
+
|
|
23
|
+
uv sync --extra docs
|
|
24
|
+
make docs-serve
|
|
25
|
+
|
|
26
|
+
The `docs-serve` target recursively discovers marimo notebooks under `docs/tutorials`, exports
|
|
27
|
+
missing or stale notebooks to ignored HTML files, and then starts MkDocs. Restart the server after
|
|
28
|
+
editing a notebook so that its HTML is refreshed.
|
|
29
|
+
|
|
30
|
+
Use these targets to export or validate the documentation without starting the server:
|
|
31
|
+
|
|
32
|
+
make docs-export # Export only missing or stale notebooks
|
|
33
|
+
make docs-export-force # Regenerate every notebook
|
|
34
|
+
make docs-build # Force export, then run a strict MkDocs build
|
fomtools-0.0.3/Makefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.PHONY: docs-export docs-export-force docs-serve docs-build
|
|
2
|
+
|
|
3
|
+
docs-export:
|
|
4
|
+
uv run --extra docs python scripts/export_marimo.py
|
|
5
|
+
|
|
6
|
+
docs-export-force:
|
|
7
|
+
uv run --extra docs python scripts/export_marimo.py --force
|
|
8
|
+
|
|
9
|
+
docs-serve: docs-export
|
|
10
|
+
uv run --extra docs mkdocs serve
|
|
11
|
+
|
|
12
|
+
docs-build: docs-export-force
|
|
13
|
+
uv run --extra docs mkdocs build --strict
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fomtools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: FOMTools: A Python Toolbox for Analysis of First-Order Methods
|
|
5
5
|
Author-email: Vinit Ranjan <vranjan1@mit.edu>, Daniel Deza <dd7022@princeton.edu>, Anushka Acharya <aa9078@princeton.edu>, Jisun Park <jisunpark@princeton.edu>, Bartolomeo Stellato <bstellato@princeton.edu>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -41,22 +41,40 @@ Provides-Extra: nn
|
|
|
41
41
|
Requires-Dist: torch; extra == "nn"
|
|
42
42
|
Requires-Dist: jax<0.11.2; extra == "nn"
|
|
43
43
|
Requires-Dist: flax; extra == "nn"
|
|
44
|
+
Provides-Extra: all
|
|
45
|
+
Requires-Dist: fomtools[codegen,cvxpygen,gurobi,nn]; extra == "all"
|
|
46
|
+
Requires-Dist: fomtools[gpu]; sys_platform != "darwin" and extra == "all"
|
|
47
|
+
Requires-Dist: fomtools[cuda]; extra == "all"
|
|
44
48
|
Provides-Extra: docs
|
|
45
49
|
Requires-Dist: fomtools[gurobi]; extra == "docs"
|
|
46
50
|
Requires-Dist: marimo; extra == "docs"
|
|
47
51
|
Requires-Dist: matplotlib; extra == "docs"
|
|
48
|
-
Requires-Dist: mkdocs; extra == "docs"
|
|
52
|
+
Requires-Dist: mkdocs<2,>=1.6; extra == "docs"
|
|
49
53
|
Requires-Dist: mkdocstrings-python; extra == "docs"
|
|
50
54
|
Requires-Dist: mkdocs-marimo; extra == "docs"
|
|
51
55
|
Requires-Dist: mkdocs-material; extra == "docs"
|
|
56
|
+
Requires-Dist: networkx; extra == "docs"
|
|
57
|
+
Requires-Dist: pepit; extra == "docs"
|
|
52
58
|
Requires-Dist: pymdown-extensions; extra == "docs"
|
|
53
59
|
Dynamic: license-file
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
<h1>
|
|
62
|
+
<picture>
|
|
63
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/stellatogrp/fomtools/main/docs/assets/logo/logo-dark.svg">
|
|
64
|
+
<img alt="FOMTools" src="https://raw.githubusercontent.com/stellatogrp/fomtools/main/docs/assets/logo/logo.svg" height="72">
|
|
65
|
+
</picture>
|
|
66
|
+
</h1>
|
|
67
|
+
|
|
68
|
+
[](https://pypi.org/project/fomtools/)
|
|
69
|
+
[](https://stellatogrp.github.io/fomtools/)
|
|
57
70
|
|
|
58
71
|
**Development, analysis, and code generation for first-order methods.**
|
|
59
72
|
|
|
73
|
+
[Documentation](https://stellatogrp.github.io/fomtools/) |
|
|
74
|
+
[PyPI](https://pypi.org/project/fomtools/) |
|
|
75
|
+
[Paper](https://arxiv.org/abs/2610.26743) |
|
|
76
|
+
[Benchmarks](https://github.com/stellatogrp/fomtools_experiments)
|
|
77
|
+
|
|
60
78
|
FOMTools is an open-source Python package for developing, analyzing, and deploying
|
|
61
79
|
first-order methods for parametric linear and convex quadratic optimization. You write the
|
|
62
80
|
iteration in Python, with syntax close to its mathematical description, and FOMTools records
|
|
@@ -114,7 +132,7 @@ for k in range(K):
|
|
|
114
132
|
|
|
115
133
|
Steps can also be written with proximal operators and projections, e.g.,
|
|
116
134
|
`VP.prox(NormL1(lambd), v, eta)` or `VP.project(Box(l, u), v)`. See the
|
|
117
|
-
[documentation](https://github.
|
|
135
|
+
[documentation](https://stellatogrp.github.io/fomtools/) for the full list of proxable functions and sets.
|
|
118
136
|
|
|
119
137
|
## Beyond worst-case verification
|
|
120
138
|
|
|
@@ -174,11 +192,26 @@ Optional extras:
|
|
|
174
192
|
| `codegen` | LLM coding-agent backends for code generation |
|
|
175
193
|
| `cvxpygen` | CVXPYgen integration |
|
|
176
194
|
| `nn` | Neural-network verification (PyTorch, JAX, Flax) |
|
|
195
|
+
| `all` | All of the above (GPU packages skipped on macOS) |
|
|
177
196
|
| `dev` | Development tools |
|
|
178
197
|
| `docs` | Documentation build dependencies |
|
|
179
198
|
|
|
180
199
|
For example, `pip install "fomtools[gurobi,codegen]"`, or
|
|
181
|
-
`pip install -e ".[gurobi,codegen]"` from source.
|
|
200
|
+
`pip install -e ".[gurobi,codegen]"` from source. Use `pip install "fomtools[all]"`
|
|
201
|
+
to install every optional feature.
|
|
202
|
+
|
|
203
|
+
### Agent skill
|
|
204
|
+
|
|
205
|
+
FOMTools ships an [Agent Skill](https://agentskills.io/) in
|
|
206
|
+
[`skills/fomtools`](skills/fomtools/SKILL.md) that teaches coding agents (Claude
|
|
207
|
+
Code, Codex, Cursor, and others) the FOMTools API. Install it with the
|
|
208
|
+
[`skills` CLI](https://github.com/vercel-labs/skills) (requires Node.js):
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
npx skills add stellatogrp/fomtools -g
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
See [Get started](https://stellatogrp.github.io/fomtools/get_started/) for details.
|
|
182
215
|
|
|
183
216
|
FOMTools is not a solver. It relies on mathematical programming solvers such as
|
|
184
217
|
[HiGHS](https://highs.dev) (the default) and [Gurobi](https://www.gurobi.com) to solve
|
|
@@ -186,9 +219,14 @@ the verification problems it builds.
|
|
|
186
219
|
|
|
187
220
|
## Examples
|
|
188
221
|
|
|
189
|
-
The [tutorials](https://github.
|
|
190
|
-
network optimization, optimal control, and portfolio rebalancing.
|
|
191
|
-
|
|
222
|
+
The [tutorials](https://stellatogrp.github.io/fomtools/tutorials/) cover sparse coding (Lasso), nonnegative least squares,
|
|
223
|
+
network optimization, optimal control, and portfolio rebalancing.
|
|
224
|
+
|
|
225
|
+
## Benchmarks
|
|
226
|
+
|
|
227
|
+
The benchmarks and the code to reproduce the experiments in our
|
|
228
|
+
[paper](https://arxiv.org/abs/2610.26743) (verification, simulation, and code generation on
|
|
229
|
+
CPU and GPU) are in a separate repository,
|
|
192
230
|
[stellatogrp/fomtools_experiments](https://github.com/stellatogrp/fomtools_experiments).
|
|
193
231
|
|
|
194
232
|
## Contributing
|
|
@@ -215,3 +253,6 @@ If you use FOMTools for published work, we encourage you to cite our
|
|
|
215
253
|
year = {2026},
|
|
216
254
|
}
|
|
217
255
|
```
|
|
256
|
+
|
|
257
|
+
The mixed-integer verification method is described in
|
|
258
|
+
[Exact Verification of First-Order Methods via Mixed-Integer Linear Programming](https://arxiv.org/abs/2412.11330).
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<h1>
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/stellatogrp/fomtools/main/docs/assets/logo/logo-dark.svg">
|
|
4
|
+
<img alt="FOMTools" src="https://raw.githubusercontent.com/stellatogrp/fomtools/main/docs/assets/logo/logo.svg" height="72">
|
|
5
|
+
</picture>
|
|
6
|
+
</h1>
|
|
7
|
+
|
|
8
|
+
[](https://pypi.org/project/fomtools/)
|
|
9
|
+
[](https://stellatogrp.github.io/fomtools/)
|
|
3
10
|
|
|
4
11
|
**Development, analysis, and code generation for first-order methods.**
|
|
5
12
|
|
|
13
|
+
[Documentation](https://stellatogrp.github.io/fomtools/) |
|
|
14
|
+
[PyPI](https://pypi.org/project/fomtools/) |
|
|
15
|
+
[Paper](https://arxiv.org/abs/2610.26743) |
|
|
16
|
+
[Benchmarks](https://github.com/stellatogrp/fomtools_experiments)
|
|
17
|
+
|
|
6
18
|
FOMTools is an open-source Python package for developing, analyzing, and deploying
|
|
7
19
|
first-order methods for parametric linear and convex quadratic optimization. You write the
|
|
8
20
|
iteration in Python, with syntax close to its mathematical description, and FOMTools records
|
|
@@ -60,7 +72,7 @@ for k in range(K):
|
|
|
60
72
|
|
|
61
73
|
Steps can also be written with proximal operators and projections, e.g.,
|
|
62
74
|
`VP.prox(NormL1(lambd), v, eta)` or `VP.project(Box(l, u), v)`. See the
|
|
63
|
-
[documentation](https://github.
|
|
75
|
+
[documentation](https://stellatogrp.github.io/fomtools/) for the full list of proxable functions and sets.
|
|
64
76
|
|
|
65
77
|
## Beyond worst-case verification
|
|
66
78
|
|
|
@@ -120,11 +132,26 @@ Optional extras:
|
|
|
120
132
|
| `codegen` | LLM coding-agent backends for code generation |
|
|
121
133
|
| `cvxpygen` | CVXPYgen integration |
|
|
122
134
|
| `nn` | Neural-network verification (PyTorch, JAX, Flax) |
|
|
135
|
+
| `all` | All of the above (GPU packages skipped on macOS) |
|
|
123
136
|
| `dev` | Development tools |
|
|
124
137
|
| `docs` | Documentation build dependencies |
|
|
125
138
|
|
|
126
139
|
For example, `pip install "fomtools[gurobi,codegen]"`, or
|
|
127
|
-
`pip install -e ".[gurobi,codegen]"` from source.
|
|
140
|
+
`pip install -e ".[gurobi,codegen]"` from source. Use `pip install "fomtools[all]"`
|
|
141
|
+
to install every optional feature.
|
|
142
|
+
|
|
143
|
+
### Agent skill
|
|
144
|
+
|
|
145
|
+
FOMTools ships an [Agent Skill](https://agentskills.io/) in
|
|
146
|
+
[`skills/fomtools`](skills/fomtools/SKILL.md) that teaches coding agents (Claude
|
|
147
|
+
Code, Codex, Cursor, and others) the FOMTools API. Install it with the
|
|
148
|
+
[`skills` CLI](https://github.com/vercel-labs/skills) (requires Node.js):
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx skills add stellatogrp/fomtools -g
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
See [Get started](https://stellatogrp.github.io/fomtools/get_started/) for details.
|
|
128
155
|
|
|
129
156
|
FOMTools is not a solver. It relies on mathematical programming solvers such as
|
|
130
157
|
[HiGHS](https://highs.dev) (the default) and [Gurobi](https://www.gurobi.com) to solve
|
|
@@ -132,9 +159,14 @@ the verification problems it builds.
|
|
|
132
159
|
|
|
133
160
|
## Examples
|
|
134
161
|
|
|
135
|
-
The [tutorials](https://github.
|
|
136
|
-
network optimization, optimal control, and portfolio rebalancing.
|
|
137
|
-
|
|
162
|
+
The [tutorials](https://stellatogrp.github.io/fomtools/tutorials/) cover sparse coding (Lasso), nonnegative least squares,
|
|
163
|
+
network optimization, optimal control, and portfolio rebalancing.
|
|
164
|
+
|
|
165
|
+
## Benchmarks
|
|
166
|
+
|
|
167
|
+
The benchmarks and the code to reproduce the experiments in our
|
|
168
|
+
[paper](https://arxiv.org/abs/2610.26743) (verification, simulation, and code generation on
|
|
169
|
+
CPU and GPU) are in a separate repository,
|
|
138
170
|
[stellatogrp/fomtools_experiments](https://github.com/stellatogrp/fomtools_experiments).
|
|
139
171
|
|
|
140
172
|
## Contributing
|
|
@@ -161,3 +193,6 @@ If you use FOMTools for published work, we encourage you to cite our
|
|
|
161
193
|
year = {2026},
|
|
162
194
|
}
|
|
163
195
|
```
|
|
196
|
+
|
|
197
|
+
The mixed-integer verification method is described in
|
|
198
|
+
[Exact Verification of First-Order Methods via Mixed-Integer Linear Programming](https://arxiv.org/abs/2412.11330).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Canonicalizers
|
|
2
|
+
|
|
3
|
+
Canonicalizers translate a verification problem into a solver-ready formulation
|
|
4
|
+
(MIP or SDP), including optimization-based bound tightening (OBBT).
|
|
5
|
+
|
|
6
|
+
::: fomtools.canonicalizers.Canonicalizer
|
|
7
|
+
|
|
8
|
+
## MIP canonicalizer
|
|
9
|
+
|
|
10
|
+
::: fomtools.canonicalizers.mip
|
|
11
|
+
options:
|
|
12
|
+
show_root_heading: false
|
|
13
|
+
show_root_toc_entry: false
|
|
14
|
+
heading_level: 3
|
|
15
|
+
|
|
16
|
+
## OBBT handler
|
|
17
|
+
|
|
18
|
+
::: fomtools.canonicalizers.obbt_handler
|
|
19
|
+
options:
|
|
20
|
+
show_root_heading: false
|
|
21
|
+
show_root_toc_entry: false
|
|
22
|
+
heading_level: 3
|
|
23
|
+
|
|
24
|
+
## Simulator
|
|
25
|
+
|
|
26
|
+
::: fomtools.canonicalizers.simulator
|
|
27
|
+
options:
|
|
28
|
+
show_root_heading: false
|
|
29
|
+
show_root_toc_entry: false
|
|
30
|
+
heading_level: 3
|
|
31
|
+
|
|
32
|
+
## SDP canonicalizer
|
|
33
|
+
|
|
34
|
+
::: fomtools.canonicalizers.sdp
|
|
35
|
+
options:
|
|
36
|
+
show_root_heading: false
|
|
37
|
+
show_root_toc_entry: false
|
|
38
|
+
heading_level: 3
|
|
@@ -5,6 +5,10 @@ methods, plus a tiny Python wrapper. An LLM coding agent translates each step of
|
|
|
5
5
|
the algorithm into the target language and iterates against a Python reference
|
|
6
6
|
oracle until the generated code is numerically verified.
|
|
7
7
|
|
|
8
|
+
The [code generation guide](../user_guide/codegen.md) is the narrative reference for
|
|
9
|
+
the symbols below, and the [tutorials](../tutorials/codegen.md) work through five
|
|
10
|
+
complete examples.
|
|
11
|
+
|
|
8
12
|
::: fomtools.codegen.generate_code
|
|
9
13
|
|
|
10
14
|
::: fomtools.codegen.CodegenConfig
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Constraints
|
|
2
|
+
|
|
3
|
+
Constraints are equalities and inequalities over linear expressions, used to
|
|
4
|
+
encode assumptions on the problem data and the initial conditions.
|
|
5
|
+
|
|
6
|
+
::: fomtools.constraint.Constraint
|
|
7
|
+
::: fomtools.constraint.EqualityConstraint
|
|
8
|
+
::: fomtools.constraint.InequalityConstraint
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# API and modules
|
|
2
|
+
|
|
3
|
+
The FOMTools API is organized around a single entry point, the
|
|
4
|
+
[`Verifier`](verifier.md), and a set of modules that describe the algorithm
|
|
5
|
+
to be verified, the operators it applies, and the numerical backend used
|
|
6
|
+
to analyze it.
|
|
7
|
+
|
|
8
|
+
A typical workflow is: declare the problem data and iterates on a `Verifier`,
|
|
9
|
+
build up the algorithm from [step operators](steps.md) and
|
|
10
|
+
[proxable functions](proxablefunctions.md), state the assumptions and the
|
|
11
|
+
quantity of interest as [linear expressions](linearexpression.md) and
|
|
12
|
+
[constraints](constraint.md), and then let a
|
|
13
|
+
[canonicalizer](canonicalizer.md) translate everything into a mixed-integer
|
|
14
|
+
program, a semidefinite relaxation, or a sampled simulation; the MIP and SDP
|
|
15
|
+
forms are solved by a [solver](solvers.md) to obtain a worst-case bound.
|
|
16
|
+
|
|
17
|
+
The source code of every module is in the
|
|
18
|
+
[`fomtools` package on GitHub](https://github.com/stellatogrp/fomtools/tree/main/fomtools).
|
|
19
|
+
|
|
20
|
+
## Modules
|
|
21
|
+
|
|
22
|
+
* **[Verifier](verifier.md)** holds the
|
|
23
|
+
optimization variables and their bounds, applies step operations, propagates
|
|
24
|
+
interval bounds, and drives the canonicalizers and OBBT handlers.
|
|
25
|
+
* **[Linear expressions](linearexpression.md)** are affine expressions
|
|
26
|
+
$Ay + b$ of the leaf variables (parameters, initial iterates, and step
|
|
27
|
+
outputs), with arithmetic and `@` support, used for iterates, objectives, and
|
|
28
|
+
performance measures.
|
|
29
|
+
* **[Constraints](constraint.md)** are equalities and inequalities over
|
|
30
|
+
linear expressions, used to encode assumptions on the problem data and the
|
|
31
|
+
initial conditions.
|
|
32
|
+
* **[Step operators](steps.md)** are the building blocks of a first-order
|
|
33
|
+
method, covering affine steps, ReLU, saturated linear, and soft thresholding.
|
|
34
|
+
* **[Canonicalizers](canonicalizer.md)** translate a verification problem
|
|
35
|
+
into a MIP, an SDP relaxation (experimental), or a sampled simulation,
|
|
36
|
+
including optimization-based bound tightening (OBBT).
|
|
37
|
+
* **[Solvers](solvers.md)** are thin wrappers that put the numerical
|
|
38
|
+
backends, such as Gurobi and HiGHS, behind a common interface.
|
|
39
|
+
* **[Proxable functions](proxablefunctions.md)** are convex functions whose
|
|
40
|
+
proximal operators can be used as steps through `vp.prox`, each supplying a
|
|
41
|
+
numerical prox and the encoding needed by the verification problem. Sets for
|
|
42
|
+
`vp.project` are on the same page.
|
|
43
|
+
* **[Code generation](codegen.md)** emits low-level solver code for a
|
|
44
|
+
verified first-order method, together with a small Python wrapper.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Proxable functions
|
|
2
|
+
|
|
3
|
+
Proxable functions are convex functions whose proximal operators can be used as
|
|
4
|
+
steps, each supplying a numerical prox and the encoding needed by the
|
|
5
|
+
verification problem. Use `vp.prox(function, arg, gamma=1.0)`; support varies by
|
|
6
|
+
backend, and unsupported operations raise explicitly. They all derive from the
|
|
7
|
+
abstract base class below.
|
|
8
|
+
|
|
9
|
+
::: fomtools.proxable_functions.ProxableFunction
|
|
10
|
+
options:
|
|
11
|
+
show_root_heading: true
|
|
12
|
+
show_root_toc_entry: true
|
|
13
|
+
|
|
14
|
+
::: fomtools.proxable_functions
|
|
15
|
+
options:
|
|
16
|
+
show_root_heading: false
|
|
17
|
+
show_root_toc_entry: false
|
|
18
|
+
filters:
|
|
19
|
+
- "!^ProxableFunction$"
|
|
20
|
+
|
|
21
|
+
## Sets and projections
|
|
22
|
+
|
|
23
|
+
Use `vp.project(set_instance, arg)`.
|
|
24
|
+
|
|
25
|
+
::: fomtools.sets.Set
|
|
26
|
+
::: fomtools.sets.Polyhedron
|
|
27
|
+
::: fomtools.sets.HalfSpace
|
|
28
|
+
::: fomtools.sets.Simplex
|
|
29
|
+
::: fomtools.sets.Box
|
|
30
|
+
::: fomtools.sets.NonNegative
|
|
31
|
+
::: fomtools.sets.NonPositive
|
|
32
|
+
::: fomtools.sets.Point
|
|
33
|
+
::: fomtools.sets.L1Ball
|
|
34
|
+
::: fomtools.sets.LinfBall
|
|
35
|
+
::: fomtools.sets.AffineSubspace
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><style>.a{stroke:#2D3748}.b{stroke:#E77500}.c{fill:#E77500}@media (prefers-color-scheme:dark){.a{stroke:#E5E7EB}.b{stroke:#00A6F4}.c{fill:#00A6F4}}</style><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" class="a" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.5 21.5 L20 32 L28.5 42.5 M35.5 21.5 L44 32 L35.5 42.5" fill="none" class="b" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="32" r="5" class="c"/></svg>
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" stroke="#E5E7EB" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.5 21.5 L20 32 L28.5 42.5 M35.5 21.5 L44 32 L35.5 42.5" fill="none" stroke="#00A6F4" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="32" r="5" fill="#00A6F4"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" stroke="#131313" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.5 21.5 L20 32 L28.5 42.5 M35.5 21.5 L44 32 L35.5 42.5" fill="none" stroke="#131313" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="32" r="5" fill="#131313"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" stroke="#2D3748" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/><path d="M30 21 L20 32 L30 43 M34 21 L44 32 L34 43" fill="none" stroke="#E77500" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" stroke="#2D3748" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.5 21.5 L20 32 L28.5 42.5 M35.5 21.5 L44 32 L35.5 42.5" fill="none" stroke="#E77500" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="32" r="5" fill="#E77500"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 253.93 64" width="253.93" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" stroke="#E5E7EB" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.5 21.5 L20 32 L28.5 42.5 M35.5 21.5 L44 32 L35.5 42.5" fill="none" stroke="#00A6F4" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="32" r="5" fill="#00A6F4"/><path d="M82.33 46V18H101.16V22.3H87.29V29.95H100.16V34.16H87.29V46ZM116.17 46.45Q112.42 46.45 109.48 44.66Q106.53 42.86 104.83 39.62Q103.13 36.38 103.13 32.02Q103.13 27.64 104.83 24.39Q106.53 21.14 109.48 19.34Q112.42 17.55 116.17 17.55Q119.91 17.55 122.86 19.34Q125.81 21.14 127.52 24.39Q129.22 27.64 129.22 32.02Q129.22 36.38 127.52 39.63Q125.81 42.88 122.86 44.67Q119.91 46.45 116.17 46.45ZM116.17 42Q118.47 42 120.28 40.83Q122.09 39.67 123.15 37.44Q124.2 35.21 124.2 32.02Q124.2 28.81 123.15 26.57Q122.09 24.33 120.28 23.17Q118.47 22 116.17 22Q113.88 22 112.07 23.17Q110.26 24.33 109.19 26.57Q108.13 28.81 108.13 32.02Q108.13 35.21 109.19 37.44Q110.26 39.67 112.07 40.83Q113.88 42 116.17 42ZM132.9 46V18H140.04L145.49 32.71Q145.88 33.88 146.49 35.75Q147.09 37.62 147.58 39.25Q148.06 37.62 148.66 35.75Q149.25 33.88 149.64 32.71L155 18H162.18V46H157.29V31.72Q157.29 30.23 157.35 28.07Q157.4 25.91 157.46 23.77Q156.71 26.14 156.03 28.29Q155.36 30.44 154.9 31.72L149.57 46H145.51L140.13 31.72Q139.7 30.5 139.03 28.46Q138.37 26.42 137.63 24.16Q137.69 26.23 137.74 28.27Q137.79 30.31 137.79 31.72V46Z" fill="#E5E7EB"/><path d="M165.45 21.01V18H187.06V21.01H177.96V46H174.58V21.01ZM194.05 46.45Q191.3 46.45 189.23 45.13Q187.15 43.8 186 41.47Q184.84 39.14 184.84 36.12Q184.84 33.07 186 30.72Q187.15 28.37 189.23 27.04Q191.3 25.7 194.05 25.7Q196.81 25.7 198.88 27.04Q200.94 28.37 202.1 30.72Q203.26 33.07 203.26 36.12Q203.26 39.14 202.1 41.47Q200.94 43.8 198.88 45.13Q196.81 46.45 194.05 46.45ZM194.05 43.56Q196.87 43.56 198.45 41.52Q200.02 39.48 200.02 36.12Q200.02 32.71 198.44 30.66Q196.85 28.6 194.05 28.6Q191.25 28.6 189.66 30.65Q188.07 32.7 188.07 36.12Q188.07 39.5 189.65 41.53Q191.23 43.56 194.05 43.56ZM215.17 46.45Q212.43 46.45 210.35 45.13Q208.27 43.8 207.12 41.47Q205.96 39.14 205.96 36.12Q205.96 33.07 207.12 30.72Q208.27 28.37 210.35 27.04Q212.43 25.7 215.17 25.7Q217.93 25.7 220 27.04Q222.07 28.37 223.22 30.72Q224.38 33.07 224.38 36.12Q224.38 39.14 223.22 41.47Q222.07 43.8 220 45.13Q217.93 46.45 215.17 46.45ZM215.17 43.56Q217.99 43.56 219.57 41.52Q221.15 39.48 221.15 36.12Q221.15 32.71 219.56 30.66Q217.97 28.6 215.17 28.6Q212.37 28.6 210.78 30.65Q209.19 32.7 209.19 36.12Q209.19 39.5 210.77 41.53Q212.35 43.56 215.17 43.56ZM231.29 18V46H228.1V18ZM242.94 46.45Q240.82 46.45 239.09 45.76Q237.36 45.06 236.29 43.64Q235.22 42.22 235.09 40.06H238.25Q238.59 43.71 242.87 43.71Q244.94 43.71 246.13 42.84Q247.32 41.98 247.32 40.66Q247.32 39.54 246.5 38.86Q245.67 38.18 244.34 37.88L241.14 37.13Q235.54 35.81 235.54 31.49Q235.54 29.8 236.45 28.5Q237.36 27.19 238.99 26.45Q240.61 25.7 242.74 25.7Q244.81 25.7 246.45 26.48Q248.09 27.26 249.06 28.69Q250.03 30.12 250.09 32.09H246.97Q246.95 30.52 245.8 29.48Q244.66 28.45 242.74 28.45Q240.92 28.45 239.83 29.33Q238.74 30.21 238.74 31.49Q238.74 32.62 239.56 33.31Q240.39 33.99 241.82 34.33L245.01 35.08Q247.87 35.76 249.2 37.1Q250.54 38.45 250.54 40.59Q250.54 42.43 249.54 43.74Q248.54 45.06 246.83 45.76Q245.11 46.45 242.94 46.45Z" fill="#E5E7EB"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 253.93 64" width="253.93" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" stroke="#131313" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.5 21.5 L20 32 L28.5 42.5 M35.5 21.5 L44 32 L35.5 42.5" fill="none" stroke="#131313" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="32" r="5" fill="#131313"/><path d="M82.33 46V18H101.16V22.3H87.29V29.95H100.16V34.16H87.29V46ZM116.17 46.45Q112.42 46.45 109.48 44.66Q106.53 42.86 104.83 39.62Q103.13 36.38 103.13 32.02Q103.13 27.64 104.83 24.39Q106.53 21.14 109.48 19.34Q112.42 17.55 116.17 17.55Q119.91 17.55 122.86 19.34Q125.81 21.14 127.52 24.39Q129.22 27.64 129.22 32.02Q129.22 36.38 127.52 39.63Q125.81 42.88 122.86 44.67Q119.91 46.45 116.17 46.45ZM116.17 42Q118.47 42 120.28 40.83Q122.09 39.67 123.15 37.44Q124.2 35.21 124.2 32.02Q124.2 28.81 123.15 26.57Q122.09 24.33 120.28 23.17Q118.47 22 116.17 22Q113.88 22 112.07 23.17Q110.26 24.33 109.19 26.57Q108.13 28.81 108.13 32.02Q108.13 35.21 109.19 37.44Q110.26 39.67 112.07 40.83Q113.88 42 116.17 42ZM132.9 46V18H140.04L145.49 32.71Q145.88 33.88 146.49 35.75Q147.09 37.62 147.58 39.25Q148.06 37.62 148.66 35.75Q149.25 33.88 149.64 32.71L155 18H162.18V46H157.29V31.72Q157.29 30.23 157.35 28.07Q157.4 25.91 157.46 23.77Q156.71 26.14 156.03 28.29Q155.36 30.44 154.9 31.72L149.57 46H145.51L140.13 31.72Q139.7 30.5 139.03 28.46Q138.37 26.42 137.63 24.16Q137.69 26.23 137.74 28.27Q137.79 30.31 137.79 31.72V46Z" fill="#131313"/><path d="M165.45 21.01V18H187.06V21.01H177.96V46H174.58V21.01ZM194.05 46.45Q191.3 46.45 189.23 45.13Q187.15 43.8 186 41.47Q184.84 39.14 184.84 36.12Q184.84 33.07 186 30.72Q187.15 28.37 189.23 27.04Q191.3 25.7 194.05 25.7Q196.81 25.7 198.88 27.04Q200.94 28.37 202.1 30.72Q203.26 33.07 203.26 36.12Q203.26 39.14 202.1 41.47Q200.94 43.8 198.88 45.13Q196.81 46.45 194.05 46.45ZM194.05 43.56Q196.87 43.56 198.45 41.52Q200.02 39.48 200.02 36.12Q200.02 32.71 198.44 30.66Q196.85 28.6 194.05 28.6Q191.25 28.6 189.66 30.65Q188.07 32.7 188.07 36.12Q188.07 39.5 189.65 41.53Q191.23 43.56 194.05 43.56ZM215.17 46.45Q212.43 46.45 210.35 45.13Q208.27 43.8 207.12 41.47Q205.96 39.14 205.96 36.12Q205.96 33.07 207.12 30.72Q208.27 28.37 210.35 27.04Q212.43 25.7 215.17 25.7Q217.93 25.7 220 27.04Q222.07 28.37 223.22 30.72Q224.38 33.07 224.38 36.12Q224.38 39.14 223.22 41.47Q222.07 43.8 220 45.13Q217.93 46.45 215.17 46.45ZM215.17 43.56Q217.99 43.56 219.57 41.52Q221.15 39.48 221.15 36.12Q221.15 32.71 219.56 30.66Q217.97 28.6 215.17 28.6Q212.37 28.6 210.78 30.65Q209.19 32.7 209.19 36.12Q209.19 39.5 210.77 41.53Q212.35 43.56 215.17 43.56ZM231.29 18V46H228.1V18ZM242.94 46.45Q240.82 46.45 239.09 45.76Q237.36 45.06 236.29 43.64Q235.22 42.22 235.09 40.06H238.25Q238.59 43.71 242.87 43.71Q244.94 43.71 246.13 42.84Q247.32 41.98 247.32 40.66Q247.32 39.54 246.5 38.86Q245.67 38.18 244.34 37.88L241.14 37.13Q235.54 35.81 235.54 31.49Q235.54 29.8 236.45 28.5Q237.36 27.19 238.99 26.45Q240.61 25.7 242.74 25.7Q244.81 25.7 246.45 26.48Q248.09 27.26 249.06 28.69Q250.03 30.12 250.09 32.09H246.97Q246.95 30.52 245.8 29.48Q244.66 28.45 242.74 28.45Q240.92 28.45 239.83 29.33Q238.74 30.21 238.74 31.49Q238.74 32.62 239.56 33.31Q240.39 33.99 241.82 34.33L245.01 35.08Q247.87 35.76 249.2 37.1Q250.54 38.45 250.54 40.59Q250.54 42.43 249.54 43.74Q248.54 45.06 246.83 45.76Q245.11 46.45 242.94 46.45Z" fill="#131313"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 253.93 64" width="253.93" height="64" role="img" aria-label="FOMTools"><title>FOMTools</title><path d="M21.5 12 L6 32 L21.5 52 M42.5 12 L58 32 L42.5 52" fill="none" stroke="#2D3748" stroke-width="7.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M28.5 21.5 L20 32 L28.5 42.5 M35.5 21.5 L44 32 L35.5 42.5" fill="none" stroke="#E77500" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="32" r="5" fill="#E77500"/><path d="M82.33 46V18H101.16V22.3H87.29V29.95H100.16V34.16H87.29V46ZM116.17 46.45Q112.42 46.45 109.48 44.66Q106.53 42.86 104.83 39.62Q103.13 36.38 103.13 32.02Q103.13 27.64 104.83 24.39Q106.53 21.14 109.48 19.34Q112.42 17.55 116.17 17.55Q119.91 17.55 122.86 19.34Q125.81 21.14 127.52 24.39Q129.22 27.64 129.22 32.02Q129.22 36.38 127.52 39.63Q125.81 42.88 122.86 44.67Q119.91 46.45 116.17 46.45ZM116.17 42Q118.47 42 120.28 40.83Q122.09 39.67 123.15 37.44Q124.2 35.21 124.2 32.02Q124.2 28.81 123.15 26.57Q122.09 24.33 120.28 23.17Q118.47 22 116.17 22Q113.88 22 112.07 23.17Q110.26 24.33 109.19 26.57Q108.13 28.81 108.13 32.02Q108.13 35.21 109.19 37.44Q110.26 39.67 112.07 40.83Q113.88 42 116.17 42ZM132.9 46V18H140.04L145.49 32.71Q145.88 33.88 146.49 35.75Q147.09 37.62 147.58 39.25Q148.06 37.62 148.66 35.75Q149.25 33.88 149.64 32.71L155 18H162.18V46H157.29V31.72Q157.29 30.23 157.35 28.07Q157.4 25.91 157.46 23.77Q156.71 26.14 156.03 28.29Q155.36 30.44 154.9 31.72L149.57 46H145.51L140.13 31.72Q139.7 30.5 139.03 28.46Q138.37 26.42 137.63 24.16Q137.69 26.23 137.74 28.27Q137.79 30.31 137.79 31.72V46Z" fill="#2D3748"/><path d="M165.45 21.01V18H187.06V21.01H177.96V46H174.58V21.01ZM194.05 46.45Q191.3 46.45 189.23 45.13Q187.15 43.8 186 41.47Q184.84 39.14 184.84 36.12Q184.84 33.07 186 30.72Q187.15 28.37 189.23 27.04Q191.3 25.7 194.05 25.7Q196.81 25.7 198.88 27.04Q200.94 28.37 202.1 30.72Q203.26 33.07 203.26 36.12Q203.26 39.14 202.1 41.47Q200.94 43.8 198.88 45.13Q196.81 46.45 194.05 46.45ZM194.05 43.56Q196.87 43.56 198.45 41.52Q200.02 39.48 200.02 36.12Q200.02 32.71 198.44 30.66Q196.85 28.6 194.05 28.6Q191.25 28.6 189.66 30.65Q188.07 32.7 188.07 36.12Q188.07 39.5 189.65 41.53Q191.23 43.56 194.05 43.56ZM215.17 46.45Q212.43 46.45 210.35 45.13Q208.27 43.8 207.12 41.47Q205.96 39.14 205.96 36.12Q205.96 33.07 207.12 30.72Q208.27 28.37 210.35 27.04Q212.43 25.7 215.17 25.7Q217.93 25.7 220 27.04Q222.07 28.37 223.22 30.72Q224.38 33.07 224.38 36.12Q224.38 39.14 223.22 41.47Q222.07 43.8 220 45.13Q217.93 46.45 215.17 46.45ZM215.17 43.56Q217.99 43.56 219.57 41.52Q221.15 39.48 221.15 36.12Q221.15 32.71 219.56 30.66Q217.97 28.6 215.17 28.6Q212.37 28.6 210.78 30.65Q209.19 32.7 209.19 36.12Q209.19 39.5 210.77 41.53Q212.35 43.56 215.17 43.56ZM231.29 18V46H228.1V18ZM242.94 46.45Q240.82 46.45 239.09 45.76Q237.36 45.06 236.29 43.64Q235.22 42.22 235.09 40.06H238.25Q238.59 43.71 242.87 43.71Q244.94 43.71 246.13 42.84Q247.32 41.98 247.32 40.66Q247.32 39.54 246.5 38.86Q245.67 38.18 244.34 37.88L241.14 37.13Q235.54 35.81 235.54 31.49Q235.54 29.8 236.45 28.5Q237.36 27.19 238.99 26.45Q240.61 25.7 242.74 25.7Q244.81 25.7 246.45 26.48Q248.09 27.26 249.06 28.69Q250.03 30.12 250.09 32.09H246.97Q246.95 30.52 245.8 29.48Q244.66 28.45 242.74 28.45Q240.92 28.45 239.83 29.33Q238.74 30.21 238.74 31.49Q238.74 32.62 239.56 33.31Q240.39 33.99 241.82 34.33L245.01 35.08Q247.87 35.76 249.2 37.1Q250.54 38.45 250.54 40.59Q250.54 42.43 249.54 43.74Q248.54 45.06 246.83 45.76Q245.11 46.45 242.94 46.45Z" fill="#2D3748"/></svg>
|