2a4c5c645a
The stone the operator/drift/occupation work stands on: express a relational neighborhood as the compact joint geometry Will specified (design §3/§5, node e94371bd) — semantic side (centroid, principal-axis ellipsoid via dual-PCA, radius) braided with the relational side (k-core skeleton, hub->periphery centrality gradient), plus soft membership and a co-registration diagnostic (corr of hebb strength vs semantic proximity — >0 reifies, <0 flags dreams). Built ONLY on the two standalone modules — engram_vindex (ANN, the cloud) and engram_store (embeddings + hebb adjacency, the skeleton). Pure C11 + libm; does not link or touch el_runtime.c. Strictly READ-ONLY: never mutates nodes, edges, activation, the index, or any retrieval path. Not yet wired into retrieval — foundation only. Self-contained test (test_geometry.c) synthesizes two known embedding clusters with intra-cluster hebb edges and verifies the descriptor recovers the shape: centroid on the seeded cluster, hub = relational center, skeleton = the strong intra-cluster wiring, positive co-registration, sorted axis extents. PERF + ASan/UBSan passes both green; needs no live data.
106 lines
5.2 KiB
C
106 lines
5.2 KiB
C
/* engram_geometry.h — M9 FOUNDATION: the relational-neighborhood GEOMETRY
|
|
* DESCRIPTOR (design doc §3, §5; memory node e94371bd).
|
|
*
|
|
* Computes, for a relational neighborhood grown from a seed set, the compact
|
|
* (KB-not-MB) joint geometry Will specified: the SEMANTIC geometry (centroid,
|
|
* covariance / principal axes, radius) braided with the RELATIONAL geometry
|
|
* (k-core skeleton, hub->periphery centrality gradient), plus soft membership.
|
|
*
|
|
* Two coordinate systems, one shape — "a constellation: bright prototype at the
|
|
* center, a cloud of members at varying distance, the strongest edges as a
|
|
* backbone, fading at the edges."
|
|
*
|
|
* Built ON the two standalone M-era modules only:
|
|
* - engram_vindex : semantic neighbors (the cloud) via ANN.
|
|
* - engram_store : node embeddings + hebb adjacency (the skeleton), read-only.
|
|
* It does NOT link or touch el_runtime.c, and it is a pure READ over the graph:
|
|
* it never modifies nodes, edges, activation, the index, or any retrieval path.
|
|
*
|
|
* Pure C11, stdlib + libm only. The descriptor is a foundation object; it is NOT
|
|
* wired into retrieval/priming yet (that is the next M9 step).
|
|
*/
|
|
#ifndef ENGRAM_GEOMETRY_H
|
|
#define ENGRAM_GEOMETRY_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include "engram_store.h"
|
|
#include "engram_vindex.h"
|
|
|
|
/* One member of the neighborhood + its place in the gradient. */
|
|
typedef struct {
|
|
char* id;
|
|
double membership; /* soft membership in [0,1] (semantic+relational blend) */
|
|
double centrality; /* skeleton weighted-degree — relational salience */
|
|
double salience; /* the node's own stored salience */
|
|
int core; /* k-core number (0 = fringe / not in any core) */
|
|
double dist_centroid; /* cosine distance of member emb to centroid (semantic)*/
|
|
int embedded; /* 1 if the member carried an emb vector */
|
|
} GeoMember;
|
|
|
|
/* One skeleton edge (indices into members[]). eff_weight = weight*(1+0.5*hebb),
|
|
* clamped to 1.0 — the effective propagation strength eg_edge_eff_weight uses. */
|
|
typedef struct { uint32_t a, b; double eff_weight; double hebb; } GeoEdge;
|
|
|
|
/* A compact principal axis of the ellipsoid: unit direction in R^dim + extent
|
|
* (sqrt of the covariance eigenvalue = the ellipsoid's half-width along it). */
|
|
typedef struct { float* axis; double extent; } GeoAxis;
|
|
|
|
typedef struct {
|
|
int dim;
|
|
/* ── anchor ── */
|
|
char* hub_id; /* highest-centrality member: the relational hub */
|
|
float* centroid; /* v̄ ∈ R^dim: mean of L2-normalized member embs */
|
|
/* ── shape (compact covariance): top principal axes + extents ── */
|
|
int n_axes;
|
|
GeoAxis* axes; /* orientation + extents of the ellipsoid */
|
|
double total_variance; /* trace(Σ) = mean squared member dist to centroid*/
|
|
/* ── scale ── */
|
|
double radius; /* sqrt(total_variance) — the neighborhood breadth*/
|
|
/* ── members + gradient ── */
|
|
int n_members;
|
|
GeoMember* members; /* soft membership {id->weight} + centrality/salience */
|
|
/* ── skeleton ── */
|
|
int n_edges;
|
|
GeoEdge* edges; /* strong internal hebb edges = the backbone */
|
|
int k_core; /* the maximum core number present in the skeleton*/
|
|
/* ── diagnostics ── */
|
|
double co_registration;/* corr(hebb strength, semantic proximity) over */
|
|
/* internal edges: >0 = geometries agree (reify); */
|
|
/* <0 = disagree (surprising links / dream cands). */
|
|
int n_embedded; /* members that carried an emb vector */
|
|
} GeoDescriptor;
|
|
|
|
typedef struct {
|
|
int ann_k; /* semantic expansion: ANN neighbors per seed (0=off) */
|
|
int hop_relational; /* 1 = include seeds' hebb neighbors as members */
|
|
double edge_min_weight; /* skeleton: ignore internal edges below this eff wt */
|
|
int kcore_k; /* target k for the reported k-core (0 = auto/max) */
|
|
int top_axes; /* principal axes to retain (default 8) */
|
|
int max_members; /* cap neighborhood size (guards the eigensolve cost) */
|
|
} GeoParams;
|
|
|
|
/* Fill p with sane defaults: ann_k=24, hop_relational=1, edge_min_weight=0.05,
|
|
* kcore_k=0 (auto), top_axes=8, max_members=400. */
|
|
void engram_geo_default_params(GeoParams* p);
|
|
|
|
/* Compute the geometry descriptor of the neighborhood grown from seed_ids.
|
|
* READ-ONLY over store + vindex.
|
|
* store — an opened store (borrowed; not modified).
|
|
* vindex — optional ANN index for semantic expansion; NULL disables it.
|
|
* vids — the ordinal->store-id map returned by vindex_build_from_store
|
|
* (vids[node_id] == store id). Required iff vindex != NULL.
|
|
* n_vids — length of vids.
|
|
* params — NULL to use engram_geo_default_params.
|
|
* Returns a malloc'd descriptor (free with engram_geo_free), or NULL on error
|
|
* (no seeds resolvable, OOM). */
|
|
GeoDescriptor* engram_geometry_descriptor(
|
|
EngramPagedStore* store, VIndex* vindex,
|
|
char** vids, int n_vids,
|
|
const char* const* seed_ids, size_t n_seeds,
|
|
const GeoParams* params);
|
|
|
|
void engram_geo_free(GeoDescriptor* g);
|
|
|
|
#endif /* ENGRAM_GEOMETRY_H */
|