Encoders - #65
Closed
MichielStock wants to merge 25 commits into
Closed
Conversation
Previously, whenever one called `+` over more than 2 hypervectors, the operation worked at each pair, that is: a+b+c+d+e = ((((a+b)+c)+d)+e) This behaviour breaks the binary hypervectors because at each step it introduced noise whenever we have a tie. This fix rewrites the `+` overload so it correctly calls the `bundle` function as an array of hypervectors instead of pairwise operations. Added some tests to cover this behaviour.
…verloaded-operations fix: correct `+` call
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bit true now maps to -1, so XOR on stored bits is exactly the +-1 product. Sign-based real-vector constructor (zero elements throw, pointing to TernaryHV), corrected summary labels, regenerated doctests, and polarity-locking tests (x * x is the all-+1 identity, construction/indexing round-trip, summary counts). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
perturbate(::FHRR, ...) threw a MethodError (no eldist); dedicated methods now resample e^(2pi*i*rand()) at the selected positions. Locked by tests asserting unit modulus, untouched positions, and exact resample counts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The vector decodelevel methods now accept (and ignore) testbound so the generic forwarding no longer mis-dispatches into a MethodError. Adjacent bug flagged, not fixed: the instance path builds encoder and decoder over different random ladders (TODO 1.4b). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
RealHV/GradedHV/GradedBipolarHV results carried the default distr, which silently changed normalize! numerics. Locked by metadata assertions and a numerical test that normalize! rescales to the original spread. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Generic shift! and the clamp!-based normalize! methods returned the raw wrapped vector. Locked by op!(hv) === hv tests for all types and all in-place operations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
δ was an exported non-const global (type-unstable at call sites). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
isequal compared raw storage across types, so a BinaryHV equalled a BipolarHV whenever the bits matched; the one-arg hash override was inconsistent with two-arg hashing. isequal is now a same-type storage fast path, cross-type comparisons fall back to Base element semantics, and hashing is element-based. Locked by same-bits/different-type tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous fix (2e952a7) let cross-type comparisons fall back to Base elementwise semantics, but Julia treats Bool as numeric (true == 1), so an all-true BinaryHV still equalled an all-+1 BipolarHV — whose stored bits are the exact opposite since the polarity flip. == and isequal between different hypervector types now return false unconditionally; same-family comparisons (e.g. TernaryHV{Int8} vs TernaryHV{Int64}) compare by value, and comparisons against plain vectors keep Base elementwise semantics. Hashing stays on the element-based AbstractArray fallback: isequal(hv, ::Vector) can be true, so a type-salted hash would break the hash/equality contract. Locked by tests covering the numeric-coincidence case, the same-family case, and the hash contract for all seven types (including BipolarHV, where storage and elements disagree) and against plain vectors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds the missing encoder layer (raw data in, hypervector out) and gives every constructor form exactly one meaning: - encode(HV, x; D) is the canonical deterministic token path (hash -> seed); HV(x) is shorthand for it. encode(HV, x, strategy) dispatches on the new AbstractEncoding strategies: KMer(k) (windows as atomic hashed tokens — resolves #53), NGram(n) (symbol-level shift-binding via ngrams), Sequence() (bundlesequence) and BagOfSymbols() (multiset). KMer and NGram are genuinely different operations and are documented as such. Extension point: one struct subtyping AbstractEncoding plus one encode method. - HV(n::Number) throws an ArgumentError naming both alternatives (D = n / encode(HV, n)); the one-time @warn and its testset are gone. - Data constructors are widened to AbstractVector{<:Real} and validate each type's element domain: BinaryHV {0,1}; BipolarHV strictly ±1 (zero points to TernaryHV, no more silent sign-taking); TernaryHV {-1,0,+1} (inner constructors stay permissive for operation results); Graded types range-checked instead of silently clamped; FHRR unit modulus. Invalid arrays throw instead of silently token-encoding — BinaryHV([1, 0]) is now a 2-element hypervector, killing that trapdoor. Tuples of reals read as data. BREAKING: numeric constructor tokens throw; graded out-of-range data throws instead of clamping; bipolar non-±1 data throws instead of sign-coercion; Vector{<:Real} data construction added for BinaryHV. Also fixes a tutorial example that constructed an invalid TernaryHV from 0:9 (now RealHV). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The §1.6 fix (9049cb9) is verified correct for every argument form; the locking test only covered the count form — now also fraction, mask, and index-vector. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
eldist(hv) now returns hv.distr for RealHV, GradedHV and GradedBipolarHV instead of falling back to the type default, so perturbate (and level ladders built from custom-distr hypervectors) draw replacement elements from the vector's own distribution. Locked by a resampled-element statistics testset. Closes TODO §1.5c. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Refactor july
Completes the stateful AbstractEncoder pair begun with LevelEncoder:
- RandomProjection{HV, T}: fixed D×d projection matrix (gaussian /
bipolar / sparse_ternary), per-type nonlinearities, scalar-or-vector
ternary threshold θ with a data-driven target_sparsity constructor,
supplied-matrix constructor, rethreshold sharing R, and
nearest-neighbour-only decode (lossy encoding: no analytic inverse).
- phase_encode(z, β): single shared FHRR phase-encoding helper; both
LevelEncoder's fractional power path and RandomProjection's FHRR
nonlinearity (random Fourier features) route through it.
- Regression tests for two known sharp edges: the ternary constructor's
positional collision (supplied matrix vs training data; the residual
square-matrix ambiguity and silently ignored kwargs are recorded as
TODO §2.6, fix is a follow-up rename) and BipolarHV's raw-bits /
zero-state polarity traps, pinned as behaviour-locking tests so the
obvious-but-wrong idioms trip red instead of shipping corruption.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Collaborator
Author
|
Superseded by #66. This is the same integration — the I went with |
Collaborator
Author
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.
Same as #64, but moving in docs. Ok to merge @cvigilv ?