*/
const struct GNUNET_CONFIGURATION_Handle *cfg;
+ /*
+ * Number of initial readings to be used for training only
+ */
+ int training_window;
+
+ /*
+ * Number of standard deviations considered within "normal"
+ */
+ int confidence_interval;
+
+};
+
+/*
+ * State of single model instance
+ */
+struct Model
+{
+
+ /*
+ * Pointer to the plugin state
+ */
+ struct Plugin *plugin;
+
+ /*
+ * Number of readings so far
+ */
+ int n;
+
+ /*
+ * Sum of readings
+ */
+ long double sum;
+
+ /*
+ * Sum square of readings
+ */
+ long double sumsq;
+
};
+static void
+update_sums (struct Model *model, double val)
+{
+ model->sum += val;
+ model->sumsq += val * val;
+ model->n ++;
+}
+
+/*
+ * Feed a new value to a model
+ *
+ * @param cls closure (model state)
+ * @param val value to be fed to the model
+ * @return #GNUNET_YES in case of a detected outlier, #GNUNET_NO otherwise
+ */
+static int
+sensor_gaussian_model_feed (void *cls, double val)
+{
+ struct Model *model = cls;
+ struct Plugin *plugin = model->plugin;
+ long double mean;
+ long double stddev;
+ long double allowed_variance;
+
+ if (model->n < plugin->training_window)
+ {
+ update_sums(model, val);
+ return GNUNET_NO;
+ }
+ mean = model->sum / model->n;
+ stddev = sqrt(
+ (model->sumsq - 2 * mean * model->sum + model->n * mean * mean)
+ /
+ (model->n - 1)
+ );
+ allowed_variance = (plugin->confidence_interval * stddev);
+ if ((val < (mean - allowed_variance)) ||
+ (val > (mean + allowed_variance)))
+ return GNUNET_YES;
+ return GNUNET_NO;
+}
+
+/*
+ * Destroy a model instance
+ *
+ * @param cls closure (model state)
+ */
+static void
+sensor_gaussian_model_destroy_model (void *cls)
+{
+ struct Model *model = cls;
+
+ GNUNET_free(model);
+}
+
+/*
+ * Create a model instance
+ *
+ * @param cls closure (plugin state)
+ * @return model state to be used for later calls
+ */
+static void *
+sensor_gaussian_model_create_model (void *cls)
+{
+ struct Plugin *plugin = cls;
+ struct Model *model;
+
+ model = GNUNET_new(struct Model);
+ model->plugin = plugin;
+ return model;
+}
+
/*
* Entry point for the plugin.
*
static struct Plugin plugin;
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct GNUNET_SENSOR_ModelFunctions *api;
+ unsigned long long num;
if (NULL != plugin.cfg)
return NULL; /* can only initialize once! */
memset (&plugin, 0, sizeof (struct Plugin));
plugin.cfg = cfg;
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
+ "sensor-model-gaussian", "TRAINING_WINDOW", &num))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ _("Missing `TRAINING_WINDOW' value in configuration.\n"));
+ return NULL;
+ }
+ plugin.training_window = (int) num;
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
+ "sensor-model-gaussian", "CONFIDENCE_INTERVAL", &num))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ _("Missing `CONFIDENCE_INTERVAL' value in configuration.\n"));
+ return NULL;
+ }
+ plugin.confidence_interval = (int) num;
api = GNUNET_new (struct GNUNET_SENSOR_ModelFunctions);
api->cls = &plugin;
- LOG(GNUNET_ERROR_TYPE_DEBUG, "Guassian model plugin is running\n");
+ api->create_model = &sensor_gaussian_model_create_model;
+ api->destroy_model = &sensor_gaussian_model_destroy_model;
+ api->feed_model = &sensor_gaussian_model_feed;
+ LOG(GNUNET_ERROR_TYPE_DEBUG, "Gaussian model plugin is running.\n");
return api;
}