Parameter learning in C#

// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ParameterLearningNonTemporal.cs" company="Bayes Server">
//   Copyright (C) Bayes Server.  All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace BayesServer.HelpSamples
    using System;
    using System.Data.SqlClient;

    using BayesServer.Data;
    using BayesServer.Inference.RelevanceTree;
    using BayesServer.Learning.Parameters;

    public static class ParameterLearningNonTemporal
        public static void Main()
            var network = CreateNetworkStructure();  // we manually construct the network here, but it could be loaded from a file
            var x = network.Variables["X"];
            var y = network.Variables["Y"];

            // now learn the parameters from the data in Walkthrough 2 - Mixture model

            // This example uses Sql Server as the data source and assumes the data has been copied to
            // a table called MixtureModel
            // We will use the RelevanceTree algorithm here, as it is optimized for parameter learning
            var learning = new ParameterLearning(network, new RelevanceTreeInferenceFactory());
            var learningOptions = new ParameterLearningOptions();

            // sql server connection string
            string sqlServer = @"localhost\sqlexpress"; // change this to your sql server instance name
            string database = "BayesServer";    // change this to your database name

            string connectionString = string.Format(
                @"Data Source={0};Initial Catalog={1};Integrated Security=True;", sqlServer, database);

            IDataReaderCommand dataReaderCommand = new DatabaseDataReaderCommand(
                "Select X, Y From MixtureModel");   // note that if a case column was added we would need to ORDER BY the case column here

            bool cacheDataInMemory = true;  // set this to false for large data sets

            if (cacheDataInMemory)
                dataReaderCommand = new DataTableDataReaderCommand(dataReaderCommand.ExecuteReader());

            var readerOptions = new ReaderOptions(null);    // we do not have a case column in this example

            // here we map variables to database columns
            // in this case the variables and database columns have the same name
            var variableReferences = new VariableReference[]
                    new VariableReference(x, ColumnValueType.Value, x.Name),
                    new VariableReference(y, ColumnValueType.Value, y.Name)

            // note that although this example only has non temporal data
            // we could have included additional temporal variables and data

            var evidenceReaderCommand = new EvidenceReaderCommand(

            var result = learning.Learn(evidenceReaderCommand, learningOptions);

            Console.WriteLine("Log likelihood = {0}", result.LogLikelihood.Value);


        private static Network CreateNetworkStructure()
            var network = new Network();

            var nodeCluster = new Node("Cluster", new string[] { "Cluster1", "Cluster2", "Cluster3" });

            var x = new Variable("X", VariableValueType.Continuous);
            var y = new Variable("Y", VariableValueType.Continuous);

            var nodePosition = new Node("Position", new Variable[] { x, y });

            network.Links.Add(new Link(nodeCluster, nodePosition));

            // at this point the Bayesian network structure is fully specified

            return network;