fomtools 0.0.1__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.1/.github/workflows/ci.yml +111 -0
- fomtools-0.0.1/.github/workflows/claude-code-review.yml +43 -0
- fomtools-0.0.1/.github/workflows/claude.yml +49 -0
- fomtools-0.0.1/.github/workflows/docs.yml +89 -0
- fomtools-0.0.1/.github/workflows/release.yml +106 -0
- fomtools-0.0.1/.github/workflows/update-skill.yml +43 -0
- fomtools-0.0.1/.gitignore +387 -0
- fomtools-0.0.1/.pre-commit-config.yaml +24 -0
- fomtools-0.0.1/AGENTS.md +84 -0
- fomtools-0.0.1/CLAUDE.md +1 -0
- fomtools-0.0.1/LICENSE +201 -0
- fomtools-0.0.1/PKG-INFO +212 -0
- fomtools-0.0.1/README.md +158 -0
- fomtools-0.0.1/docs/api/canonicalizer.md +8 -0
- fomtools-0.0.1/docs/api/codegen.md +32 -0
- fomtools-0.0.1/docs/api/constraint.md +5 -0
- fomtools-0.0.1/docs/api/linearexpression.md +1 -0
- fomtools-0.0.1/docs/api/proxablefunctions.md +45 -0
- fomtools-0.0.1/docs/api/solvers.md +8 -0
- fomtools-0.0.1/docs/api/steps.md +11 -0
- fomtools-0.0.1/docs/api/verifier.md +2 -0
- fomtools-0.0.1/docs/api.md +11 -0
- fomtools-0.0.1/docs/index.md +101 -0
- fomtools-0.0.1/docs/installation.md +41 -0
- fomtools-0.0.1/docs/javascripts/mathjax.js +12 -0
- fomtools-0.0.1/docs/tutorials/_recorded_timings.json +84 -0
- fomtools-0.0.1/docs/tutorials/codegen.md +630 -0
- fomtools-0.0.1/docs/tutorials/codegen_speedup_results.md +23 -0
- fomtools-0.0.1/docs/tutorials/control.py +343 -0
- fomtools-0.0.1/docs/tutorials/cvxpygen.md +287 -0
- fomtools-0.0.1/docs/tutorials/cvxpygen_mpc.py +147 -0
- fomtools-0.0.1/docs/tutorials/lasso.py +303 -0
- fomtools-0.0.1/docs/tutorials/network.py +377 -0
- fomtools-0.0.1/docs/tutorials/nnls.py +292 -0
- fomtools-0.0.1/docs/tutorials/nnls_verification.py +183 -0
- fomtools-0.0.1/docs/tutorials/portfolio.py +290 -0
- fomtools-0.0.1/docs/tutorials.md +18 -0
- fomtools-0.0.1/fomtools/__init__.py +14 -0
- fomtools-0.0.1/fomtools/canonicalizers/__init__.py +5 -0
- fomtools-0.0.1/fomtools/canonicalizers/canonicalizer.py +293 -0
- fomtools-0.0.1/fomtools/canonicalizers/mip.py +1265 -0
- fomtools-0.0.1/fomtools/canonicalizers/obbt_handler.py +339 -0
- fomtools-0.0.1/fomtools/canonicalizers/sdp.py +2223 -0
- fomtools-0.0.1/fomtools/canonicalizers/simulator.py +1403 -0
- fomtools-0.0.1/fomtools/codegen/__init__.py +103 -0
- fomtools-0.0.1/fomtools/codegen/agent/__init__.py +110 -0
- fomtools-0.0.1/fomtools/codegen/agent/agents.yaml +33 -0
- fomtools-0.0.1/fomtools/codegen/agent/budget.py +132 -0
- fomtools-0.0.1/fomtools/codegen/agent/claude_sdk.py +221 -0
- fomtools-0.0.1/fomtools/codegen/agent/cli_driver.py +328 -0
- fomtools-0.0.1/fomtools/codegen/agent/cli_specs.py +265 -0
- fomtools-0.0.1/fomtools/codegen/agent/codex_sdk.py +151 -0
- fomtools-0.0.1/fomtools/codegen/agent/driver.py +313 -0
- fomtools-0.0.1/fomtools/codegen/agent/pidev_sdk.py +131 -0
- fomtools-0.0.1/fomtools/codegen/agent/prompts.py +246 -0
- fomtools-0.0.1/fomtools/codegen/agent/sdk_base.py +384 -0
- fomtools-0.0.1/fomtools/codegen/agent/stub.py +104 -0
- fomtools-0.0.1/fomtools/codegen/cli.py +263 -0
- fomtools-0.0.1/fomtools/codegen/config.py +336 -0
- fomtools-0.0.1/fomtools/codegen/dedup.py +132 -0
- fomtools-0.0.1/fomtools/codegen/emit.py +37 -0
- fomtools-0.0.1/fomtools/codegen/examples.py +483 -0
- fomtools-0.0.1/fomtools/codegen/extract.py +655 -0
- fomtools-0.0.1/fomtools/codegen/extract_scheduled.py +415 -0
- fomtools-0.0.1/fomtools/codegen/extract_unrolled.py +321 -0
- fomtools-0.0.1/fomtools/codegen/factorize.py +457 -0
- fomtools-0.0.1/fomtools/codegen/generate.py +625 -0
- fomtools-0.0.1/fomtools/codegen/harness.py +226 -0
- fomtools-0.0.1/fomtools/codegen/ir.py +456 -0
- fomtools-0.0.1/fomtools/codegen/kernel_rules.py +347 -0
- fomtools-0.0.1/fomtools/codegen/objective.py +463 -0
- fomtools-0.0.1/fomtools/codegen/oracle.py +470 -0
- fomtools-0.0.1/fomtools/codegen/postprocess.py +298 -0
- fomtools-0.0.1/fomtools/codegen/schedule.py +123 -0
- fomtools-0.0.1/fomtools/codegen/spec.py +584 -0
- fomtools-0.0.1/fomtools/codegen/targets/__init__.py +26 -0
- fomtools-0.0.1/fomtools/codegen/targets/base.py +151 -0
- fomtools-0.0.1/fomtools/codegen/targets/embedded_c.py +1751 -0
- fomtools-0.0.1/fomtools/codegen/targets/large_scale_cuda.py +1028 -0
- fomtools-0.0.1/fomtools/codegen/targets/large_scale_openmp.py +119 -0
- fomtools-0.0.1/fomtools/codegen/wrapper.py +167 -0
- fomtools-0.0.1/fomtools/constraint.py +425 -0
- fomtools-0.0.1/fomtools/cvxpygen/__init__.py +62 -0
- fomtools-0.0.1/fomtools/cvxpygen/api.py +200 -0
- fomtools-0.0.1/fomtools/cvxpygen/builders.py +600 -0
- fomtools-0.0.1/fomtools/cvxpygen/glue.py +397 -0
- fomtools-0.0.1/fomtools/cvxpygen/interface.py +470 -0
- fomtools-0.0.1/fomtools/cvxpygen/qpdata.py +240 -0
- fomtools-0.0.1/fomtools/cvxpygen/scaling.py +136 -0
- fomtools-0.0.1/fomtools/iteratetrajectory.py +212 -0
- fomtools-0.0.1/fomtools/linearexpression.py +837 -0
- fomtools-0.0.1/fomtools/nn/__init__.py +3 -0
- fomtools-0.0.1/fomtools/nn/layers.py +256 -0
- fomtools-0.0.1/fomtools/proxable_functions/__init__.py +25 -0
- fomtools-0.0.1/fomtools/proxable_functions/elastic_net.py +108 -0
- fomtools-0.0.1/fomtools/proxable_functions/hinge_loss.py +72 -0
- fomtools-0.0.1/fomtools/proxable_functions/huber_loss.py +137 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_affine.py +144 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_ball_l1.py +67 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_ball_linf.py +69 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_box.py +108 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_half_space.py +86 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_nonnegative.py +65 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_nonpositive.py +65 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_point.py +71 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_polyhedral.py +86 -0
- fomtools-0.0.1/fomtools/proxable_functions/ind_simplex.py +56 -0
- fomtools-0.0.1/fomtools/proxable_functions/labeled_hinge_loss.py +74 -0
- fomtools-0.0.1/fomtools/proxable_functions/least_squares.py +91 -0
- fomtools-0.0.1/fomtools/proxable_functions/linear.py +90 -0
- fomtools-0.0.1/fomtools/proxable_functions/norm_inf.py +80 -0
- fomtools-0.0.1/fomtools/proxable_functions/norm_l1.py +109 -0
- fomtools-0.0.1/fomtools/proxable_functions/proximal_operator.py +97 -0
- fomtools-0.0.1/fomtools/proxable_functions/quadratic.py +152 -0
- fomtools-0.0.1/fomtools/proxable_functions/soft_nonnegative.py +85 -0
- fomtools-0.0.1/fomtools/proxable_functions/sq_l2_norm.py +84 -0
- fomtools-0.0.1/fomtools/proxable_functions/sum_negative.py +101 -0
- fomtools-0.0.1/fomtools/proxable_functions/sum_positive.py +97 -0
- fomtools-0.0.1/fomtools/proxable_functions/total_variation_1d.py +93 -0
- fomtools-0.0.1/fomtools/sets/__init__.py +21 -0
- fomtools-0.0.1/fomtools/sets/affine_subspace.py +31 -0
- fomtools-0.0.1/fomtools/sets/ball.py +58 -0
- fomtools-0.0.1/fomtools/sets/box.py +98 -0
- fomtools-0.0.1/fomtools/sets/polyhedron.py +91 -0
- fomtools-0.0.1/fomtools/sets/set.py +112 -0
- fomtools-0.0.1/fomtools/solvers/__init__.py +20 -0
- fomtools-0.0.1/fomtools/solvers/clarabel.py +269 -0
- fomtools-0.0.1/fomtools/solvers/cuclarabel.py +159 -0
- fomtools-0.0.1/fomtools/solvers/factory.py +75 -0
- fomtools-0.0.1/fomtools/solvers/gurobi.py +567 -0
- fomtools-0.0.1/fomtools/solvers/highs.py +430 -0
- fomtools-0.0.1/fomtools/solvers/mip_solver.py +293 -0
- fomtools-0.0.1/fomtools/solvers/sdp_solver.py +48 -0
- fomtools-0.0.1/fomtools/solvers/solver.py +179 -0
- fomtools-0.0.1/fomtools/stepdecomposers/__init__.py +3 -0
- fomtools-0.0.1/fomtools/stepdecomposers/mip_step_decomposer.py +52 -0
- fomtools-0.0.1/fomtools/stepdecomposers/sdp_step_decomposer.py +201 -0
- fomtools-0.0.1/fomtools/stepdecomposers/simulator_step_decomposer.py +326 -0
- fomtools-0.0.1/fomtools/stepdecomposers/step_decomposer.py +1303 -0
- fomtools-0.0.1/fomtools/steps/__init__.py +7 -0
- fomtools-0.0.1/fomtools/steps/affine.py +133 -0
- fomtools-0.0.1/fomtools/steps/lin_prog.py +128 -0
- fomtools-0.0.1/fomtools/steps/quad_prog.py +224 -0
- fomtools-0.0.1/fomtools/steps/relu.py +223 -0
- fomtools-0.0.1/fomtools/steps/saturated_linear.py +113 -0
- fomtools-0.0.1/fomtools/steps/soft_threshold.py +89 -0
- fomtools-0.0.1/fomtools/steps/step.py +79 -0
- fomtools-0.0.1/fomtools/utils/__init__.py +2 -0
- fomtools-0.0.1/fomtools/utils/convex_hull_cuts.py +206 -0
- fomtools-0.0.1/fomtools/utils/dict_utils.py +69 -0
- fomtools-0.0.1/fomtools/utils/envelopes.py +66 -0
- fomtools-0.0.1/fomtools/utils/math_utils.py +86 -0
- fomtools-0.0.1/fomtools/utils/matrix_utils.py +60 -0
- fomtools-0.0.1/fomtools/utils/range_utils.py +65 -0
- fomtools-0.0.1/fomtools/utils/sparse_utils.py +81 -0
- fomtools-0.0.1/fomtools/verifier.py +1602 -0
- fomtools-0.0.1/fomtools.egg-info/PKG-INFO +212 -0
- fomtools-0.0.1/fomtools.egg-info/SOURCES.txt +308 -0
- fomtools-0.0.1/fomtools.egg-info/dependency_links.txt +1 -0
- fomtools-0.0.1/fomtools.egg-info/entry_points.txt +2 -0
- fomtools-0.0.1/fomtools.egg-info/requires.txt +53 -0
- fomtools-0.0.1/fomtools.egg-info/scm_file_list.json +304 -0
- fomtools-0.0.1/fomtools.egg-info/scm_version.json +8 -0
- fomtools-0.0.1/fomtools.egg-info/top_level.txt +1 -0
- fomtools-0.0.1/mkdocs.yml +53 -0
- fomtools-0.0.1/pyproject.toml +106 -0
- fomtools-0.0.1/setup.cfg +4 -0
- fomtools-0.0.1/skills/README.md +55 -0
- fomtools-0.0.1/skills/fomtools/SKILL.md +250 -0
- fomtools-0.0.1/skills/fomtools/references/api.md +182 -0
- fomtools-0.0.1/skills/fomtools/references/codegen.md +233 -0
- fomtools-0.0.1/skills/fomtools/references/cvxpygen.md +128 -0
- fomtools-0.0.1/skills/update-prompt.md +29 -0
- fomtools-0.0.1/tests/__init__.py +0 -0
- fomtools-0.0.1/tests/codegen/__init__.py +0 -0
- fomtools-0.0.1/tests/codegen/conftest.py +675 -0
- fomtools-0.0.1/tests/codegen/golden/boxqp/embedded_c/fom_solver.c +81 -0
- fomtools-0.0.1/tests/codegen/golden/cgqp/large_scale_cuda/fom_solver.cu +147 -0
- fomtools-0.0.1/tests/codegen/golden/cgqp/large_scale_openmp/fom_solver.c +84 -0
- fomtools-0.0.1/tests/codegen/golden/cvxpygen_qp/embedded_c/fom_solver.c +106 -0
- fomtools-0.0.1/tests/codegen/golden/cvxpygen_qp_objective/embedded_c/fom_solver.c +103 -0
- fomtools-0.0.1/tests/codegen/golden/dr/embedded_c/fom_solver.c +95 -0
- fomtools-0.0.1/tests/codegen/golden/fista/embedded_c/fom_solver.c +133 -0
- fomtools-0.0.1/tests/codegen/golden/fista_objective/embedded_c/fom_solver.c +116 -0
- fomtools-0.0.1/tests/codegen/golden/halpern/embedded_c/fom_solver.c +87 -0
- fomtools-0.0.1/tests/codegen/golden/indef_kkt/embedded_c/fom_solver.c +84 -0
- fomtools-0.0.1/tests/codegen/golden/ista/embedded_c/fom_solver.c +102 -0
- fomtools-0.0.1/tests/codegen/golden/ista/large_scale_cuda/fom_solver.cu +152 -0
- fomtools-0.0.1/tests/codegen/golden/ista/large_scale_openmp/fom_solver.c +89 -0
- fomtools-0.0.1/tests/codegen/golden/ista_objective/embedded_c/fom_solver.c +90 -0
- fomtools-0.0.1/tests/codegen/golden/ista_objective/large_scale_cuda/fom_solver.cu +108 -0
- fomtools-0.0.1/tests/codegen/golden/mpc/embedded_c/fom_solver.c +96 -0
- fomtools-0.0.1/tests/codegen/golden/pdhg_lp/embedded_c/fom_solver.c +105 -0
- fomtools-0.0.1/tests/codegen/golden/pdhg_lp/large_scale_cuda/fom_solver.cu +178 -0
- fomtools-0.0.1/tests/codegen/golden/scheduled/embedded_c/fom_solver.c +124 -0
- fomtools-0.0.1/tests/codegen/golden/scheduled_objective/embedded_c/fom_solver.c +98 -0
- fomtools-0.0.1/tests/codegen/golden/scheduled_objective/large_scale_cuda/fom_solver.cu +119 -0
- fomtools-0.0.1/tests/codegen/test_agent_budget.py +147 -0
- fomtools-0.0.1/tests/codegen/test_agent_integration.py +84 -0
- fomtools-0.0.1/tests/codegen/test_agent_notes.py +302 -0
- fomtools-0.0.1/tests/codegen/test_cli.py +226 -0
- fomtools-0.0.1/tests/codegen/test_codegen_dispatch.py +144 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_bounds.py +59 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_builders.py +150 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_dispatch.py +613 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_e2e.py +199 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_glue.py +251 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_objective.py +345 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_preflight.py +58 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_qpdata.py +118 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_register.py +107 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_scaling.py +177 -0
- fomtools-0.0.1/tests/codegen/test_cvxpygen_scheduled.py +240 -0
- fomtools-0.0.1/tests/codegen/test_dedup.py +183 -0
- fomtools-0.0.1/tests/codegen/test_dr_pipeline.py +62 -0
- fomtools-0.0.1/tests/codegen/test_editable_linsolve.py +109 -0
- fomtools-0.0.1/tests/codegen/test_editable_ops.py +546 -0
- fomtools-0.0.1/tests/codegen/test_emit_scaffold.py +97 -0
- fomtools-0.0.1/tests/codegen/test_examples_scale.py +156 -0
- fomtools-0.0.1/tests/codegen/test_factorize.py +312 -0
- fomtools-0.0.1/tests/codegen/test_fista_pipeline.py +123 -0
- fomtools-0.0.1/tests/codegen/test_float32.py +115 -0
- fomtools-0.0.1/tests/codegen/test_indefinite_kkt.py +62 -0
- fomtools-0.0.1/tests/codegen/test_ir_extraction.py +156 -0
- fomtools-0.0.1/tests/codegen/test_large_scale.py +627 -0
- fomtools-0.0.1/tests/codegen/test_objective_termination.py +1002 -0
- fomtools-0.0.1/tests/codegen/test_oracle.py +80 -0
- fomtools-0.0.1/tests/codegen/test_pdhg_pipeline.py +95 -0
- fomtools-0.0.1/tests/codegen/test_postprocess.py +102 -0
- fomtools-0.0.1/tests/codegen/test_profiling.py +149 -0
- fomtools-0.0.1/tests/codegen/test_satlin_mpc.py +204 -0
- fomtools-0.0.1/tests/codegen/test_scheduled_ir.py +291 -0
- fomtools-0.0.1/tests/codegen/test_scheduled_pipeline.py +162 -0
- fomtools-0.0.1/tests/codegen/test_spec_roundtrip.py +132 -0
- fomtools-0.0.1/tests/codegen/test_static_constraints.py +356 -0
- fomtools-0.0.1/tests/codegen/test_stationarity_gate.py +135 -0
- fomtools-0.0.1/tests/codegen/test_stub_pipeline.py +115 -0
- fomtools-0.0.1/tests/codegen/test_termination_interval.py +95 -0
- fomtools-0.0.1/tests/codegen/test_unrolled_emission.py +161 -0
- fomtools-0.0.1/tests/codegen/test_unrolled_ir.py +384 -0
- fomtools-0.0.1/tests/codegen/test_wrapper_roundtrip.py +73 -0
- fomtools-0.0.1/tests/conftest.py +150 -0
- fomtools-0.0.1/tests/cvxpy.py +246 -0
- fomtools-0.0.1/tests/examples/comparison_lasso.py +174 -0
- fomtools-0.0.1/tests/examples/cut_experiment.py +299 -0
- fomtools-0.0.1/tests/test_LP_pdhg.py +115 -0
- fomtools-0.0.1/tests/test_add_constraint.py +190 -0
- fomtools-0.0.1/tests/test_affine_simulator.py +124 -0
- fomtools-0.0.1/tests/test_audit_regressions.py +300 -0
- fomtools-0.0.1/tests/test_boxpgd_sdp_mip.py +163 -0
- fomtools-0.0.1/tests/test_complementarity.py +188 -0
- fomtools-0.0.1/tests/test_convex_hull_cuts.py +370 -0
- fomtools-0.0.1/tests/test_copy_isolation.py +129 -0
- fomtools-0.0.1/tests/test_docs_examples.py +16 -0
- fomtools-0.0.1/tests/test_douglas_rachford.py +89 -0
- fomtools-0.0.1/tests/test_fixed_point_ista.py +52 -0
- fomtools-0.0.1/tests/test_fixed_point_nnls.py +139 -0
- fomtools-0.0.1/tests/test_ind_ball_l1.py +144 -0
- fomtools-0.0.1/tests/test_ind_polyhedral.py +204 -0
- fomtools-0.0.1/tests/test_ind_simplex.py +159 -0
- fomtools-0.0.1/tests/test_inf_norm_sdp.py +227 -0
- fomtools-0.0.1/tests/test_infinite_bounds.py +230 -0
- fomtools-0.0.1/tests/test_ista.py +61 -0
- fomtools-0.0.1/tests/test_ista_sdp_mip.py +168 -0
- fomtools-0.0.1/tests/test_iterate_trajectory.py +399 -0
- fomtools-0.0.1/tests/test_l1_obj_norm.py +582 -0
- fomtools-0.0.1/tests/test_linear_program.py +151 -0
- fomtools-0.0.1/tests/test_linearexpression.py +368 -0
- fomtools-0.0.1/tests/test_linsolve_simulator.py +169 -0
- fomtools-0.0.1/tests/test_mincost_flow.py +241 -0
- fomtools-0.0.1/tests/test_mip_solution_consistency.py +344 -0
- fomtools-0.0.1/tests/test_nn_verify_jax.py +83 -0
- fomtools-0.0.1/tests/test_nn_verify_torch.py +66 -0
- fomtools-0.0.1/tests/test_nnls_sdp_mip.py +71 -0
- fomtools-0.0.1/tests/test_norm_inf.py +160 -0
- fomtools-0.0.1/tests/test_obbt_handler.py +570 -0
- fomtools-0.0.1/tests/test_objective_bounds.py +204 -0
- fomtools-0.0.1/tests/test_partial_relu.py +70 -0
- fomtools-0.0.1/tests/test_partial_relu_sdp_sim.py +341 -0
- fomtools-0.0.1/tests/test_placeholder.py +12 -0
- fomtools-0.0.1/tests/test_portfolio.py +135 -0
- fomtools-0.0.1/tests/test_prox_decomposer.py +1976 -0
- fomtools-0.0.1/tests/test_quadratic_program.py +252 -0
- fomtools-0.0.1/tests/test_range_functions.py +42 -0
- fomtools-0.0.1/tests/test_relu_simulator.py +59 -0
- fomtools-0.0.1/tests/test_satlin.py +257 -0
- fomtools-0.0.1/tests/test_satlin_simulator.py +64 -0
- fomtools-0.0.1/tests/test_sdp_canonicalizer.py +172 -0
- fomtools-0.0.1/tests/test_sdp_cuts.py +2000 -0
- fomtools-0.0.1/tests/test_sdp_hull.py +156 -0
- fomtools-0.0.1/tests/test_sdp_inequality.py +136 -0
- fomtools-0.0.1/tests/test_sdp_nnls.py +103 -0
- fomtools-0.0.1/tests/test_sdp_selector.py +206 -0
- fomtools-0.0.1/tests/test_sets.py +302 -0
- fomtools-0.0.1/tests/test_simulator.py +210 -0
- fomtools-0.0.1/tests/test_soft_threshold_simulator.py +58 -0
- fomtools-0.0.1/tests/test_solve_kwargs.py +228 -0
- fomtools-0.0.1/tests/test_solver_boundary.py +109 -0
- fomtools-0.0.1/tests/test_sparse_utils.py +65 -0
- fomtools-0.0.1/tests/test_stack.py +426 -0
- fomtools-0.0.1/tests/test_subproblem_simulator.py +230 -0
- fomtools-0.0.1/tests/test_sum_squares.py +203 -0
- fomtools-0.0.1/tests/test_total_variation_1d.py +168 -0
- fomtools-0.0.1/tests/test_two_norm_mip.py +168 -0
- fomtools-0.0.1/tests/test_vec_LUhat.py +48 -0
- fomtools-0.0.1/tests/test_verifier.py +108 -0
- fomtools-0.0.1/tests/test_verifier_ista.py +78 -0
- fomtools-0.0.1/tests/test_warm_start.py +151 -0
- fomtools-0.0.1/uv.lock +4414 -0
- fomtools-0.0.1/wrangler.toml +5 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
name: Python build and test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
linter:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.13"
|
|
17
|
+
- name: ruff
|
|
18
|
+
uses: chartboost/ruff-action@v1
|
|
19
|
+
|
|
20
|
+
package:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.13"
|
|
30
|
+
|
|
31
|
+
- name: Set up uv
|
|
32
|
+
uses: astral-sh/setup-uv@v6
|
|
33
|
+
with:
|
|
34
|
+
version: "0.11.15"
|
|
35
|
+
|
|
36
|
+
- name: Build wheel
|
|
37
|
+
run: uv build --wheel
|
|
38
|
+
|
|
39
|
+
- name: Install into clean venv (no extras)
|
|
40
|
+
run: |
|
|
41
|
+
uv venv /tmp/pkg-test
|
|
42
|
+
uv pip install --python /tmp/pkg-test/bin/python dist/*.whl
|
|
43
|
+
|
|
44
|
+
- name: Smoke-test import and CLI
|
|
45
|
+
run: |
|
|
46
|
+
/tmp/pkg-test/bin/python -c "import fomtools; print(fomtools.__version__)"
|
|
47
|
+
/tmp/pkg-test/bin/fomtools-codegen --help
|
|
48
|
+
|
|
49
|
+
- name: Verify HiGHS default works
|
|
50
|
+
run: |
|
|
51
|
+
/tmp/pkg-test/bin/python -c "
|
|
52
|
+
from fomtools.verifier import Verifier
|
|
53
|
+
v = Verifier()
|
|
54
|
+
assert v.canonicalizer.solver.__class__.__name__ == 'HiGHSSolver'
|
|
55
|
+
print('HiGHS default: OK')
|
|
56
|
+
"
|
|
57
|
+
|
|
58
|
+
- name: Verify Gurobi ImportError message
|
|
59
|
+
run: |
|
|
60
|
+
/tmp/pkg-test/bin/python -c "
|
|
61
|
+
import sys
|
|
62
|
+
from fomtools.verifier import Verifier
|
|
63
|
+
try:
|
|
64
|
+
Verifier(solver='gurobi')
|
|
65
|
+
sys.exit('expected ImportError')
|
|
66
|
+
except ImportError as e:
|
|
67
|
+
assert 'fomtools[gurobi]' in str(e)
|
|
68
|
+
print(f'ImportError hint: OK ({e})')
|
|
69
|
+
"
|
|
70
|
+
|
|
71
|
+
test:
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
strategy:
|
|
74
|
+
matrix:
|
|
75
|
+
python-version: ["3.12", "3.13"]
|
|
76
|
+
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/checkout@v4
|
|
79
|
+
|
|
80
|
+
- name: Install OpenBLAS (needed for SCS)
|
|
81
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
82
|
+
|
|
83
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
84
|
+
uses: actions/setup-python@v5
|
|
85
|
+
with:
|
|
86
|
+
python-version: ${{ matrix.python-version }}
|
|
87
|
+
|
|
88
|
+
- name: Set up uv
|
|
89
|
+
uses: astral-sh/setup-uv@v6
|
|
90
|
+
with:
|
|
91
|
+
version: "0.11.15"
|
|
92
|
+
|
|
93
|
+
- shell: bash
|
|
94
|
+
id: write-license
|
|
95
|
+
env:
|
|
96
|
+
LICENSE: ${{ secrets.GUROBI_LICENSE}}
|
|
97
|
+
run: |
|
|
98
|
+
echo "$LICENSE" > $PWD/gurobi.lic
|
|
99
|
+
|
|
100
|
+
- name: Install the project
|
|
101
|
+
run: uv sync --extra dev --extra docs --extra nn --extra cvxpygen
|
|
102
|
+
|
|
103
|
+
- name: Check Gurobi License
|
|
104
|
+
env:
|
|
105
|
+
GRB_LICENSE_FILE: ${{ github.workspace }}/gurobi.lic
|
|
106
|
+
run: uv run --frozen python -c "import gurobipy; gurobipy.Model()"
|
|
107
|
+
|
|
108
|
+
- name: Run tests
|
|
109
|
+
env:
|
|
110
|
+
GRB_LICENSE_FILE: ${{ github.workspace }}/gurobi.lic
|
|
111
|
+
run: uv run --frozen pytest tests
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Claude Code Review
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, ready_for_review, reopened]
|
|
6
|
+
# Optional: Only run on specific file changes
|
|
7
|
+
# paths:
|
|
8
|
+
# - "src/**/*.ts"
|
|
9
|
+
# - "src/**/*.tsx"
|
|
10
|
+
# - "src/**/*.js"
|
|
11
|
+
# - "src/**/*.jsx"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude-review:
|
|
15
|
+
# Optional: Filter by PR author
|
|
16
|
+
# if: |
|
|
17
|
+
# github.event.pull_request.user.login == 'external-contributor' ||
|
|
18
|
+
# github.event.pull_request.user.login == 'new-developer' ||
|
|
19
|
+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
|
20
|
+
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
pull-requests: read
|
|
25
|
+
issues: read
|
|
26
|
+
id-token: write
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout repository
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
with:
|
|
32
|
+
fetch-depth: 1
|
|
33
|
+
|
|
34
|
+
- name: Run Claude Code Review
|
|
35
|
+
id: claude-review
|
|
36
|
+
uses: anthropics/claude-code-action@v1
|
|
37
|
+
with:
|
|
38
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
39
|
+
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
|
|
40
|
+
plugins: 'code-review@claude-code-plugins'
|
|
41
|
+
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
|
|
42
|
+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
|
43
|
+
# or https://code.claude.com/docs/en/cli-reference for available options
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Claude Code
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issue_comment:
|
|
5
|
+
types: [created]
|
|
6
|
+
pull_request_review_comment:
|
|
7
|
+
types: [created]
|
|
8
|
+
issues:
|
|
9
|
+
types: [opened, assigned]
|
|
10
|
+
pull_request_review:
|
|
11
|
+
types: [submitted]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude:
|
|
15
|
+
if: |
|
|
16
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
17
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
18
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
19
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
pull-requests: read
|
|
24
|
+
issues: read
|
|
25
|
+
id-token: write
|
|
26
|
+
actions: read # Required for Claude to read CI results on PRs
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout repository
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
with:
|
|
31
|
+
fetch-depth: 1
|
|
32
|
+
|
|
33
|
+
- name: Run Claude Code
|
|
34
|
+
id: claude
|
|
35
|
+
uses: anthropics/claude-code-action@v1
|
|
36
|
+
with:
|
|
37
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
38
|
+
|
|
39
|
+
# This is an optional setting that allows Claude to read CI results on PRs
|
|
40
|
+
additional_permissions: |
|
|
41
|
+
actions: read
|
|
42
|
+
|
|
43
|
+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
|
44
|
+
# prompt: 'Update the pull request description to include a summary of changes.'
|
|
45
|
+
|
|
46
|
+
# Optional: Add claude_args to customize behavior and configuration
|
|
47
|
+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
|
48
|
+
# or https://code.claude.com/docs/en/cli-reference for available options
|
|
49
|
+
# claude_args: '--allowed-tools Bash(gh pr:*)'
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
deploy:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
python: [ "3.13" ]
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Setup Python
|
|
21
|
+
uses: actions/setup-python@v4
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python }}
|
|
24
|
+
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Upgrade setuptools/build
|
|
28
|
+
run: |
|
|
29
|
+
pip install wheel --upgrade
|
|
30
|
+
pip install setuptools --upgrade
|
|
31
|
+
python -m pip install --upgrade build
|
|
32
|
+
|
|
33
|
+
- name: Build wheels for package
|
|
34
|
+
run: python -m build
|
|
35
|
+
|
|
36
|
+
- name: Install Package with docs extra
|
|
37
|
+
run: pip install ."[docs, cvxpygen]"
|
|
38
|
+
|
|
39
|
+
- name: List dependencies
|
|
40
|
+
run: pip freeze
|
|
41
|
+
|
|
42
|
+
- shell: bash
|
|
43
|
+
id: write-license
|
|
44
|
+
env:
|
|
45
|
+
LICENSE: ${{ secrets.GUROBI_LICENSE}}
|
|
46
|
+
run: |
|
|
47
|
+
echo "$LICENSE" > $PWD/gurobi.lic
|
|
48
|
+
|
|
49
|
+
- name: Check Gurobi License
|
|
50
|
+
env:
|
|
51
|
+
GRB_LICENSE_FILE: ${{ github.workspace }}/gurobi.lic
|
|
52
|
+
run: python -c "import gurobipy; gurobipy.Model()"
|
|
53
|
+
|
|
54
|
+
- name: Export marimo notebooks
|
|
55
|
+
env:
|
|
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
|
|
61
|
+
|
|
62
|
+
- name: Verify html generation
|
|
63
|
+
run: ls docs/tutorials
|
|
64
|
+
|
|
65
|
+
- name: Configure Git Credentials
|
|
66
|
+
run: |
|
|
67
|
+
git config user.name github-actions[bot]
|
|
68
|
+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
|
69
|
+
|
|
70
|
+
- name: Set weekly cache ID
|
|
71
|
+
run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
|
72
|
+
|
|
73
|
+
- name: Cache MkDocs Material build files
|
|
74
|
+
uses: actions/cache@v4
|
|
75
|
+
with:
|
|
76
|
+
key: mkdocs-material-${{ env.cache_id }}
|
|
77
|
+
path: ~/.cache
|
|
78
|
+
restore-keys: |
|
|
79
|
+
mkdocs-material-
|
|
80
|
+
|
|
81
|
+
- name: Build MkDocs site
|
|
82
|
+
run: mkdocs build
|
|
83
|
+
|
|
84
|
+
- name: Deploy to Cloudflare Pages with Wrangler
|
|
85
|
+
uses: cloudflare/wrangler-action@v4.0.0
|
|
86
|
+
with:
|
|
87
|
+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
88
|
+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
89
|
+
command: deploy
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes only when BOTH hold:
|
|
4
|
+
# 1. a tag matching v* is pushed, and
|
|
5
|
+
# 2. the tagged commit is on main.
|
|
6
|
+
# Tag the merge commit on main after the PR is merged, then push the tag.
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
tags: ["v*"]
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0 # setuptools_scm needs the history and tags
|
|
22
|
+
|
|
23
|
+
- name: Require the tagged commit to be on main
|
|
24
|
+
run: |
|
|
25
|
+
git fetch origin main
|
|
26
|
+
if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
|
|
27
|
+
echo "::error::Tag $GITHUB_REF_NAME ($GITHUB_SHA) is not on main; refusing to publish."
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.13"
|
|
34
|
+
|
|
35
|
+
- name: Set up uv
|
|
36
|
+
uses: astral-sh/setup-uv@v6
|
|
37
|
+
with:
|
|
38
|
+
version: "0.11.15"
|
|
39
|
+
|
|
40
|
+
- name: Build sdist and wheel
|
|
41
|
+
run: uv build
|
|
42
|
+
|
|
43
|
+
- name: Check the built version matches the tag
|
|
44
|
+
run: |
|
|
45
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
46
|
+
ls dist
|
|
47
|
+
test -f "dist/fomtools-${VERSION}.tar.gz" \
|
|
48
|
+
|| { echo "::error::sdist for version $VERSION not found"; exit 1; }
|
|
49
|
+
test -f dist/fomtools-"${VERSION}"-*.whl \
|
|
50
|
+
|| { echo "::error::wheel for version $VERSION not found"; exit 1; }
|
|
51
|
+
|
|
52
|
+
- name: Smoke-test the wheel in a clean venv
|
|
53
|
+
run: |
|
|
54
|
+
uv venv /tmp/pkg-test
|
|
55
|
+
uv pip install --python /tmp/pkg-test/bin/python dist/*.whl
|
|
56
|
+
/tmp/pkg-test/bin/python -c "
|
|
57
|
+
import fomtools
|
|
58
|
+
assert fomtools.__version__ == '${GITHUB_REF_NAME#v}', fomtools.__version__
|
|
59
|
+
from fomtools.verifier import Verifier
|
|
60
|
+
Verifier()
|
|
61
|
+
print('fomtools', fomtools.__version__, 'OK')
|
|
62
|
+
"
|
|
63
|
+
/tmp/pkg-test/bin/fomtools-codegen --help
|
|
64
|
+
|
|
65
|
+
- uses: actions/upload-artifact@v4
|
|
66
|
+
with:
|
|
67
|
+
name: dist
|
|
68
|
+
path: dist/
|
|
69
|
+
|
|
70
|
+
publish:
|
|
71
|
+
needs: build
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
environment:
|
|
74
|
+
name: pypi
|
|
75
|
+
url: https://pypi.org/project/fomtools/
|
|
76
|
+
permissions:
|
|
77
|
+
id-token: write # Trusted Publishing (OIDC); no API token needed
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/download-artifact@v4
|
|
80
|
+
with:
|
|
81
|
+
name: dist
|
|
82
|
+
path: dist/
|
|
83
|
+
|
|
84
|
+
- name: Publish to PyPI
|
|
85
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
86
|
+
|
|
87
|
+
github-release:
|
|
88
|
+
needs: publish
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
permissions:
|
|
91
|
+
contents: write
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/download-artifact@v4
|
|
94
|
+
with:
|
|
95
|
+
name: dist
|
|
96
|
+
path: dist/
|
|
97
|
+
|
|
98
|
+
- name: Create GitHub Release
|
|
99
|
+
env:
|
|
100
|
+
GH_TOKEN: ${{ github.token }}
|
|
101
|
+
run: |
|
|
102
|
+
gh release create "$GITHUB_REF_NAME" dist/* \
|
|
103
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
104
|
+
--title "$GITHUB_REF_NAME" \
|
|
105
|
+
--generate-notes \
|
|
106
|
+
--verify-tag
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Update FOMTools Skill
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- 'docs/**'
|
|
8
|
+
- 'fomtools/**'
|
|
9
|
+
- 'AGENTS.md'
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
pull-requests: write
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
update-skill:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout repository
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
with:
|
|
23
|
+
fetch-depth: 1
|
|
24
|
+
|
|
25
|
+
- name: Run Claude Code to update skill
|
|
26
|
+
id: claude
|
|
27
|
+
uses: anthropics/claude-code-action@v1
|
|
28
|
+
with:
|
|
29
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
30
|
+
prompt_file: skills/update-prompt.md
|
|
31
|
+
|
|
32
|
+
allowed_tools: |
|
|
33
|
+
Bash(git status)
|
|
34
|
+
Bash(git diff:*)
|
|
35
|
+
Bash(git log:*)
|
|
36
|
+
Bash(git add:*)
|
|
37
|
+
Bash(git commit:*)
|
|
38
|
+
Bash(find:*)
|
|
39
|
+
Bash(grep:*)
|
|
40
|
+
Bash(wc:*)
|
|
41
|
+
Read
|
|
42
|
+
Edit
|
|
43
|
+
Write
|