Skip to content

Regional target algorithm refactoring - #2422

Draft
Renato-Rodrigues wants to merge 5 commits into
remindmodel:developfrom
Renato-Rodrigues:leastSquareSlope
Draft

Regional target algorithm refactoring#2422
Renato-Rodrigues wants to merge 5 commits into
remindmodel:developfrom
Renato-Rodrigues:leastSquareSlope

Conversation

@Renato-Rodrigues

@Renato-Rodrigues Renato-Rodrigues commented Aug 5, 2026

Copy link
Copy Markdown
Member

Purpose of this PR

Replaces the carbon-price search behind regional emission targets (47_regipol / regiCarbonPrice) with a least-squares slope (Newton) formulation plus an explicit convergence state machine.

This PR fits the local price update response ΔEmissions/ΔPrice by least squares over a rolling window of the last 8 iterations in which the target actually steered its own price, and takes a Newton step bounded by a trust region.

Around that a state machine was built to deal with the noisy search characteristics of the issue:

  • Convergence bands with hysteresis: converge at 0.75 × tolerance, hold until 1.0 × tolerance, both requiring 2 consecutive iterations. The margin exists because the Nash loop itself wobbles by ~±1%, which is the size of a typical tolerance.
  • A re-open budget: a converged target dragged back out by other regions re-steers, at most 3 times, and earns the budget back after a long settled stretch.
  • Five give-up branches: noise floor, infeasible target, divergence, re-open budget spent, parked. Each freezes the price, reports the real residual, and records which branch fired. An unreachable target is now abandoned deliberately and visibly instead of running the price up until the iteration cap.
  • Two termination signals: the run may only end when every target is frozen and (met or given up), so the Nash loop can no longer finish one iteration before a correction the algorithm was about to make.

Every tuning constant is overridable per scenario via the cm_slopeParam switch, without touching code.

Nothing changes for runs without cm_emiMktTarget.

Docs: tutorials/19_RegionalEmissionTargets.md is new and covers usage, the algorithm, diagnostics and the test-scenario suite, with three generated decision graphs. Please check the tutorial for more details on how the algorithm works.

https://github.com/Renato-Rodrigues/remind/blob/4163945d8ca9202b6aa6c643978f9d7ba1b55560/tutorials/19_RegionalEmissionTargets.md

What changed, by file

File Change
modules/47_regipol/regiCarbonPrice/postsolve.gms The algorithm: slope fit, step bounding, state machine, give-up branches, rollback
.../datainput.gms, declarations.gms, sets.gms 35 tuning constants, per-target state container p47_targetState, per-iteration trace p47_slopeTrace_iter
main.gms New cm_slopeParam switch; cm_emiMktTarget documentation (also fixes an ESDESR typo)
modules/47_regipol/module.gms In-code documentation of the target syntax and behaviour
config/scenario_config_emiMkt_tests.csv New: 33-scenario regression suite (see below)
tutorials/19_RegionalEmissionTargets.md + figures/ New user/developer documentation and its figure generator

Test scenario suite

config/scenario_config_emiMkt_tests.csv covers every target shape the syntax allows (multi-region, ETS/ESR split, nested group/member, multi-period, budget, net-zero, non-binding market, sub-noise-floor tolerance) plus A/B pairs: each mechanism has an off-arm, and an off-arm must never beat its base. Tutorial §4 documents each scenario and why it exists.

Reporting updates

pik-piam/remind2#802

Results

Example results from a test run: emiMkt_mult_2026-08-05_09.45.55 with net-zero targets for CHA (2060), DEU (2030, 2045), EU (2030, 2050), UKI (2050), IND (2070), JPN (2050), USA (2050).

image

Type of change

Indicate the items relevant for your PR by replacing ◻️ with ☑️.
Do not delete any lines. This makes it easier to understand which areas are affected by your changes and which are not.

Parts concerned

  • ☑️ GAMS Code
  • ◻️ R-scripts
  • ☑️ Documentation (GAMS incode documentation, comments, tutorials)
  • ◻️ Input data / CES parameters
  • ◻️ Tests, CI/CD (continuous integration/deployment)
  • ◻️ Configuration (switches in main.gms, default.cfg, and scenario_config*.csv files)
  • ◻️ Other (please give a description)

Impact

  • ◻️ Bug fix
  • ☑️ Refactoring
  • ☑️ New feature
  • ◻️ Change of parameter values or input data (including CES parameters)
  • ◻️ Minor change (default scenarios show only small differences)
  • ◻️ Fundamental change of results of default scenarios

Checklist

Do not delete any line. Leave unfinished elements unchecked so others know how far along you are.
In the end all checkboxes must be ticked before you can merge
.

  • I executed the automated model tests (make test) after my final commit and all tests pass (FAIL 0)
  • I adjusted the reporting in remind2 if and where it was needed
  • I adjusted the madrat packages (mrremind and other packages involved) for input data generation if and where it was needed
  • My code follows the coding etiquette
  • I explained my changes within the PR, particularly in hard-to-understand areas
  • I checked that the in-code documentation is up-to-date
  • I adjusted forbiddenColumnNames in readCheckScenarioConfig.R in case the PR leads to deprecated switches
  • I updated the CHANGELOG.md correctly (added, changed, fixed, removed, input data/calibration)

Further information (optional)

  • Runs with these changes are here:
    /p/projects/ecemf/REMIND/debug/remind_leastSquareSlope/output

@Renato-Rodrigues Renato-Rodrigues changed the title Least square slope Regional target algorithm refactoring Aug 5, 2026
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.

1 participant