class BayesianNetwork(StatisticalModel):
    class Meta:
class BayesianNetworkNodeColumn(models.Model):
    class Meta:
class BayesianNetworkNode(models.Model):
    class Meta:
class BayesianNetworkEdge(models.Model):
    BN_TYPE_GENERAL = 0
    BN_TYPE_CLUSTERING = 1
    TYPE_CLUSTERING = BN_TYPE_CLUSTERING
    TYPE_GENERAL = BN_TYPE_GENERAL
    NETWORK_TYPE_CHOICES = (
        (BN_TYPE_GENERAL, "General"),
        (BN_TYPE_CLUSTERING, "Clustering"),
    )
    ACTIONS_KEYWORDS = [":recalculate", ]
                Q = self.get_engine_object(reconstruct=True)
            Q_0 = bp.inference.VB(Z_new, Y_new, *eo.model)
    NODE_TYPE_STOCHASTIC = 0
    NODE_TYPE_DETERMINISTIC = 1
    NODE_TYPE_CHOICES = (
        (NODE_TYPE_STOCHASTIC, "Stochastic"),
        (NODE_TYPE_DETERMINISTIC, "Deterministic"),
    )
    FIELDS_STOCHASTIC = [
        "is_observable", "distribution", "distribution_params",
        "graph_interval"
    ]
    FIELDS_DETERMINISTIC = [
        "deterministic", "deterministic_params"
    ]
        Q = self.network.perform_inference(recalculate=recalculate)
    def __str__(self):
    def save(self, *args, **kwargs):
    def parse_and_run_threshold_actions(self):
    def get_graph(self):
    def get_raw_network_image(self):
    def update_image(self):
    def get_nodes_names(self):
    def get_engine_object(self, reconstruct=False, propagate=True, save=True):
    def perform_inference(self, iters=None, recalculate=False, save=True):
    def reset_engine_object(self, save=True):
    def reset_inference(self, save=True):
    def assign_cluster(self, observation):
    def assign_clusters_labels(self, save=True):
    def columns_names_to_metadata(self, save=True):
    def metadata_update_cluster_sizes(self, save=True):
    def get_results(self):
    def update_eos_struct(eos_struct, node):
    def is_inferred(self):
    def __str__(self):
    def clean(self):
    def parents(self):
    def children(self):
    def clean(self):
    def get_params(self):
    def get_params_type(self):
    def resolve_eos_in_params(self, params=[], kwparams={}, parents={}):
    def get_engine_object(self, parents={}, reconstruct=False, save=True):
    def get_engine_inferred_object(self, recalculate=False, save=True):
    def reset_engine_object(self, save=True):
    def reset_inference(self, save=True):
    def update_image(self):
    def __str__(self):
    def __str__(self):
    def save(self, *args, **kwargs):
def update_bn_image(sender, **kwargs): DIST_GAUSSIAN_ARD = "GaussianARD"  # GaussianARD(mu, alpha[, ndim, shape]) DIST_GAMMA = "Gamma"  # Gamma(a, b, **kwargs) DIST_GAUSSIAN = "Gaussian"  # Gaussian(mu, Lambda, \*\*kwargs) DET_ADD = "Add"  # Add(*nodes, **kwargs) DIST_DIRICHLET = "Dirichlet"  # Dirichlet(*args, **kwargs) DIST_WISHART = "Wishart"  # Wishart(n, V, **kwargs) DIST_CATEGORICAL = "Categorical"  # Categorical(p, **kwargs) DIST_MIXTURE = "Mixture"  # Mixture(z, node_class, *params[, cluster_plat]) def parse_node_args(args_string, flat=False):
    """
    Parses the string intended for Node Initialization
    Based on https://groups.google.com/forum/#!msg/comp.lang.python/vgOWCZ7Z8Yw/ZQgDJfXtCj0J
    """
    LPAR, RPAR, LBRACK, RBRACK, EQ, COMMA = \
        map(pp.Suppress, "()[]=,")

    # Booleans and Keywords
    noneLiteral = pp.Literal("None")
    boolLiteral = pp.oneOf("True False")
    # Scalars
    integer = pp.Combine(pp.Optional(pp.oneOf("+ -")) +
                         pp.Word(pp.nums)).setName("integer")
    real = pp.Combine(pp.Optional(pp.oneOf("+ -")) +
                      pp.Word(pp.nums) + pp.oneOf(". e") +
                      pp.Optional(pp.oneOf("+ -")) +
                      pp.Optional(pp.Word(pp.nums))).setName("real")
    # Identifiers
    identifier = pp.Word(pp.alphas + "_:", pp.alphanums + "_:")
    funStr = pp.Forward().setResultsName("fun")
    # Structures
    listStr = pp.Forward()
    tupleStr = pp.Forward()

    listItem = (real | integer |
                noneLiteral | boolLiteral |
                pp.quotedString.setParseAction(pp.removeQuotes) |
                pp.Group(listStr()) | tupleStr() | identifier)

    funStr << (pp.Optional("@") +
               pp.delimitedList(identifier, delim=".", combine=True) +
               (LPAR + pp.Optional(pp.delimitedList(listItem)) + RPAR))
    listStr << (LBRACK + pp.Optional(pp.delimitedList(listItem)) +
                pp.Optional(COMMA) + RBRACK)
    tupleStr << (LPAR + pp.Optional(pp.delimitedList(listItem)) +
                 pp.Optional(COMMA) + RPAR)
    kwarg = (pp.Group(identifier("kwarg") + EQ +
                      (pp.Group(funStr("fun")) | listItem()
                       ).setResultsName("kwvalue")))

    arg = pp.Group(funStr("fun")) | kwarg("kwarg") | listItem
    args = pp.delimitedList(arg)

    # parse actions perform parse-time conversions
    noneLiteral.setParseAction(lambda: None)
    boolLiteral.setParseAction(lambda toks: toks[0] == "True")
    integer    .setParseAction(lambda toks: int(toks[0]))
    real       .setParseAction(lambda toks: float(toks[0]))
    listStr    .setParseAction(lambda toks: toks.asList())
    tupleStr   .setParseAction(lambda toks: tuple(toks.asList()))
    funStr     .setParseAction(lambda toks: toks.asList())

    parsedArgs = args.parseString(args_string)

    f_args = []
    f_kwargs = {}

    for item in parsedArgs:
        if isinstance(item, pp.ParseResults):
            if 'kwarg' in item:
                if 'fun' in item.kwvalue:
                    kw_value = eval_function(item.kwvalue)
                    f_kwargs[item.kwarg] = kw_value
                else:
                    kw = item.asList()[0]
                    kw_val = item.asList()[1]
                    f_kwargs[kw] = kw_val
            else:
                if 'fun' in item:
                    f_args.append(eval_function(item))
                else:
                    f_args.append(item.asList())
        else:
            # It is one of the "basic objects" and passed as an arg
            f_args.append(item)

    if flat:
        return f_args + list(f_kwargs.values())
    else:
        return({"args": f_args, "kwargs": f_kwargs}) def mahalanobis_distance(x, y, S):
    """
    Returns the Mahalanobis distance between x and y, given the covariance
    matrix S.
    """
    S_inv = np.linalg.inv(S)
    dxy = np.array(x) - np.array(y)
    dist = np.sqrt(np.dot(np.dot(dxy.T, S_inv), dxy))
    return(dist) class UserInfo(models.Model):
