public void gh_937()
        {
            #region doc_learn_database
            // Note: this example uses a System.Data.DataTable to represent input data,
            // but note that this is not required. The data could have been represented
            // as jagged double matrices (double[][]) directly.

            // If you have to handle heterogeneus data in your application, such as user records
            // in a database, this data is best represented within the framework using a .NET's
            // DataTable object. In order to try to learn a classification or regression model
            // using this datatable, first we will need to convert the table into a representation
            // that the machine learning model can understand. Such representation is quite often,
            // a matrix of doubles (double[][]).
            var data = new DataTable("Customer Revenue Example");

            data.Columns.Add("Day", "CustomerId", "Time (hour)", "Weather", "Revenue");
            data.Rows.Add("D1", 0, 8, "Sunny", 101.2);
            data.Rows.Add("D2", 1, 10, "Sunny", 24.1);
            data.Rows.Add("D3", 2, 10, "Rain", 107);
            data.Rows.Add("D4", 3, 16, "Rain", 223);
            data.Rows.Add("D5", 4, 15, "Rain", 1);
            data.Rows.Add("D6", 5, 20, "Rain", 42);
            data.Rows.Add("D7", 6, 12, "Cloudy", 123);
            data.Rows.Add("D8", 7, 12, "Sunny", 64);

            // One way to perform this conversion is by using a Codification filter. The Codification
            // filter can take care of converting variables that actually denote symbols (i.e. the
            // weather in the example above) into representations that make more sense given the assumption
            // of a real vector-based classifier.

            // Create a codification codebook
            var codebook = new Codification()
            {
                { "Weather", CodificationVariable.Categorical },
                { "Time (hour)", CodificationVariable.Continuous },
                { "Revenue", CodificationVariable.Continuous },
            };

            // Learn from the data
            codebook.Learn(data);

            // Now, we will use the codebook to transform the DataTable into double[][] vectors. Due
            // the way the conversion works, we can end up with more columns in your output vectors
            // than the ones started with. If you would like more details about what those columns
            // represent, you can pass then as 'out' parameters in the methods that follow below.
            string[] inputNames;  // (note: if you do not want to run this example yourself, you
            string   outputName;  // can see below the new variable names that will be generated)

            // Now, we can translate our training data into integer symbols using our codebook:
            double[][] inputs  = codebook.Apply(data, "Weather", "Time (hour)").ToJagged(out inputNames);
            double[]   outputs = codebook.Apply(data, "Revenue").ToVector(out outputName);
            // (note: the Apply method transform a DataTable into another DataTable containing the codified
            //  variables. The ToJagged and ToVector methods are then used to transform those tables into
            //  double[][] matrices and double[] vectors, respectively.

            // If we would like to learn a linear regression model for this data, there are two possible
            // ways depending on which aspect of the linear regression we are interested the most. If we
            // are interested in interpreting the linear regression, performing hypothesis tests with the
            // coefficients and performing an actual _linear regression analysis_, then we can use the
            // MultipleLinearRegressionAnalysis class for this. If however we are only interested in using
            // the learned model directly to predict new values for the dataset, then we could be using the
            // MultipleLinearRegression and OrdinaryLeastSquares classes directly instead.

            // This example deals with the former case. For the later, please see the documentation page
            // for the MultipleLinearRegression class.

            // We can create a new multiple linear analysis for the variables
            var mlra = new MultipleLinearRegressionAnalysis(intercept: true)
            {
                // We can also inform the names of the new variables that have been created by the
                // codification filter. Those can help in the visualizing the analysis once it is
                // data-bound to a visual control such a Windows.Forms.DataGridView or WPF DataGrid:

                Inputs = inputNames, // will be { "Weather: Sunny", "Weather: Rain, "Weather: Cloudy", "Time (hours)" }
                Output = outputName  // will be "Revenue"
            };

            // To overcome linear dependency errors
            mlra.OrdinaryLeastSquares.IsRobust = true;

            // Compute the analysis and obtain the estimated regression
            MultipleLinearRegression regression = mlra.Learn(inputs, outputs);

            // And then predict the label using
            double predicted = mlra.Transform(inputs[0]); // result will be ~72.3

            // Because we opted for doing a MultipleLinearRegressionAnalysis instead of a simple
            // linear regression, we will have further information about the regression available:
            int    inputCount       = mlra.NumberOfInputs;    // should be 4
            int    outputCount      = mlra.NumberOfOutputs;   // should be 1
            double r2               = mlra.RSquared;          // should be 0.12801838425195311
            AnovaSourceCollection a = mlra.Table;             // ANOVA table (bind to a visual control for quick inspection)
            double[][]            h = mlra.InformationMatrix; // should contain Fisher's information matrix for the problem
            ZTest z = mlra.ZTest;                             // should be 0 (p=0.999, non-significant)
            #endregion

            Assert.AreEqual(72.279574468085144d, predicted, 1e-8);
            Assert.AreEqual(4, inputCount, 1e-8);
            Assert.AreEqual(1, outputCount, 1e-8);
            Assert.AreEqual(0.12801838425195311, r2, 1e-8);
            Assert.AreEqual(0.11010987669344097, a[0].Statistic, 1e-8);

            string     str       = h.ToCSharp();
            double[][] expectedH = new double[][]
            {
                new double[] { 0.442293243337911, -0.069833718526197, -0.228692384542512, -0.0141758263063635, 0.143767140269202 },
                new double[] { -0.0698337185261971, 0.717811616891116, -0.112258662892007, -0.0655549422852099, 0.535719235472913 },
                new double[] { -0.228692384542512, -0.112258662892007, 0.717434922237013, -0.0232803210243207, 0.376483874802496 },
                new double[] { -0.0141758263063635, -0.0655549422852099, -0.0232803210243207, 0.0370082984668314, -0.103011089615894 },
                new double[] { 0.143767140269202, 0.535719235472913, 0.376483874802496, -0.103011089615894, 1.05597025054461 }
            };

            Assert.IsTrue(expectedH.IsEqual(h, 1e-8));
            Assert.AreEqual(0, z.Statistic, 1e-8);
            Assert.AreEqual(1, z.PValue, 1e-8);
        }
        public void RegressTest7()
        {
            double[][] example2 =
            {
                new double[] { -0.47, 1.16, -1.25 },
                new double[] {  0.55, 1.15, -0.78 },
                new double[] {  1.38, 0.63, -0.84 },
                new double[] {  0.99, 0.63, -0.81 },
                new double[] {  1.72, 0.62, -1.59 },
                new double[] {  1.05, 0.62, -1.05 },
                new double[] { -0.51, 0.62, -0.98 },
                new double[] {  1.83, 0.61,  0.86 },
                new double[] {  1.16, 0.61,  0.15 },
                new double[] {  0.59, 0.61, -0.28 },
                new double[] {  0.40, 0.60, -0.30 },
                new double[] {  0.48, 0.60, -0.41 },
                new double[] {  1.28, 0.53, -0.31 },
                new double[] {  0.36, 0.53, -0.41 },
                new double[] {  0.93, 0.16, -0.19 },
                new double[] { -0.61, 0.16, -0.32 },
                new double[] { -0.58, 0.16, -0.01 },
                new double[] {  0.53, 0.16, -0.13 },
                new double[] {  1.48, 0.16,  1.12 },
                new double[] { -0.34, 0.15, -0.10 },
                new double[] {  0.81, 0.15,  0.14 },
                new double[] {  0.85, 0.15, -0.02 },
                new double[] {  0.69, 0.15, -0.16 },
                new double[] {  0.39, 0.15, -0.33 },
                new double[] {  0.70, 0.00,  2.00 },
                new double[] {  0.25, 0.00, -0.01 },
                new double[] { -0.96, 0.85, -0.19 },
                new double[] {  1.04, 0.84,  0.35 },
                new double[] {  0.30, 0.83,  0.05 },
                new double[] {  0.28, 0.83,  0.84 },
                new double[] {  0.18, 0.82,  0.06 },
                new double[] {  0.49, 0.81,  0.41 },
                new double[] {  0.40, 0.81,  0.50 },
                new double[] {  0.41, 0.80,  0.00 },
                new double[] {  0.06, 0.79,  0.39 },
                new double[] {  0.55, 0.79,  0,55 },
            };


            double[][] inputs = example2.GetColumns(new[] { 1, 2 });
            double[] outputs = example2.GetColumn(0);

            bool thrown = false;

            MultipleLinearRegressionAnalysis target;

            try
            {
                target = new MultipleLinearRegressionAnalysis(inputs, outputs, new string[0], "Test", false);
            }
            catch (ArgumentException) { thrown = true; }

            Assert.IsTrue(thrown);

            target = new MultipleLinearRegressionAnalysis(inputs, outputs, new string[2], "Test", false);

            target.Compute();

            Assert.AreEqual(2, target.NumberOfInputs);
            Assert.AreEqual(1, target.NumberOfOutputs);

            Assert.AreEqual(target.Array, inputs);
            Assert.AreEqual(target.Outputs, outputs);

            Assert.AreEqual(-0.19371930561139417, target.RSquared, 1e-5);
            Assert.AreEqual(-0.26606593019390279, target.RSquareAdjusted, 1e-5);

            Assert.AreEqual(2, target.Table[0].DegreesOfFreedom);
            Assert.AreEqual(33, target.Table[1].DegreesOfFreedom);
            Assert.AreEqual(35, target.Table[2].DegreesOfFreedom);

            Assert.AreEqual(-2.9165797494934651, target.Table[0].SumOfSquares, 1e-10);
            Assert.AreEqual(17.972279749493463, target.Table[1].SumOfSquares, 1e-10);
            Assert.AreEqual(15.055699999999998, target.Table[2].SumOfSquares, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Table[0].SumOfSquares));
            Assert.IsFalse(Double.IsNaN(target.Table[1].SumOfSquares));
            Assert.IsFalse(Double.IsNaN(target.Table[2].SumOfSquares));

            Assert.AreEqual(-1.4582898747467326, target.Table[0].MeanSquares, 1e-10);
            Assert.AreEqual(0.54461453786343827, target.Table[1].MeanSquares, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Table[0].MeanSquares));
            Assert.IsFalse(Double.IsNaN(target.Table[1].MeanSquares));

            Assert.AreEqual(-2.6776550630978524, target.Table[0].Statistic.Value, 1e-10);
            Assert.AreEqual(1, target.Table[0].Significance.PValue, 1e-16);
            Assert.IsFalse(Double.IsNaN(target.Table[0].Significance.PValue));

            Assert.AreEqual(0.72195200211671728, target.Coefficients[0].Value, 1e-10);
            Assert.AreEqual(0.15872233321508125, target.Coefficients[1].Value, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Coefficients[0].Value));
            Assert.IsFalse(Double.IsNaN(target.Coefficients[1].Value));

            Assert.IsFalse(target.Coefficients[0].IsIntercept);
            Assert.IsFalse(target.Coefficients[1].IsIntercept);

            Assert.AreEqual(0.20506051379737225, target.Coefficients[0].StandardError, 1e-10);
            Assert.AreEqual(0.18842330299464302, target.Coefficients[1].StandardError, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Coefficients[0].StandardError));
            Assert.IsFalse(Double.IsNaN(target.Coefficients[1].StandardError));

            Assert.AreEqual(3.5206778172325479, target.Coefficients[0].TTest.Statistic, 1e-10);
            Assert.AreEqual(0.84237103740609942, target.Coefficients[1].TTest.Statistic, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Coefficients[0].TTest.Statistic));
            Assert.IsFalse(Double.IsNaN(target.Coefficients[1].TTest.Statistic));

            DoubleRange range;

            range = target.Coefficients[0].TTest.GetConfidenceInterval(0.9);
            Assert.AreEqual(0.37491572761667513, range.Min, 1e-10);
            Assert.AreEqual(1.0689882766167593, range.Max, 1e-10);

            range = target.Coefficients[1].TTest.GetConfidenceInterval(0.9);
            Assert.AreEqual(-0.16015778606945111, range.Min, 1e-10);
            Assert.AreEqual(0.47760245249961364, range.Max, 1e-10);


            MultipleLinearRegression mlr = new MultipleLinearRegression(2, false);
            mlr.Regress(inputs, outputs);

            Assert.AreEqual(2, target.NumberOfInputs);
            Assert.AreEqual(1, target.NumberOfOutputs);

            double[] actual = target.Transform(inputs);
            double[] expected = mlr.Transform(inputs);
            Assert.IsTrue(Matrix.IsEqual(actual, expected, 1e-8));

            double r2 = mlr.CoefficientOfDetermination(inputs, outputs, false);
            double r2a = mlr.CoefficientOfDetermination(inputs, outputs, true);

            Assert.AreEqual(r2, target.RSquared, 1e-6);
            Assert.AreEqual(r2a, target.RSquareAdjusted, 1e-6);
        }
        public void RegressTest7()
        {
            double[][] example2 =
            {
                new double[] { -0.47, 1.16, -1.25 },
                new double[] {  0.55, 1.15, -0.78 },
                new double[] {  1.38, 0.63, -0.84 },
                new double[] {  0.99, 0.63, -0.81 },
                new double[] {  1.72, 0.62, -1.59 },
                new double[] {  1.05, 0.62, -1.05 },
                new double[] { -0.51, 0.62, -0.98 },
                new double[] {  1.83, 0.61,  0.86 },
                new double[] {  1.16, 0.61,  0.15 },
                new double[] {  0.59, 0.61, -0.28 },
                new double[] {  0.40, 0.60, -0.30 },
                new double[] {  0.48, 0.60, -0.41 },
                new double[] {  1.28, 0.53, -0.31 },
                new double[] {  0.36, 0.53, -0.41 },
                new double[] {  0.93, 0.16, -0.19 },
                new double[] { -0.61, 0.16, -0.32 },
                new double[] { -0.58, 0.16, -0.01 },
                new double[] {  0.53, 0.16, -0.13 },
                new double[] {  1.48, 0.16,  1.12 },
                new double[] { -0.34, 0.15, -0.10 },
                new double[] {  0.81, 0.15,  0.14 },
                new double[] {  0.85, 0.15, -0.02 },
                new double[] {  0.69, 0.15, -0.16 },
                new double[] {  0.39, 0.15, -0.33 },
                new double[] {  0.70, 0.00,  2.00 },
                new double[] {  0.25, 0.00, -0.01 },
                new double[] { -0.96, 0.85, -0.19 },
                new double[] {  1.04, 0.84,  0.35 },
                new double[] {  0.30, 0.83,  0.05 },
                new double[] {  0.28, 0.83,  0.84 },
                new double[] {  0.18, 0.82,  0.06 },
                new double[] {  0.49, 0.81,  0.41 },
                new double[] {  0.40, 0.81,  0.50 },
                new double[] {  0.41, 0.80,  0.00 },
                new double[] {  0.06, 0.79,  0.39 },
                new double[] {  0.55, 0.79, 0, 55 },
            };


            double[][] inputs  = example2.GetColumns(new[] { 1, 2 });
            double[]   outputs = example2.GetColumn(0);

            bool thrown = false;

            MultipleLinearRegressionAnalysis target;

            try
            {
                target = new MultipleLinearRegressionAnalysis(inputs, outputs, new string[0], "Test", false);
            }
            catch (ArgumentException) { thrown = true; }

            Assert.IsTrue(thrown);

            target = new MultipleLinearRegressionAnalysis(inputs, outputs, new string[2], "Test", false);

            target.Compute();

            Assert.AreEqual(2, target.NumberOfInputs);
            Assert.AreEqual(1, target.NumberOfOutputs);

            Assert.AreEqual(target.Array, inputs);
            Assert.AreEqual(target.Outputs, outputs);

            Assert.AreEqual(-0.19371930561139417, target.RSquared, 1e-5);
            Assert.AreEqual(-0.26606593019390279, target.RSquareAdjusted, 1e-5);

            Assert.AreEqual(2, target.Table[0].DegreesOfFreedom);
            Assert.AreEqual(33, target.Table[1].DegreesOfFreedom);
            Assert.AreEqual(35, target.Table[2].DegreesOfFreedom);

            Assert.AreEqual(-2.9165797494934651, target.Table[0].SumOfSquares, 1e-10);
            Assert.AreEqual(17.972279749493463, target.Table[1].SumOfSquares, 1e-10);
            Assert.AreEqual(15.055699999999998, target.Table[2].SumOfSquares, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Table[0].SumOfSquares));
            Assert.IsFalse(Double.IsNaN(target.Table[1].SumOfSquares));
            Assert.IsFalse(Double.IsNaN(target.Table[2].SumOfSquares));

            Assert.AreEqual(-1.4582898747467326, target.Table[0].MeanSquares, 1e-10);
            Assert.AreEqual(0.54461453786343827, target.Table[1].MeanSquares, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Table[0].MeanSquares));
            Assert.IsFalse(Double.IsNaN(target.Table[1].MeanSquares));

            Assert.AreEqual(-2.6776550630978524, target.Table[0].Statistic.Value, 1e-10);
            Assert.AreEqual(1, target.Table[0].Significance.PValue, 1e-16);
            Assert.IsFalse(Double.IsNaN(target.Table[0].Significance.PValue));

            Assert.AreEqual(0.72195200211671728, target.Coefficients[0].Value, 1e-10);
            Assert.AreEqual(0.15872233321508125, target.Coefficients[1].Value, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Coefficients[0].Value));
            Assert.IsFalse(Double.IsNaN(target.Coefficients[1].Value));

            Assert.IsFalse(target.Coefficients[0].IsIntercept);
            Assert.IsFalse(target.Coefficients[1].IsIntercept);

            Assert.AreEqual(0.20506051379737225, target.Coefficients[0].StandardError, 1e-10);
            Assert.AreEqual(0.18842330299464302, target.Coefficients[1].StandardError, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Coefficients[0].StandardError));
            Assert.IsFalse(Double.IsNaN(target.Coefficients[1].StandardError));

            Assert.AreEqual(3.5206778172325479, target.Coefficients[0].TTest.Statistic, 1e-10);
            Assert.AreEqual(0.84237103740609942, target.Coefficients[1].TTest.Statistic, 1e-10);

            Assert.IsFalse(Double.IsNaN(target.Coefficients[0].TTest.Statistic));
            Assert.IsFalse(Double.IsNaN(target.Coefficients[1].TTest.Statistic));

            DoubleRange range;

            range = target.Coefficients[0].TTest.GetConfidenceInterval(0.9);
            Assert.AreEqual(0.37491572761667513, range.Min, 1e-10);
            Assert.AreEqual(1.0689882766167593, range.Max, 1e-10);

            range = target.Coefficients[1].TTest.GetConfidenceInterval(0.9);
            Assert.AreEqual(-0.16015778606945111, range.Min, 1e-10);
            Assert.AreEqual(0.47760245249961364, range.Max, 1e-10);


            MultipleLinearRegression mlr = new MultipleLinearRegression(2, false);

            mlr.Regress(inputs, outputs);

            Assert.AreEqual(2, target.NumberOfInputs);
            Assert.AreEqual(1, target.NumberOfOutputs);

            double[] actual   = target.Transform(inputs);
            double[] expected = mlr.Transform(inputs);
            Assert.IsTrue(Matrix.IsEqual(actual, expected, 1e-8));

            double r2  = mlr.CoefficientOfDetermination(inputs, outputs, false);
            double r2a = mlr.CoefficientOfDetermination(inputs, outputs, true);

            Assert.AreEqual(r2, target.RSquared, 1e-6);
            Assert.AreEqual(r2a, target.RSquareAdjusted, 1e-6);
        }