// --------------------------------------------------------------------------------------------------------------------// <copyright file="CLGaussianExample.cs" company="Bayes Server">//   Copyright (C) Bayes Server.  All rights reserved.// </copyright>// --------------------------------------------------------------------------------------------------------------------namespace BayesServer.HelpSamples{    using System;    using BayesServer.Inference.RelevanceTree;    public static class CLGaussianExample    {        public static void Main()        {            // In this example we programatically create a simple Bayesian network            // that has some continuous variables.            // Note that you can automatically define nodes from data using            // classes in BayesServer.Data.Discovery,             // and you can automatically learn the parameters using classes in            // BayesServer.Learning.Parameters,            // however here we build a Bayesian network from scratch.            var network = new Network("Demo");            // add the nodes (variables)            var dFalse = new State("False");            var dTrue = new State("True");            var d = new Variable("D", dFalse, dTrue);            var c1 = new Variable("C1", VariableValueType.Continuous);            var c2 = new Variable("C2", VariableValueType.Continuous);            network.Nodes.Add(new Node(d));            network.Nodes.Add(new Node(c1));            network.Nodes.Add(new Node(c2));            // add some directed links            network.Links.Add(new Link(d.Node, c2.Node));            network.Links.Add(new Link(c1.Node, c2.Node));            // at this point we have fully specified the structural (graphical) specification of the Bayesian Network.            // We must define the necessary probability distributions for each node.            // Each node in a Bayesian Network requires a probability distribution conditioned on it's parents.            // NewDistribution() can be called on a Node to create the appropriate probability distribution for a node            // or it can be created manually.            // The interface IDistribution has been designed to represent both discrete and continuous variables,            var tableD = d.Node.NewDistribution().Table;     // access the table property of the Distribution                       // IMPORTANT            // Note that calling Node.NewDistribution() does NOT assign the distribution to the node.            // A distribution cannot be assigned to a node until it is correctly specified.            // If a distribution becomes invalid  (e.g. a parent node is added), it is automatically set to null.            tableD[dFalse] = 0.2;            tableD[dTrue] = 0.8;            // now tableD is correctly specified we can assign it to Node D;            d.Node.Distribution = tableD;            var gaussianC1 = (CLGaussian)c1.Node.NewDistribution();            gaussianC1.SetMean(c1, 3.5);            gaussianC1.SetVariance(c1, 12.2);            c1.Node.Distribution = gaussianC1;            var clgaussianC2 = (CLGaussian)c2.Node.NewDistribution();            clgaussianC2.SetMean(c2, 22.2, dFalse);            clgaussianC2.SetMean(c2, 54.6, dTrue);            clgaussianC2.SetVariance(c2, 14.6, dFalse);            clgaussianC2.SetVariance(c2, 3.2, dTrue);            clgaussianC2.SetWeight(c2, c1, 1.2, dFalse);            clgaussianC2.SetWeight(c2, c1, -2.1, dTrue);            c2.Node.Distribution = clgaussianC2;            // The network is now fully specified            // If required the network can be saved...            if (false)   // change this to true to save the network            {                // network.Save("fileName.bayes");  // replace 'fileName.bayes' with your own path and uncomment start of line            }            // Now we will calculate P(C2|C1=4)            // use the factory design pattern to create the necessary inference related objects            var factory = new RelevanceTreeInferenceFactory();            var inference = factory.CreateInferenceEngine(network);            var queryOptions = factory.CreateQueryOptions();            var queryOutput = factory.CreateQueryOutput();            inference.Evidence.Set(c1, 4.0);    // set c1 = 4            var queryC2 = new CLGaussian(c2);            inference.QueryDistributions.Add(queryC2);            inference.Query(queryOptions, queryOutput); // note that this can raise an exception (see help for details)            Console.WriteLine("P(C2|C1=4) = (mean " + queryC2.GetMean(c2) + ", variance " + queryC2.GetVariance(c2) + ")");            // Expected output ...            // P(C2|C1=4) = (mean 42.36, variance 64.46240000000002)            // Note that we could also calculate other queries such as P(C1,C2|D=True) or P(C2|C1,D=True) or P(C2,D|C1=4), etc...        }    }}