class UserInfo2(models.Model):
class MyStatisticalModel(StatisticalModel):
    class Meta:
class MySupervisedLearningTechnique(SupervisedLearningTechnique):
    class Meta:
class MyUnsupervisedLearningTechnique(UnsupervisedLearningTechnique):
    class Meta:
class SpammableModel(IsSpammable):
class MySFPT(SpamFilterPreTraining):
    SEX_CHOICES = ((0, "M"), (1, "F"))
    SPAM_FILTER = "Spam Filter for tests"
    SPAMMABLE_FIELD = "comment"
    def __unicode__(self):
    def __unicode__(self):
import random
import numpy as np
from bayespy.nodes import Gaussian
from django.test import (TestCase, )
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
from django_ai.bayesian_networks import models
from django_ai.bayesian_networks.bayespy_constants import (
    DIST_GAUSSIAN_ARD, DIST_GAMMA, DIST_GAUSSIAN, DET_ADD,
    DIST_DIRICHLET, DIST_WISHART, DIST_CATEGORICAL, DIST_MIXTURE, )
from django_ai.bayesian_networks.utils import (
    parse_node_args, mahalanobis_distance, )
from tests.test_models import models as test_models
            from django_ai.bayesian_networks.utils import \
                parse_node_args as pnn
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
test_django-ai
------------

Tests for `django-ai` models module.
"""


# from django.urls import reverse




class TestBN(TestCase):

    def setUp(self):
        # Set the seeds
        random.seed(123456)
        np.random.seed(123456)
        # Set up the user
        self.user, _ = User.objects.get_or_create(
            username='testadmin', email='testadmin@example.com',
            is_superuser=True
        )
        self.user.set_password("12345")
        self.user.save()
        self.client.login(username='testadmin', password='12345')
        # BN 1
        self.bn1, _ = models.BayesianNetwork.objects.get_or_create(
            name="BN for tests - 1")
        self.mu, _ = models.BayesianNetworkNode.objects.get_or_create(
            network=self.bn1,
            name="mu",
            node_type=models.BayesianNetworkNode.NODE_TYPE_STOCHASTIC,
            is_observable=False,
            distribution=DIST_GAUSSIAN_ARD,
            distribution_params="0, 1e-6",
            graph_interval="-10, 20"
        )
        self.tau, _ = models.BayesianNetworkNode.objects.get_or_create(
            network=self.bn1,
            name="tau",
            node_type=models.BayesianNetworkNode.NODE_TYPE_STOCHASTIC,
            is_observable=False,
            distribution=DIST_GAMMA,
            distribution_params="1e-6, 1e-6",
            graph_interval="1e-6, 0.1"
        )
        self.ui_avg1, _ = models.BayesianNetworkNode.objects.get_or_create(
            network=self.bn1,
            name="userinfo.avg1",
            node_type=models.BayesianNetworkNode.NODE_TYPE_STOCHASTIC,
            is_observable=True,

            distribution=DIST_GAUSSIAN_ARD,