Skip to content
This repository was archived by the owner on Aug 20, 2026. It is now read-only.
This repository was archived by the owner on Aug 20, 2026. It is now read-only.

reg_field: membrane penalty runs at half strength inside make_kernel_bending_rls #40

Description

@balbasty

Summary

make_kernel_bending_rls (regularisers/field/2d.h, and the 3D analogue) fills the kernel table via make_kernel_bending(kernel, ..., nc) and then uniformly rescales kernel[1..5] by 0.25. That rescale is correct for the bending part of the coefficients, but kernel[1] = -4·b·vx·(vx+vy) - m·vx (and the vy analogue) also mixes in a membrane term, which wants a 0.5 scale factor (matching the plain membrane_rls kernel), not 0.25.

Symptom

With a uniform weight map w≡1:

  • bending_rls reproduces matvec_bending exactly for absolute-only and bending-only inputs (diff ~1e-16/1e-14).
  • For membrane-only input, the diff is ~1.07 (not the ~1e-16 you'd expect from an exact reduction) — the membrane contribution is running at the wrong magnitude specifically when computed via the bending-order kernel path (i.e. when bending != 0 alongside membrane != 0, or more precisely whenever make_kernel_bending_rls is the constructor used).

This is a magnitude/scaling bug, not a self-adjointness bug — the operator stays symmetric either way, it's just computing the wrong coefficient value for the membrane term when bending order is active with RLS/JRLS weighting.

Suggested fix

Split the two scale factors explicitly instead of a single uniform 0.25:

kernel[1] = -b * vx * (vx + vy) - 0.5 * m * vx; // was: -4*b*vx*(vx+vy) - m*vx, then *0.25
kernel[2] = -b * vy * (vx + vy) - 0.5 * m * vy;
kernel[3] = 0.25 * b * vx * vx;
kernel[4] = 0.25 * b * vy * vy;
kernel[5] = 0.5 * b * vx * vy;

(matching the existing pre-scale-then-multiply structure, just correcting which factor applies to which term). Verify: keeps the self-adjointness fix from #38 intact, and makes w≡1 bending+membrane+absolute reduce exactly to the unweighted matvec_bending/matvec_all at that combined order.

Related

Also worth a deliberate decision (separate follow-up, not blocking this fix): bending_rls's kernel[0] (the absolute term) is left unweighted by the RLS weight map, whereas membrane_rls's kernel does modulate absolute by the weight — an inconsistency between the two orders' semantics that predates this issue.

Surfaced during the investigation for #34 (bending RLS/JRLS self-adjointness), not folded into that fix since it's an independent magnitude issue.

Workstream: claude-jitfields-to-fastfields

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions