OverviewFilesCommitsIssuesDocsReleasesPeers

basal-agent / src / model.h

44 lines · c ref:
/* model.h — the world model with EMERGENT relations.
 *
 * The model always tracks the two marginals P(class|ext), P(class|dir) and the
 * joint counts. But a *relation* over a specific pair (ext,dir) only "exists" if
 * that pair carries information beyond its parts — measured by the divergence of
 * its joint distribution from the factored marginals (an MI/interaction score).
 *
 *   rel_gain(f0,f1)   = KL( P_joint(class|f0,f1) || P_marginal(class|f0,f1) )   [nats]
 *   rel_emerged(f0,f1)= seen(f0,f1) >= MINOBS  &&  rel_gain >= MI_THRESH
 *
 * Prediction uses the joint iff the relation has emerged, else the marginals.
 * So relations precipitate from data (Linas's connectors forming themselves),
 * rather than being hard-wired as "always ext x dir". */
#ifndef BASAL_MODEL_H
#define BASAL_MODEL_H

#include "sensor.h"

typedef struct {
	double  alpha;
	int     nf0, nf1;
	long   *m0, *s0;     /* marginal ext */
	long   *m1, *s1;     /* marginal dir */
	long   *j,  *sj;     /* joint */
} Rel;

void   rel_init(Rel *r, int nf0, int nf1, double alpha);
void   rel_free(Rel *r);
void   rel_update(Rel *r, int f0, int f1, int klass);

void   pred_ext (const Rel *r, int f0,         double out[NUM_CLASSES]);
void   pred_dir (const Rel *r, int f1,         double out[NUM_CLASSES]);
void   pred_marg(const Rel *r, int f0, int f1, double out[NUM_CLASSES]); /* no relation */
void   pred_rel (const Rel *r, int f0, int f1, double out[NUM_CLASSES]); /* gated by emergence */

double rel_gain   (const Rel *r, int f0, int f1);   /* MI-type score, nats */
int    rel_emerged(const Rel *r, int f0, int f1);   /* has the relation formed? */

int    argmax(const double p[NUM_CLASSES]);
double infogain_pair(const Rel *r, int f0, int f1);
long   pair_seen(const Rel *r, int f0, int f1);

#endif