Recast Section 7 on a value-added base (formulation A) and verify the iso-elastic optimum#20
Merged
Merged
Conversation
Verify the structural simulator's iso-elastic firm optimum and ground its
effective VAT wedge in real sector data, addressing whether VAT is correctly
applied to value added rather than whole turnover.
- dynamic/verify_optimum.py: numerically verifies the iso-elastic optimum
against the closed form y*=n(1-tau)^e, the FOC elasticity identity, the
second-order condition, the e->0 frictionless limit, and the Kleven-Waseem
notch geometry (dominated region + marginal buncher). Writes
results/iso_optimum_verification.{png,txt}.
- dynamic/sector_vat.py: derives an empirical sector net-VAT-to-turnover wedge
from HMRC sector VAT data and re-prices the flat reforms with it, vs the
synthetic firm-level wedge. Writes results/sector_vat_comparison.{png,txt}.
- dynamic/model.py: backward-compatible tau0_override kwarg on reform_revenue
(default behaviour unchanged) so the effective wedge can come from data.
- Register firm-microsim-verify-optimum and firm-microsim-sector-vat console
scripts; extend smoke-test coverage.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lysis
Make the deductible-expense structure explicit and analyse the optima of the
iso-elastic profit function, following up the data-grounded wedge.
- dynamic/deductible_model.py: explicit reformulation in which VAT is levied on
value added, pi = (1 - tau*(1-delta))*y - C(y;n,e) with sector deductible
share delta. Closed forms for the effective wedge tau*(1-delta), optimum
n*(1-tau*(1-delta))**e, notch jump and dominated-region width, plus a
marginal-buncher indifference solve. Verifies the optimum (closed form vs
numerical argmax to 4e-7), and proves machine-precision equivalence with the
existing (1-tau0)*y simulator when tau0 = tau*(1-delta). Sector deductible
shares come from the real HMRC data via sector_vat, making the notch and
dominated region sector-specific (agriculture ~no notch; IT services the full
£21,250). Writes results/deductible_model.{png,txt}.
- dynamic/optima_count.py: counts/plots the local maxima of the profit function
per schedule shape — flat single rate (1), hard notch (2), reduced-rate band
(3), graduated taper (2, non-concave) — showing one FOC root per rate regime
with extra maxima at the schedule discontinuities. Writes
results/optima_count.{png,txt}.
- Register firm-microsim-deductible and firm-microsim-optima-count console
scripts; extend smoke-test coverage. Full suite: 77 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compare two ways of writing the registered firm's profit, differing in whether
deductible input spend d=delta*y is subtracted as a real cost:
A pi = (1-tau)(y - delta*y) - C(y;n,e) = (1-delta)(1-tau)*y - C (inputs a cost)
B pi = (1 - tau(1-delta))*y - C(y;n,e) (paper; tax base only)
dynamic/value_added_model.py implements A, verifies its optimum
y*=n[(1-delta)(1-tau)]^e (worst rel err 1.4e-6, strictly concave), and compares
against B across sectors and the real population:
- notch jump tau(1-delta)T* is IDENTICAL under A and B;
- dominated region under A is a flat £21,250 for every sector (the (1-delta)
cancels exactly), matching the paper's section-4 value, whereas under B it is
sector-specific and smaller (population mean £9,024);
- A's retained wedge (1-delta)(1-tau) is smaller than B's 1-tau(1-delta) by
exactly delta, so A attributes more distortion and recovers much higher
abilities (population mean +297%), degenerating as delta->1 (zero value added);
- A's larger wedge implies stronger base-broadening, so reforms are relatively
cheaper under A than B.
Neither is identified by the data: it is a modelling convention (C is total
turnover cost under B, own-factor cost under A). Writes
results/value_added_comparison.{png,txt}. Register firm-microsim-value-added.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Model A2: the firm chooses value added z=(1-delta)*y directly (pure
Kleven-Waseem with z as the base), taxed at the full statutory rate when
registered:
unregistered: pi = z - C(z;n,e) -> z* = n
registered: pi = (1-tau)*z - C(z;n,e) -> z* = n*(1-tau)^e
The £85k turnover notch maps to a sector-specific value-added threshold
z_T=(1-delta)*T*. A2 is the cleanest of the three formulations for a
value-added VAT base:
- literal value-added base (VAT on z, not on whole turnover);
- BOUNDED ability n = undistorted value added, n=(1-delta)*y_obs/(1-tau)^e,
which goes to 0 (not infinity) as delta->1, fixing model A's blow-up
(population mean n: A2 £0.96M vs A £7.73M vs B £1.94M);
- turnover dominated region a_y = T*tau/(1-tau) = £21,250 flat for every
sector (the (1-delta) cancels), matching section 4 and model A, where
model B shrinks it by sector (mean £9,024);
- notch jump tau(1-delta)T* identical to A and B;
- intensive response governed by the full (1-tau) on value added, so larger
than B (20%->15% band: +1.04% turnover vs B +0.45%).
Optimum verified (z*=n(1-tau)^e, worst rel err 7.3e-7, strictly concave,
elasticity identity). Writes results/va_choice_comparison.{png,txt}. Register
firm-microsim-va-choice. Full suite: 164 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document why a single value-added wedge (models B/A2) cannot represent the
bunching-vs-voluntary-registration split that Liu, Lockwood, Almunia & Tam
(2021) identify. Registration carries two opposing effects:
pi_registered - pi_unregistered = t*y*[omega - beta*(1-omega)]
input VAT reclaim (a benefit, proportional to input share omega) vs output VAT
borne on B2C sales (a cost, proportional to B2C share beta). The net notch is
negative for consumer-facing low-input firms (bunching) and positive for
input-heavy B2B firms (voluntary registration) -- a sign flip across firm types
that no single turnover/value-added wedge can produce.
dynamic/liu_mechanism.py plots the notch and taper for three illustrative firm
types. Clearly flagged as STYLISED: Liu et al. use fixed-coefficients production
and CES demand (no iso-elastic ability n -- the iso-elastic cost here is borrowed
only for curve shape), and it is not data-grounded (it would need sector input
share omega from ONS Supply-Use/ABS value-added-to-turnover, and B2C share beta
from the Supply-Use final-demand split, neither yet in the repo). Writes
results/liu_mechanism.{png,txt}. Register firm-microsim-liu-mechanism. 168 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…neity Reframe the behavioural-costs section so VAT is levied on value added, not whole turnover, and add the registration-heterogeneity discussion. paper/Sections/behavioural.tex: - Recast the iso-elastic simulator on the value-added base (model A2): the firm chooses value added z=(1-delta)*y, pi=(1-tau*f(z))*z - C(z;n,e), z*=n(1-tau)^e, with n the undistorted value added and the £85k turnover notch mapping to a sector-specific value-added threshold (1-delta)*T*. State the clean properties (bounded ability; turnover dominated region T*tau/(1-tau)=£21,250 independent of delta). Note the input-subtraction formulation (A) gives the same notch jump but diverging abilities, and that A/A2/B coincide at delta=0; the reported costing is the same value-added tax expressed as the effective turnover wedge tau(1-delta), so Table behavioural_costs is unchanged. - delta is parametric, to be grounded in ONS Supply-Use / ABS value-added-to- turnover data in future work. - New subsection "Heterogeneous registration incentives: input reclaim and B2C sales" (Liu et al. 2021): net registration effect t*[omega - beta*(1-omega)], input-VAT reclaim vs output VAT on B2C, with two illustrative figures; the notch flips sign across firm types (bunching vs voluntary registration), which the single wedge cannot represent. Scope conclusion: consumer-facing, limited-reclaim firms are the omega->0, beta->1 corner where the single-wedge / Kleven-Waseem treatment applies. All reported numbers, labels, cross-refs, and the taper-exclusion reasoning preserved. dynamic/liu_mechanism.py: restyle to the paper teal palette (no suptitle, 300 dpi) and emit two paper figures -- liu_registration_choice and liu_notch_taper -- to results/ and paper/figures/. Drop the superseded results/liu_mechanism.png. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the iso-elastic intensive-margin simulator with the extensive registration margin of Liu, Lockwood, Almunia & Tam (2021) throughout the paper, and add a parametric budget costing on that margin. Section 7 (paper/Sections/behavioural.tex), fully rewritten: - The firm's problem is now the Liu structural registration model: fixed- coefficients (Keen-Mintz) unit cost 1/a registered vs (1+omega t)/a unregistered (derived from a taxed input share omega and labour share 1-omega); CES demand in B2C and B2B markets; constant-elasticity monopoly markups; profit maximised over prices and the registration indicator subject to the s* constraint. The net benefit of registering is t[omega - beta(1-omega)] -- input-VAT reclaim vs the output-VAT burden on B2C sales -- so the threshold is a downward notch (bunching) for consumer-facing low-input firms and a net gain (voluntary registration) for input-heavy B2B firms. - New parametric budget cost on the EXTENSIVE margin: a registered firm yields t(1-omega)y, an unregistered firm t*omega*y; a reform that changes who is in the net moves revenue between them. Raising the threshold to GBP100k costs GBP0 to about -GBP1.05bn (only low-omega/high-beta consumer firms de-register; input-heavy firms register voluntarily); 10%/15% bands up to about -GBP0.93bn/-GBP0.47bn. Explicitly extensive-margin only (turnover held fixed); the intensive CES response and ONS Supply-Use grounding of (omega, beta) are future work. Removed: the iso-elastic firm problem, ability recovery, forward solve, Table behavioural_costs, the e->0 validation, and the taper behavioural-exclusion. Propagated the swap so the paper is consistent: the abstract (frontmatter.tex), the intro (four-things, contribution #3, behavioural numbers, roadmap), the conclusion (summary-table row + behavioural discussion + limitations), and a model.tex cross-reference (marginal-buncher caption repointed to the inference appendix; the Section 7 preview updated). Static costs, the GBP21,250 dominated region, and the placebo / bunching non-identification are unchanged. dynamic/liu_costing.py: the parametric extensive-margin costing (registered vs unregistered government VAT, registration rule, the three reforms) with the (omega,beta) sensitivity sweep; writes results/liu_costing.{png,txt} and the paper figure. Register firm-microsim-liu-costing. Full suite: 179 passed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per author direction, drop the Liu et al. CES registration model from the paper and make Section 7 the value-added "formulation A" of the iso-elastic simulator. - paper/Sections/behavioural.tex: restore the iso-elastic structural simulator and re-express its firm problem so VAT falls on value added (formulation A), pi_i(y) = (1-delta_i)(1-tau f(y)) y - C(y;n_i,e), with delta_i the deductible-input share so value added is (1-delta_i)y. Explain C: because inputs delta_i*y are already netted out via the (1-delta_i) factor, C is the firm's OWN-FACTOR production cost (labour and capital), not its total cost -- reading it as total cost would double-count inputs. Flat-rate optimum y*=n[(1-delta)(1-tau)]^e. The operational forward solve and Table behavioural_costs are unchanged, pinned to each firm's calibrated net-VAT rate tau_i (~3%); formulation A is the conceptual value-added statement of the same tax (the two coincide at delta=0). Caveat: the literal formulation-A recovery diverges as delta->1, which is why the costing uses the net-VAT wedge; delta_i is parametric, to be grounded in ONS Supply-Use / ABS value-added data in future work. No Liu/CES content. - Revert intro, conclusion, abstract (frontmatter), and the model.tex cross-reference to the iso-elastic structural-simulator framing (contribution #3, the e-sensitivity numbers, the conclusion table row, and the marginal-buncher caption pointing to Section 7). Static costs, the GBP21,250 dominated region, and the placebo are unchanged. Compiles clean (38 pages, no undefined references). The Liu analysis code (liu_mechanism.py, liu_costing.py) remains as committed tooling but is no longer cited in the paper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Trim the branch to the code and figures the final paper actually uses, and add a
value-added optima figure to Section 7.
Added:
- dynamic/formulation_a_optima.py (+ test): the formulation-A profit
(1-delta)(1-tau f(y))y - C(y;n,e) and its optima across the hard notch and the
graduated taper for three deductible shares delta in {0,0.4,0.8}; writes
results/ and paper/figures/formulation_a_optima.png. Referenced in Section 7
(fig:formulation_a_optima) showing how delta scales the curve and pulls the
registered optimum toward the threshold.
Removed (redundant exploration that is no longer in the paper):
- dynamic/deductible_model.py (B), value_added_model.py (A vs B),
va_choice_model.py (A2), sector_vat.py, optima_count.py, liu_mechanism.py,
liu_costing.py, and their tests, result artifacts, and paper/figures/liu_* images.
- the backward-compatible tau0_override hook on reform_revenue (added for the
removed sector_vat module); reform_revenue is back to its original signature.
- the corresponding console-script and smoke-test entries.
Kept: dynamic/verify_optimum.py (iso-elastic optimum verification) and the new
formulation_a_optima.py.
Paper polish: data.tex and bunching.tex no longer claim a behavioural forward
solve is "left to future work" (Section 7 performs it); removed dead commented
traces in appendix.tex. No reported numbers, labels, or table cells changed.
Compiles clean (39 pages, no undefined references); full suite green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vahid-ahmadi
added a commit
that referenced
this pull request
Jun 30, 2026
Sync onto the new main (PRs #19, #20 merged) and reflect Section 7's value-added recast of the behavioural simulator. - New slide "The firm's problem: VAT on value added (formulation A)": pi(y)=(1-delta)(1-tau f(y))y - C(y;n,e), with delta the deductible-input share (value added (1-delta)y), C the own-factor cost (inputs already netted, so reading C as total cost would double-count), optimum n[(1-delta)(1-tau)]^e, and the new formulation_a_optima figure (delta in {0,0.4,0.8} across notch and taper). - Behavioural slide: note the simulator is a value-added base (formulation A). The e-sensitivity numbers (GBP508m->GBP292m, etc.) are unchanged. - Limitations: the "turnover-tax approximation" bullet now states the simulator taxes value added with a parametric delta (ONS Supply-Use to come), still abstracting from voluntary registration. Rebuilt slides.pdf (30 pages). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #19.
Recasts the paper's behavioural layer (Section 7) so that VAT falls on value added rather than on whole turnover, and verifies the underlying iso-elastic optimum.
Paper (Section 7,
behavioural.tex)The iso-elastic structural simulator is written in an explicit value-added form ("formulation A"):
π_i(y) = (1 − δ_i)(1 − τ f(y))·y − C(y;n_i,e)where
δ_iis the firm's deductible-input share, so value added is(1 − δ_i)y, andf(y)∈[0,1]is the schedule's fraction of the statutory rateτ.Cis: because the deductible inputsδ_i yare already netted out by the(1−δ_i)factor,C(y;n,e)is the firm's own-factor production cost (labour and capital) — not total cost; reading it as total cost would double-count the inputs.y* = n[(1−δ)(1−τ)]^e.e-sensitivity cost table are unchanged: they stay pinned to each firm's calibrated net-VAT rateτ_i(~3%), with formulation A the conceptual value-added statement of the same tax (the two coincide atδ=0).δ→1, which is why the costing uses the net-VAT wedge;δis currently parametric, to be grounded in ONS Supply–Use / ABS value-added data in future work.fig:formulation_a_optima: the value-added profit and its optima across the hard notch and the graduated taper forδ ∈ {0, 0.4, 0.8}, showing how a higher deductible share pulls the registered optimum toward the threshold.data.tex/bunching.tex(the behavioural forward solve is no longer described as "future work") and dead commented traces removed fromappendix.tex.Code
dynamic/formulation_a_optima.py(+ test) — generates the Section 7 figure.dynamic/verify_optimum.py(+ test) — numerically verifies the iso-elastic optimum: closed formy*=n(1−τ)^eto 4e-7, the FOC elasticity identity, strict concavity, thee→0limit, and the Kleven–Waseem notch geometry (dominated region; marginal buncher matches the paper).Tests
pytest→ all green.ruff check .clean. The paper compiles (39 pages, no undefined references). No reported number, label, or table cell changed.🤖 Generated with Claude Code