/// <summary>
        ///   Runs the learning algorithm.
        /// </summary>
        ///
        /// <param name="computeError">True to compute error after the training
        /// process completes, false otherwise.</param>
        ///
        public double Run(bool computeError)
        {
            int n = supportVectors.Length;


            // Create Gram matrix
            double[,] K = new double[n, n];
            for (int i = 0; i < supportVectors.Length; i++)
            {
                for (int j = 0; j < supportVectors.Length; j++)
                {
                    K[i, j] = machine.Kernel.Function(supportVectors[i], supportVectors[j]);
                }
            }

            // Reduce to Echelon form to detect linear dependence
            ReducedRowEchelonForm ech = new ReducedRowEchelonForm(K);

            var rref  = ech.Result;
            var pivot = ech.Pivot;


            // For each support vector
            for (int i = 0; i < supportVectors.Length; i++)
            {
                // Get its corresponding row
                int row = ech.Pivot[i];

                // Check if it can be expressed as a
                // linear combination of other vectors

                if (row > supportVectors.Length - ech.FreeVariables - 1)
                {
                    double c = alpha[row];
                    for (int j = 0; j < supportVectors.Length; j++)
                    {
                        alpha[j] = alpha[j] + c * rref[j, row];
                    }

                    alpha[row] = 0;
                }
            }

            // Retain only multipliers which are not zero
            int[] idx = alpha.Find(a => a != 0);
            machine.Weights        = alpha.Submatrix(idx);
            machine.SupportVectors = supportVectors.Submatrix(idx);

            if (computeError)
            {
                return(ComputeError(supportVectors, outputs));
            }

            return(0);
        }
Пример #2
0
        public void ReducedRowEchelonFormConstructorTest()
        {
            double[,] matrix =
            {
                { 1, 2, -3 },
                { 3, 5,  9 },
                { 5, 9,  3 },
            };

            ReducedRowEchelonForm target = new ReducedRowEchelonForm(matrix);

            var actual = target.Result;

            double[,] expected =
            {
                { 1, 0,  33 },
                { 0, 1, -18 },
                { 0, 0,   0 },
            };


            Assert.IsTrue(expected.IsEqual(actual));
        }
Пример #3
0
        public void ReducedRowEchelonFormConstructorTest2()
        {
            double[,] matrix =
            {
                { 3, 2, 2, 3, 1 },
                { 6, 4, 4, 6, 2 },
                { 9, 6, 6, 9, 1 },
            };

            ReducedRowEchelonForm target = new ReducedRowEchelonForm(matrix);

            var actual = target.Result;

            double[,] expected =
            {
                { 1, 2 / 3.0, 2 / 3.0, 1, 0 },
                { 0,       0,       0, 0, 1 },
                { 0,       0,       0, 0, 0 },
            };


            Assert.IsTrue(expected.IsEqual(actual));
        }
Пример #4
0
        private void CubicSplineLinearSystem()
        {
            double[,] matrix_X = new double[pts_.Count + 2, pts_.Count + 3];

            // first n points
            for (int i = 0; i < pts_.Count; ++i)
            {
                for (int j = 0; j < pts_.Count + 2; ++j)
                {
                    if (j <= 3)
                    {
                        matrix_X[i, j] = Math.Pow(i, j);
                    }
                    else
                    {
                        if (i < j - 3)
                        {
                            matrix_X[i, j] = 0;
                        }
                        else
                        {
                            matrix_X[i, j] = Math.Pow(i - (j - 3), 3);
                        }
                    }
                }
            }

            // last 2 points - 2nd derivative of 0 and k
            for (int i = pts_.Count; i < pts_.Count + 2; ++i)
            {
                bool firstLoop = true;
                if (i != pts_.Count)
                {
                    firstLoop = false;
                }

                for (int j = 0; j < pts_.Count + 2; ++j)
                {
                    if (j < 2)
                    {
                        matrix_X[i, j] = 0;
                    }

                    else if (j == 2)
                    {
                        matrix_X[i, j] = 2;
                    }

                    else
                    {
                        int t;
                        if (firstLoop)
                        {
                            t = 0;
                        }
                        else
                        {
                            t = pts_.Count - 1;
                        }

                        if (t < j - 3)
                        {
                            matrix_X[i, j] = 0;
                        }
                        else
                        {
                            matrix_X[i, j] = 6 * (t - (j - 3));
                        }
                    }
                }
            }

            double[,] matrix_Y = new double[pts_.Count + 2, pts_.Count + 3];
            Array.Copy(matrix_X, matrix_Y, (pts_.Count + 2) * (pts_.Count + 3));

            for (int i = 0; i < pts_.Count; ++i)
            {
                matrix_X[i, pts_.Count + 2] = pts_[i].x;
                matrix_Y[i, pts_.Count + 2] = pts_[i].y;
            }

            matrix_X = ReducedRowEchelonForm.calculate(matrix_X);
            matrix_Y = ReducedRowEchelonForm.calculate(matrix_Y);

            CubicSplineCoeff = new Point2D[pts_.Count + 2];

            for (int i = 0; i < pts_.Count + 2; ++i)
            {
                CubicSplineCoeff[i] = new Point2D((float)matrix_X[i, pts_.Count + 2],
                                                  (float)matrix_Y[i, pts_.Count + 2]);
            }
        }