Skip to content

[codex] Fix load polynomial cost signs#3036

Open
Kkkakania wants to merge 4 commits into
e2nIEE:developfrom
Kkkakania:codex/fix-load-poly-cost-signs
Open

[codex] Fix load polynomial cost signs#3036
Kkkakania wants to merge 4 commits into
e2nIEE:developfrom
Kkkakania:codex/fix-load-poly-cost-signs

Conversation

@Kkkakania

@Kkkakania Kkkakania commented Jun 21, 2026

Copy link
Copy Markdown

Summary

This fixes the polynomial active-power cost conversion for controllable loads and other elements that are represented with the opposite active-power sign in PYPOWER.

For a controllable load, pandapower cost coefficients describe the load-side power P, while PYPOWER represents it with -P. The transformed polynomial should therefore be:

a * (-P)^2 + b * (-P) + c = a * P^2 - b * P + c

So only the linear active-power coefficient changes sign. The quadratic and constant terms should keep their original signs.

Changes

  • Keep cp2_eur_per_mw2 unchanged when filling gencost.
  • Keep cp0_eur unchanged for both quadratic and linear polynomial costs.
  • Continue applying the existing sign conversion to cp1_eur_per_mw.
  • Add a regression test for controllable load polynomial costs, including both quadratic and linear gencost layouts.
  • Constrain scipy-stubs below 1.18 for the typing extra, because the current 1.18 stubs use Python 3.12 type statement syntax while mypy.ini intentionally checks with python_version = 3.10.

Fixes #2954.

Validation

  • python -m pytest pandapower/test/opf/test_costs_pol.py -q
  • python -m pytest pandapower/test/opf/test_costs_mixed.py pandapower/test/opf/test_basic.py::test_storage_opf pandapower/test/opf/test_dcline.py -q
  • python -m mypy
  • git diff --check

Remote checks after the second push:

  • Passed: Codacy, SonarCloud, all Python 3.10-3.14 build splits, numpy1-support, OPF, docs, linting, postgresql, relying jobs, coverage, typing, and tutorial jobs including tutorial_warnings_tests.
  • Known baseline failure: the warnings (3.14, *) jobs fail with the same pandapower/test/plotting/test_geo.py / tap_dependency_table DeprecationWarning that is present on the current develop workflow run. I verified this against develop run 27626832854, job 81693439589.

@codecov

codecov Bot commented Jun 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.98%. Comparing base (4917c0d) to head (d15df89).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3036      +/-   ##
===========================================
- Coverage    71.98%   71.98%   -0.01%     
===========================================
  Files          352      352              
  Lines        38591    38590       -1     
===========================================
- Hits         27779    27778       -1     
  Misses       10812    10812              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Kkkakania Kkkakania marked this pull request as ready for review June 21, 2026 08:49
Comment thread pandapower/opf/make_objective.py Outdated
signs = array([-1 if element in ["load", "storage", "dcline"] else 1 for element in cost.et])
if is_quadratic:
c2 = cost["cp2_eur_per_mw2"]
c2 = cost["cp2_eur_per_mw2"].values

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the rebased branch: the new code uses .to_numpy() for the OPF cost coefficient arrays instead of .values.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up: I expanded the cleanup before pushing again, so _fill_gencost_poly() now uses .to_numpy() for the active and reactive polynomial cost coefficient arrays (cp* and cq*). The focused OPF and converter tests still pass locally.

@vogt31337

Copy link
Copy Markdown
Contributor

Hi @Kkkakania , thanks for the PR. But since this convention is in pandapower already a long time, I first want to check other OPF tools. pypower is only one of many possible, and I would not prefer to break all the others just for pypower.

@Kkkakania Kkkakania force-pushed the codex/fix-load-poly-cost-signs branch from a753e99 to b434044 Compare June 25, 2026 04:12
@Kkkakania

Copy link
Copy Markdown
Author

Rebased onto the current develop branch, so the PR no longer has merge conflicts. The earlier scipy-stubs pin change is no longer part of this branch because develop already includes the upstream dependency update.\n\nLocal checks after the rebase:\n\n- uv run pytest pandapower/test/opf/test_costs_pol.py::test_controllable_load_polynomial_cost_signs pandapower/test/opf/test_pandamodels_converter.py::test_controllable_load_polynomial_cost_signs_for_powermodels -q\n- uv run pytest pandapower/test/opf/test_costs_pol.py -q\n- uv run pytest pandapower/test/opf/test_pandamodels_converter.py -q\n\nOn the backend-compatibility concern: the remaining patch keeps the sign convention limited to the generated OPF cost coefficients. The added tests cover both the PYPOWER conversion path and the PowerModels converter output. The intended behavior is that controllable load active power uses the opposite sign for the linear term, while the constant and quadratic coefficients stay in the user-provided cost convention. If the preferred project policy is to keep the historical coefficient convention for compatibility, I can narrow this further to a documentation/test-only change instead of changing the generated coefficients.

@Kkkakania Kkkakania force-pushed the codex/fix-load-poly-cost-signs branch 2 times, most recently from d51542c to 02f5382 Compare June 25, 2026 07:45
@Kkkakania

Copy link
Copy Markdown
Author

Added a focused reactive polynomial-cost regression test for the PYPOWER q-cost rows. This covers the cq0/cq1/cq2 coefficient path that Codecov was flagging after the .to_numpy() cleanup.

Fresh local checks:

  • uv run pytest pandapower/test/opf/test_costs_pol.py::test_controllable_load_reactive_polynomial_cost_signs -q
  • uv run pytest pandapower/test/opf/test_costs_pol.py pandapower/test/opf/test_pandamodels_converter.py -q
  • git diff --check

I also checked the failing warnings (3.14, 1) job log. It fails while collecting pandapower/test/plotting/test_geo.py because mv_oberrhein() emits the existing tap_dependency_table is missing in net deprecation warning under -W error; that does not appear related to this OPF cost change.

@Kkkakania Kkkakania force-pushed the codex/fix-load-poly-cost-signs branch from 02f5382 to d15df89 Compare June 27, 2026 02:58
@Kkkakania

Copy link
Copy Markdown
Author

I trimmed the implementation diff to keep this PR focused on the coefficient sign behavior only. The .to_numpy() cleanup is no longer part of the branch, so the changed production code is now just the active-power coefficient convention plus the duplicate-sign removal.

Fresh local checks after the force-push:

  • uv run pytest pandapower/test/opf/test_costs_pol.py::test_controllable_load_polynomial_cost_signs pandapower/test/opf/test_costs_pol.py::test_controllable_load_reactive_polynomial_cost_signs pandapower/test/opf/test_pandamodels_converter.py::test_controllable_load_polynomial_cost_signs_for_powermodels -q
  • uv run pytest pandapower/test/opf/test_costs_pol.py pandapower/test/opf/test_pandamodels_converter.py -q
  • git diff --check

This should also make the patch easier for Codecov to evaluate.

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wrong sign parameter cp2_eur_per_mw2 of create_poly_cost for load

2 participants