Adding the Mexican hat neighborhood function - #2
Conversation
The Mexican hat was computed as the outer product of two 1-D Ricker wavelets, mirroring how _gaussian is written. That reasoning holds only for the gaussian: exp(-(dx^2+dy^2)/2s^2) factors into exp(-dx^2/2s^2) * exp(-dy^2/2s^2), so its outer product is exactly the isotropic 2-D gaussian. The Ricker wavelet is not multiplicatively separable. The product is therefore not a function of the distance between two nodes, which is what a neighborhood function must be: cf. sqdist(c, i) in Kohonen (2013) Eq. (5), and the single "lateral distance" abscissa of Vrieze (1995) Fig. 3. Concretely, in the diagonal quadrants both 1-D factors are negative and their product flips positive, putting a spurious excitatory lobe exactly where the function must inhibit. On a 21x21 grid with sigma=3 the old form gave h = +0.165 at (c+2s, c+2s) where the isotropic form gives -0.055, and its zero-crossing locus was a cross rather than the circle r = sqrt(2)*sigma. Rewrite it as (1 - u) * exp(-u) over u = sqdist(c, i) / (2*sigma^2), normalized so h_cc = 1. It now crosses zero at r = sqrt(2)*sigma and bottoms out at -exp(-2) at r = 2*sigma. Also, since both functions now share one distance computation: - Fix the cyclic fold-back, which only folded offsets above +length/2 and left those below -length/2 alone. A winner at row 0 of a 10x10 toroidal map wrapped correctly (h[9] = 0.6065) while a winner at row 9 did not (h[0] = 0.0). Replaced with the minimum-image convention, which folds both tails. This bug predates this branch and affected _gaussian; the new function would have inherited it. - Reject a non-finite or non-positive sigma instead of dividing by zero. The bubble still admits sigma = 0, which selects the winner alone. - Raise ValueError naming the valid options for an unknown neighborhood_function, matching weight_initialization, rather than letting a bare KeyError escape. - Reject mode='batch' with the mexican hat. Kohonen Eq. (8) is a weighted mean whose denominator sum_j n_j*h_ji is not sign-definite for a signed neighborhood function; on a 12x12 grid 49 of 144 denominators come out negative, which inverts or explodes the update. Add tests/test_neighborhood.py, asserting closed-form properties rather than golden values: isotropy, the zero crossing, the minimum, absence of a positive lobe beyond the zero crossing, and cyclic wrap symmetry in both directions.
|
Hi @Arne49, thank you for this, and sorry for how long it took me to get to it. I've reviewed the implementation and pushed a few commits to your branch instead of sending you The separability issueThe implementation builds the 2-D neighborhood as the outer product of two 1-D Ricker wavelets: ax = (1 - dx**2 / sigma**2) * np.exp(-dx**2 / d)
ay = (1 - dy**2 / sigma**2) * np.exp(-dy**2 / d)
return np.outer(ax, ay)This follows The exponential turns a sum into a product, so the outer product of two 1-D gaussians really is the Why it matters in practiceIn the diagonal quadrants both
So nodes far out along the diagonals get pulled toward the input with up to 16.5% of the winner's What the sources sayBoth references the library is built on require the neighborhood to be a function of one scalar
Every formulation collapses The change
u = self._sqdist(c, sigma) / (2 * sigma * sigma)
return (1.0 - u) * np.exp(-u)normalized so One consequence worth pointing out: this shifts your 1-D profile slightly too. The 2-D Two things that were already broken before your PRYour function copied the distance computation from
One new restriction
Also in the pushed commits
Could you look over the commits before I merge? And thanks again. This turned up a real bug in the |
|
One correction to what I said above: I went ahead and merged rather than waiting, since I didn't Your review is still very welcome, and it isn't too late to act on. If something in the isotropic Next up is a larger PR modernizing the packaging, adding a proper test suite and CI, and fixing a Thanks again for the contribution and for the nudge. |
|
Hi André,
Thank you for your response and comments. This week, I am quite busy, but I
will have time for the review next week.
Best,
Arne
Am Di., 28. Juli 2026 um 20:52 Uhr schrieb André Moreira Souza <
***@***.***>:
… *andremsouza* left a comment (andremsouza/python-som#2)
<#2 (comment)>
One correction to what I said above: I went ahead and merged rather than
waiting, since I didn't
want this sitting open any longer on my account after you'd already waited
since June.
Your review is still very welcome, and it isn't too late to act on. If
something in the isotropic
version looks wrong to you, say so here and I'll open a follow-up. The
Mexican hat is one function
behind a name in a dict with tests around it, so changing it after the
fact is cheap.
Next up is a larger PR modernizing the packaging, adding a proper test
suite and CI, and fixing a
few other things the review turned up along the way. That's where a second
pair of eyes would help
most, if you're interested. I'll link it here when it's open.
Thanks again for the contribution and for the nudge.
—
Reply to this email directly, view it on GitHub
<#2?email_source=notifications&email_token=AHQMSMGN5ULKFSUQUSQNCFL5HDY5BA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMJQHA2DAMRUGMZKM4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5108402432>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHQMSMDSRWEEXF4YN5QLJUD5HDY5BAVCNFSNUABFKJSXA33TNF2G64TZHMZDEOJSGUYDIOJZHNEXG43VMU5TINJWGMYTCOBVGE2KC5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AHQMSMCF4J7HKHC4RM27VBL5HDY5BA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMJQHA2DAMRUGMZKM4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AHQMSMHCKHA6MBLOGN7HEM35HDY5BA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMJQHA2DAMRUGMZKM4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Additionaly to the Gaussian and Bubble neighborhood function, now also the Mexican hat neighborhood function implemented.