예제 #1
0
 /// <summary>
 /// Element-wise multiplication of two vectors.
 /// Identical to MATLAB's '.*' operator.
 /// Requires: rv1.Dimension == v2.Dimension
 /// </summary>
 /// <param name="cv1">The first operand.</param>
 /// <param name="v2">The second operand.</param>
 /// <returns>A vector in which each element is the product
 /// of the corresponding elements in cv1, cv2.</returns>
 public static ColumnVector ewMultiply(this ColumnVector cv1, VectorBase v2)
 {
     return(new ColumnVector(elemWiseMultiply(cv1, v2)));
 }
예제 #2
0
        public void SparseSquareMatrixPotential()
        {
            // An 2D electrostatic boundary value problem in cartesian coordinates
            // A square of length n, with specified constant potentials on each wall
            // Discritized Laplace equation is
            //  u_{x,y-1} + u_{x+1,y} + u_{x,y+1} + u_{x-1,y} - 4 u_{x,y} = 0
            // Number interior points sequentially row-wise i.e. i = x + n * y
            // Points nearest the walls will pick up a boundary value, which because it is not a variable we move to the RHS
            // Points closer to the interior pick up no boundary value, so their RHS is zero

            int n = 100;

            double pn = 0.0; double pe = 1.0; double ps = 0.0; double pw = 1.0;

            SparseSquareMatrix A = new SparseSquareMatrix(n * n);
            ColumnVector       b = new ColumnVector(n * n);

            // set up A and b
            for (int y = 0; y < n; y++)
            {
                for (int x = 0; x < n; x++)
                {
                    int i = x + n * y;
                    // center value
                    A[i, i] = 4.0;
                    // north
                    if (y == 0)
                    {
                        b[i] += pn;
                    }
                    else
                    {
                        int j = x + n * (y - 1);
                        A[i, j] = -1.0;
                    }
                    // east
                    if (x == (n - 1))
                    {
                        b[i] += pe;
                    }
                    else
                    {
                        int j = (x + 1) + n * y;
                        A[i, j] = -1.0;
                    }
                    // south
                    if (y == (n - 1))
                    {
                        b[i] += ps;
                    }
                    else
                    {
                        int j = x + n * (y + 1);
                        A[i, j] = -1.0;
                    }
                    // west
                    if (x == 0)
                    {
                        b[i] += pw;
                    }
                    else
                    {
                        int j = (x - 1) + n * y;
                        A[i, j] = -1.0;
                    }
                }
            }

            ColumnVector u = A.Solve(b);

            for (int y = 0; y < 10; y++)
            {
                for (int x = 0; x < 10; x++)
                {
                    int i = x + n * y;
                    Console.Write("{0} ", u[i]);
                }
                Console.WriteLine();
            }

            Console.WriteLine(PotentialSolution(1, 2, n));
        }
예제 #3
0
        public void BivariatePolynomialRegression()
        {
            // do a set of polynomial regression fits
            // make sure not only that the fit parameters are what they should be, but that their variances/covariances are as claimed

            Random rng = new Random(271828);

            // define logistic parameters
            double[] a = new double[] { 0.0, -1.0, 2.0, -3.0 };

            // keep track of sample of returned a and b fit parameters
            MultivariateSample A = new MultivariateSample(a.Length);

            // also keep track of returned covariance estimates
            // since these vary slightly from fit to fit, we will average them
            SymmetricMatrix C = new SymmetricMatrix(a.Length);

            // also keep track of test statistics
            Sample F = new Sample();

            // do 100 fits
            for (int k = 0; k < 100; k++)
            {
                // we should be able to draw x's from any distribution; noise should be drawn from a normal distribution
                ContinuousDistribution xd = new CauchyDistribution();
                ContinuousDistribution nd = new NormalDistribution(0.0, 4.0);

                // generate a synthetic data set
                BivariateSample s = new BivariateSample();
                for (int j = 0; j < 20; j++)
                {
                    double x = xd.GetRandomValue(rng);
                    double y = nd.GetRandomValue(rng);
                    for (int i = 0; i < a.Length; i++)
                    {
                        y += a[i] * MoreMath.Pow(x, i);
                    }
                    s.Add(x, y);
                }

                // do the regression
                PolynomialRegressionResult r = s.PolynomialRegression(a.Length - 1);

                ColumnVector ps = r.Parameters.Best;
                //Console.WriteLine("{0} {1} {2}", ps[0], ps[1], ps[2]);

                // record best fit parameters
                A.Add(ps);

                // record estimated covariances
                C += r.Parameters.Covariance;

                // record the fit statistic
                F.Add(r.F.Statistic);
                //Console.WriteLine("F={0}", r.GoodnessOfFit.Statistic);
            }

            C = (1.0 / A.Count) * C; // allow matrix division by real numbers

            // check that mean parameter estimates are what they should be: the underlying population parameters
            for (int i = 0; i < A.Dimension; i++)
            {
                Console.WriteLine("{0} {1}", A.Column(i).PopulationMean, a[i]);
                Assert.IsTrue(A.Column(i).PopulationMean.ConfidenceInterval(0.95).ClosedContains(a[i]));
            }

            // check that parameter covarainces are what they should be: the reported covariance estimates
            for (int i = 0; i < A.Dimension; i++)
            {
                for (int j = i; j < A.Dimension; j++)
                {
                    Console.WriteLine("{0} {1} {2} {3}", i, j, C[i, j], A.TwoColumns(i, j).PopulationCovariance);
                    Assert.IsTrue(A.TwoColumns(i, j).PopulationCovariance.ConfidenceInterval(0.95).ClosedContains(C[i, j]));
                }
            }

            // check that F is distributed as it should be
            //Console.WriteLine(fs.KolmogorovSmirnovTest(new FisherDistribution(2, 48)).LeftProbability);
        }
예제 #4
0
        public static void Integration()
        {
            // This is the area of the upper half-circle, so the value should be pi/2.
            IntegrationResult i = FunctionMath.Integrate(x => Math.Sqrt(1.0 - x * x), -1.0, +1.0);

            Console.WriteLine($"i = {i.Estimate} after {i.EvaluationCount} evaluations.");

            Interval          zeroToPi = Interval.FromEndpoints(0.0, Math.PI);
            IntegrationResult watson   = MultiFunctionMath.Integrate(
                x => 1.0 / (1.0 - Math.Cos(x[0]) * Math.Cos(x[1]) * Math.Cos(x[2])),
                new Interval[] { zeroToPi, zeroToPi, zeroToPi }
                );

            IntegrationResult i2 = FunctionMath.Integrate(
                x => Math.Sqrt(1.0 - x * x), -1.0, +1.0,
                new IntegrationSettings()
            {
                RelativePrecision = 1.0E-4
            }
                );

            // This integrand has a log singularity at x = 0.
            // The value of this integral is the Catalan constant.
            IntegrationResult soft = FunctionMath.Integrate(
                x => - Math.Log(x) / (1.0 + x * x), 0.0, 1.0
                );

            // This integral has a power law singularity at x = 0.
            // The value of this integral is 4.
            IntegrationResult hard = FunctionMath.Integrate(
                x => Math.Pow(x, -3.0 / 4.0), 0.0, 1.0,
                new IntegrationSettings()
            {
                RelativePrecision = 1.0E-6
            }
                );

            // The value of this infinite integral is sqrt(pi)
            IntegrationResult infinite = FunctionMath.Integrate(
                x => Math.Exp(-x * x), Double.NegativeInfinity, Double.PositiveInfinity
                );

            Func <IReadOnlyList <double>, double> distance = z => {
                ColumnVector x = new ColumnVector(z[0], z[1], z[2]);
                ColumnVector y = new ColumnVector(z[3], z[4], z[5]);
                ColumnVector d = x - y;
                return(d.Norm());
            };

            Interval oneBox = Interval.FromEndpoints(0.0, 1.0);

            Interval[] sixBox = new Interval[] { oneBox, oneBox, oneBox, oneBox, oneBox, oneBox };

            IntegrationSettings settings = new IntegrationSettings()
            {
                RelativePrecision = 1.0E-4,
                AbsolutePrecision = 0.0,
                Listener          = r => {
                    Console.WriteLine($"Estimate {r.Estimate} after {r.EvaluationCount} evaluations.");
                }
            };

            IntegrationResult numeric = MultiFunctionMath.Integrate(distance, sixBox, settings);

            Console.WriteLine($"The numeric result is {numeric.Estimate}.");

            double analytic = 4.0 / 105.0 + 17.0 / 105.0 * Math.Sqrt(2.0) - 2.0 / 35.0 * Math.Sqrt(3.0)
                              + Math.Log(1.0 + Math.Sqrt(2.0)) / 5.0 + 2.0 / 5.0 * Math.Log(2.0 + Math.Sqrt(3.0))
                              - Math.PI / 15.0;

            Console.WriteLine($"The analytic result is {analytic}.");
        }
예제 #5
0
        public static void Optimization()
        {
            Interval range = Interval.FromEndpoints(0.0, 6.28);
            Extremum min   = FunctionMath.FindMinimum(x => Math.Sin(x), range);

            Console.WriteLine($"Found minimum of {min.Value} at {min.Location}.");
            Console.WriteLine($"Required {min.EvaluationCount} evaluations.");

            MultiExtremum rosenbrock = MultiFunctionMath.FindLocalMinimum(
                x => MoreMath.Sqr(2.0 - x[0]) + 100.0 * MoreMath.Sqr(x[1] - x[0] * x[0]),
                new ColumnVector(0.0, 0.0)
                );
            ColumnVector xm = rosenbrock.Location;

            Console.WriteLine($"Found minimum of {rosenbrock.Value} at ({xm[0]},{xm[1]}).");
            Console.WriteLine($"Required {rosenbrock.EvaluationCount} evaluations.");

            Func <IReadOnlyList <double>, double> leviFunction = z => {
                double x = z[0];
                double y = z[1];
                return(
                    MoreMath.Sqr(MoreMath.Sin(3.0 * Math.PI * x)) +
                    MoreMath.Sqr(x - 1.0) * (1.0 + MoreMath.Sqr(MoreMath.Sin(3.0 * Math.PI * y))) +
                    MoreMath.Sqr(y - 1.0) * (1.0 + MoreMath.Sqr(MoreMath.Sin(2.0 * Math.PI * y)))
                    );
            };

            Interval[] leviRegion = new Interval[] {
                Interval.FromEndpoints(-10.0, +10.0),
                Interval.FromEndpoints(-10.0, +10.0)
            };

            MultiExtremum levi = MultiFunctionMath.FindGlobalMinimum(leviFunction, leviRegion);

            ColumnVector zm = levi.Location;

            Console.WriteLine($"Found minimum of {levi.Value} at ({zm[0]},{zm[1]}).");
            Console.WriteLine($"Required {levi.EvaluationCount} evaluations.");

            // Select a dimension
            int n = 6;

            // Define a function that takes 2n polar coordinates in the form
            // phi_1, theta_1, phi_2, theta_2, ..., phi_n, theta_n, computes
            // the sum of the potential energy 1/d for all pairs.
            Func <IReadOnlyList <double>, double> thompson = (IReadOnlyList <double> v) => {
                double e = 0.0;
                // iterate over all distinct pairs of points
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        // compute the chord length between points i and j
                        double dx = Math.Cos(v[2 * j]) * Math.Cos(v[2 * j + 1]) - Math.Cos(v[2 * i]) * Math.Cos(v[2 * i + 1]);
                        double dy = Math.Cos(v[2 * j]) * Math.Sin(v[2 * j + 1]) - Math.Cos(v[2 * i]) * Math.Sin(v[2 * i + 1]);
                        double dz = Math.Sin(v[2 * j]) - Math.Sin(v[2 * i]);
                        double d  = Math.Sqrt(dx * dx + dy * dy + dz * dz);
                        e += 1.0 / d;
                    }
                }
                return(e);
            };

            // Limit all polar coordinates to their standard ranges.
            Interval[] box = new Interval[2 * n];
            for (int i = 0; i < n; i++)
            {
                box[2 * i]     = Interval.FromEndpoints(-Math.PI, Math.PI);
                box[2 * i + 1] = Interval.FromEndpoints(-Math.PI / 2.0, Math.PI / 2.0);
            }

            // Use settings to monitor proress toward a rough solution.
            MultiExtremumSettings roughSettings = new MultiExtremumSettings()
            {
                RelativePrecision = 0.05, AbsolutePrecision = 0.0,
                Listener          = r => {
                    Console.WriteLine($"Minimum {r.Value} after {r.EvaluationCount} evaluations.");
                }
            };
            MultiExtremum roughThompson = MultiFunctionMath.FindGlobalMinimum(thompson, box, roughSettings);

            // Use settings to monitor proress toward a refined solution.
            MultiExtremumSettings refinedSettings = new MultiExtremumSettings()
            {
                RelativePrecision = 1.0E-5, AbsolutePrecision = 0.0,
                Listener          = r => {
                    Console.WriteLine($"Minimum {r.Value} after {r.EvaluationCount} evaluations.");
                }
            };
            MultiExtremum refinedThompson = MultiFunctionMath.FindLocalMinimum(thompson, roughThompson.Location, refinedSettings);

            Console.WriteLine($"Minimum potential energy {refinedThompson.Value}.");
            Console.WriteLine($"Required {roughThompson.EvaluationCount} + {refinedThompson.EvaluationCount} evaluations.");

            /*
             * // Define a function that takes 2n coordinates x1, y1, x2, y2, ... xn, yn
             * // and finds the smallest distance between two coordinate pairs.
             * Func<IReadOnlyList<double>, double> function = (IReadOnlyList<double> x) => {
             *  double sMin = Double.MaxValue;
             *  for (int i = 0; i < n; i++) {
             *      for (int j = 0; j < i; j++) {
             *          double s = MoreMath.Hypot(x[2 * i] - x[2 * j], x[2 * i + 1] - x[2 * j + 1]);
             *          if (s < sMin) sMin = s;
             *      }
             *  }
             *  return (sMin);
             * };
             *
             * // Limit all coordinates to the unit box.
             * Interval[] box = new Interval[2 * n];
             * for (int i = 0; i < box.Length; i++) box[i] = Interval.FromEndpoints(0.0, 1.0);
             *
             * // Use settings to monitor proress toward a rough solution.
             * MultiExtremumSettings roughSettings = new MultiExtremumSettings() {
             *  RelativePrecision = 1.0E-2, AbsolutePrecision = 0.0,
             *  Listener = r => {
             *      Console.WriteLine($"Minimum {r.Value} after {r.EvaluationCount} evaluations.");
             *  }
             * };
             * MultiExtremum roughMaximum = MultiFunctionMath.FindGlobalMaximum(function, box, roughSettings);
             *
             * // Use settings to monitor proress toward a rough solution.
             * MultiExtremumSettings refinedSettings = new MultiExtremumSettings() {
             *  RelativePrecision = 1.0E-8, AbsolutePrecision = 0.0,
             *  Listener = r => {
             *      Console.WriteLine($"Minimum {r.Value} after {r.EvaluationCount} evaluations.");
             *  }
             * };
             * MultiExtremum refinedMaximum = MultiFunctionMath.FindLocalMaximum(function, roughMaximum.Location, refinedSettings);
             */
        }
예제 #6
0
        /// <summary>
        /// Computes the polynomial of given degree which best fits the data.
        /// </summary>
        /// <param name="m">The degree, which must be non-negative.</param>
        /// <returns>The fit result.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="m"/> is negative.</exception>
        /// <exception cref="InsufficientDataException">There are fewer data points than coefficients to be fit.</exception>
        public PolynomialRegressionResult PolynomialRegression(int m)
        {
            if (m < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(m));
            }

            int n = Count;

            if (n < (m + 1))
            {
                throw new InsufficientDataException();
            }

            // Construct the n X m design matrix X_{ij} = x_{i}^{j}
            RectangularMatrix X = new RectangularMatrix(n, m + 1);
            ColumnVector      y = new ColumnVector(n);

            for (int i = 0; i < n; i++)
            {
                double x = xData[i];
                X[i, 0] = 1.0;
                for (int j = 1; j <= m; j++)
                {
                    X[i, j] = X[i, j - 1] * x;
                }
                y[i] = yData[i];
            }

            // Use X = QR to solve X b = y and compute C
            ColumnVector    b;
            SymmetricMatrix C;

            QRDecomposition.SolveLinearSystem(X, y, out b, out C);

            // Compute residuals
            double       SSR       = 0.0;
            double       SSF       = 0.0;
            ColumnVector yHat      = X * b;
            Sample       residuals = new Sample();

            for (int i = 0; i < n; i++)
            {
                double z = yData[i] - yHat[i];
                residuals.Add(z);
                SSR += z * z;
                SSF += MoreMath.Sqr(yHat[i] - yData.Mean);
            }
            double sigma2 = SSR / (n - (m + 1));

            // Scale up C by \sigma^2
            // (It sure would be great to be able to overload *=.)
            for (int i = 0; i <= m; i++)
            {
                for (int j = i; j <= m; j++)
                {
                    C[i, j] = C[i, j] * sigma2;
                }
            }

            // Compute remaing sums-of-squares
            double SST = yData.Variance * n;

            // Use sums-of-squares to do ANOVA
            AnovaRow          fit      = new AnovaRow(SSF, m);
            AnovaRow          residual = new AnovaRow(SSR, n - (m + 1));
            AnovaRow          total    = new AnovaRow(SST, n - 1);
            OneWayAnovaResult anova    = new OneWayAnovaResult(fit, residual, total);

            string[] names = new string[m + 1];
            names[0] = "1";
            if (m > 0)
            {
                names[1] = "x";
            }
            for (int i = 2; i <= m; i++)
            {
                names[i] = $"x^{i}";
            }
            ParameterCollection parameters = new ParameterCollection(names, b, C);

            return(new PolynomialRegressionResult(parameters, anova, residuals));
        }
예제 #7
0
        public static QuadraticInterpolationModel Construct(double[][] points, double[] values)
        {
            int m = points.Length;
            int d = points[0].Length;

            // find the minimum point, use it as the origin
            int iMin = 0; double fMin = values[0];

            for (int i = 1; i < values.Length; i++)
            {
                if (values[i] < fMin)
                {
                    iMin = i; fMin = values[i];
                }
            }

            SquareMatrix A = new SquareMatrix(m);
            int          c = 0;

            for (int r = 0; r < m; r++)
            {
                A[r, 0] = 1.0;
            }
            for (int i = 0; i < d; i++)
            {
                c++;
                for (int r = 0; r < m; r++)
                {
                    A[r, c] = points[r][i] - points[iMin][i];
                }
            }
            for (int i = 0; i < d; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    c++;
                    for (int r = 0; r < m; r++)
                    {
                        A[r, c] = (points[r][i] - points[iMin][i]) * (points[r][j] - points[iMin][j]);
                    }
                }
            }
            ColumnVector b = new ColumnVector(values);

            SquareQRDecomposition QR = A.QRDecomposition();
            ColumnVector          a  = QR.Solve(b);

            QuadraticInterpolationModel model = new QuadraticInterpolationModel();

            model.d      = d;
            model.origin = points[iMin];
            model.f0     = a[0];
            model.g      = new double[d];
            c            = 0;
            for (int i = 0; i < d; i++)
            {
                c++;
                model.g[i] = a[c];
            }
            model.h = new double[d][];
            for (int i = 0; i < d; i++)
            {
                model.h[i] = new double[d];
            }
            for (int i = 0; i < d; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    c++;
                    if (i == j)
                    {
                        model.h[i][j] = 2.0 * a[c];
                    }
                    else
                    {
                        model.h[i][j] = a[c];
                        model.h[j][i] = a[c];
                    }
                }
            }

            return(model);
        }
        // the internal linear regression routine, which assumes inputs are entirely valid

        private MultiLinearRegressionResult LinearRegression_Internal(int outputIndex)
        {
            // To do a fit, we need more data than parameters.
            if (Count < Dimension)
            {
                throw new InsufficientDataException();
            }

            // Compute the design matrix X.
            int n = Count;
            int m = Dimension;
            RectangularMatrix X = new RectangularMatrix(n, m);
            ColumnVector      y = new ColumnVector(n);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    if (j == outputIndex)
                    {
                        X[i, j] = 1.0;
                    }
                    else
                    {
                        X[i, j] = storage[j][i];
                    }
                }
                y[i] = storage[outputIndex][i];
            }

            // Use X = QR to solve X b = y and compute C.
            ColumnVector    b;
            SymmetricMatrix C;

            QRDecomposition.SolveLinearSystem(X, y, out b, out C);

            // Compute residuals
            double       SSR       = 0.0;
            double       SSF       = 0.0;
            ColumnVector yHat      = X * b;
            Sample       residuals = new Sample();

            for (int i = 0; i < n; i++)
            {
                double z = storage[outputIndex][i] - yHat[i];
                residuals.Add(z);
                SSR += z * z;
                SSF += MoreMath.Sqr(yHat[i] - storage[outputIndex].Mean);
            }
            double sigma2 = SSR / (n - m);


            // Scale up C by \sigma^2
            // (It sure would be great to be able to overload *=.)
            for (int i = 0; i < m; i++)
            {
                for (int j = i; j < m; j++)
                {
                    C[i, j] = C[i, j] * sigma2;
                }
            }

            // Compute remaing sums-of-squares
            double SST = storage[outputIndex].Variance * n;

            // Use sums-of-squares to do ANOVA
            AnovaRow          fit      = new AnovaRow(SSF, m - 1);
            AnovaRow          residual = new AnovaRow(SSR, n - m);
            AnovaRow          total    = new AnovaRow(SST, n - 1);
            OneWayAnovaResult anova    = new OneWayAnovaResult(fit, residual, total);

            string[] names = new string[m];
            for (int j = 0; j < m; j++)
            {
                if (j == outputIndex)
                {
                    names[j] = "Intercept";
                }
                else
                {
                    names[j] = $"[{j}]";
                }
            }
            ParameterCollection parameters = new ParameterCollection(names, b, C);

            return(new MultiLinearRegressionResult(parameters, anova, residuals));
        }
예제 #9
0
        /// <summary>
        /// Computes the best-fit linear regression from the data.
        /// </summary>
        /// <returns>The result of the fit.</returns>
        /// <remarks>
        /// <para>Linear regression assumes that the data have been generated by a function y = a + b x + e, where e is
        /// normally distributed noise, and determines the values of a and b that best fit the data. It also
        /// determines an error matrix on the parameters a and b, and does an F-test to</para>
        /// <para>The fit result is two-dimensional. The first parameter is the intercept a, the second is the slope b.
        /// The goodness-of-fit test is a F-test comparing the variance accounted for by the model to the remaining,
        /// unexplained variance.</para>
        /// </remarks>
        /// <exception cref="InsufficientDataException">There are fewer than three data points.</exception>
        public LinearRegressionResult LinearRegression()
        {
            int n = this.Count;

            if (n < 3)
            {
                throw new InsufficientDataException();
            }

            // The means and covariances are the inputs to most of the regression formulas.
            double mx  = xData.Mean;
            double my  = yData.Mean;
            double cxx = xData.Variance;
            double cyy = yData.Variance;
            double cxy = this.Covariance;

            Debug.Assert(cxx >= 0.0);
            Debug.Assert(cyy >= 0.0);

            // Compute the best-fit parameters
            double b = cxy / cxx;
            double a = my - b * mx;
            // Since cov(x,y) = (n S_xy - S_x S_y)/n^2 and var(x) = (n S_xx - S_x^2) / n^2,
            // these formulas are equivilent to the
            // to the usual formulas for a and b involving sums, but it is more stable against round-off
            ColumnVector v = new ColumnVector(a, b);

            v.IsReadOnly = true;

            // Compute Pearson r value
            double     r     = cxy / Math.Sqrt(cxx * cyy);
            TestResult rTest = new TestResult("r", r, TestType.TwoTailed, new Distributions.PearsonRDistribution(n));

            // Compute residuals and other sum-of-squares
            double SSR       = 0.0;
            double SSF       = 0.0;
            Sample residuals = new Sample();

            foreach (XY point in this)
            {
                double y = a + b * point.X;
                double z = point.Y - y;
                SSR += z * z;
                residuals.Add(z);
                SSF += MoreMath.Sqr(y - my);
            }
            double SST = cyy * n;
            // Note SST = SSF + SSR because \sum_{i} ( y_i - \bar{y})^2 = \sum_i (y_i - f_i)^2 + \sum_i (f_i - \bar{y})^2

            // Use sums-of-squares to do ANOVA
            AnovaRow          fit      = new AnovaRow(SSF, 1);
            AnovaRow          residual = new AnovaRow(SSR, n - 2);
            AnovaRow          total    = new AnovaRow(SST, n - 1);
            OneWayAnovaResult anova    = new OneWayAnovaResult(fit, residual, total);

            // Compute covariance of parameters matrix
            double s2  = SSR / (n - 2);
            double cbb = s2 / cxx / n;
            double cab = -mx * cbb;
            double caa = (cxx + mx * mx) * cbb;

            SymmetricMatrix C = new SymmetricMatrix(2);

            C[0, 0]      = caa;
            C[1, 1]      = cbb;
            C[0, 1]      = cab;
            C.IsReadOnly = true;

            // Package the parameters
            ParameterCollection parameters = new ParameterCollection(
                new string[] { "Intercept", "Slope" }, v, C
                );

            // Prepare the prediction function
            Func <double, UncertainValue> predict = (double x) => {
                double y = a + b * x;
                return(new UncertainValue(y, Math.Sqrt(s2 * (1.0 + (1.0 + MoreMath.Sqr(x - mx) / cxx) / n))));
            };

            return(new LinearRegressionResult(parameters, rTest, anova, residuals, predict));
        }
예제 #10
0
 internal GumbelFit(ColumnVector parameters, SymmetricMatrix covariances, TestResult test) : base(parameters, covariances, test)
 {
     this.distribution = new GumbelDistribution(parameters[0], parameters[1]);
 }
        /// <summary>
        /// 重回帰分析を適用する.
        /// </summary>
        /// <param name="y">出力値のベクトル</param>
        /// <param name="xs">入力ベクトルのセット</param>
        public MultipleLinearRegressionAnalysis(IVector y, IVector[] xs)
        {
            if (y.Size != xs.Length)
            {
                throw new Exception.MismatchSizeException();
            }

            ColumnVector Y = new ColumnVector(y);
            Matrix       X = new Matrix(VectorType.RowVector, xs);
            int          p = X.ColumnSize; // 変数の数

            // 各変数の平均値を算出
            IVector colAvgs = X.ColumnAverages;

            X.Rows.ForEach(delegate(IVector rv)
            {
                rv.ForEach(delegate(int i, ref double val)
                {
                    val -= colAvgs[i];
                });
            });

            // 第1列目に"1"を挿入
            Matrix tmp = new Matrix(X.RowSize, X.ColumnSize + 1);

            for (int r = 0; r < tmp.RowSize; ++r)
            {
                tmp[r, 0] = 1.0;
                for (int c = 1; c < tmp.ColumnSize; ++c)
                {
                    tmp[r, c] = X[r, c - 1];
                }
            }
            X = tmp;

            // 係数の同定
            Matrix  tX   = Matrix.Transpose(X);
            Matrix  itXX = Matrix.Inverse(tX * X);
            IVector C    = itXX * tX * Y;

            // 定数項を求める
            for (int i = 1; i < C.Size; ++i)
            {
                C[0] -= C[i] * colAvgs[i - 1];
            }

            this.coefficients = C;

            // テコ比
            Matrix H = X * itXX * tX;

            this.leverages = new Vector(H.ColumnSize);
            H.Rows.ForEach(delegate(int r, IVector v)
            {
                this.leverages[r] = v[r];
            });

            // 残差ベクトル
            ColumnVector e = Y - H * Y;

            this.residuals = new Vector(e);

            int    phi_t = Y.Size - 1;     // n - 1
            int    phi_e = Y.Size - p - 1; // n - p - 1
            double Se    = e * e;

            this.dofP = p;
            this.dofE = phi_e;

            double y_avg = Y.Average;
            double Syy   = 0.0;

            Y.ForEach(delegate(double val)
            {
                Syy += (val - y_avg) * (val - y_avg);
            });

            // 決定係数
            this.r2 = 1.0 - Se / Syy;

            // 自由度補正済み決定係数
            this.rc2 = 1.0 - (Se / phi_e) / (Syy / phi_t);

            // 各係数のt値
            double  Ve        = Se / phi_e;
            IVector std_coeff = new Vector(this.coefficients.Size);

            std_coeff.ForEach(delegate(int i, ref double val)
            {
                val = Math.Sqrt(Ve * itXX[i, i]);
            }); // Sqrt(Ve/Sxx)
            // まだ,定数項の標準偏差は使えない(Yの平均値のものになっている)

            // 定数項の検定統計量を算出
            double var0 = itXX[0, 0];   // 1/n

            for (int i = 1; i < p + 1; ++i)
            {
                for (int j = 1; j < p + 1; ++j)
                {
                    var0 += colAvgs[i - 1] * colAvgs[j - 1] * itXX[i, j];
                }
            }
            std_coeff[0] = Math.Sqrt(var0 * Ve);

            IVector t = new Vector(std_coeff.Size);

            t.ForEach(delegate(int i, ref double val)
            {
                val = Math.Abs(this.coefficients[i]) / std_coeff[i]; // 帰無仮説はβ=0
            });
            this.ts = t;
        }
        public void MeansClustering2()
        {
            ColumnVector[] centers = new ColumnVector[] {
                new ColumnVector(0.0, 0.0, 0.0),
                new ColumnVector(2.0, 0.0, 0.0),
                new ColumnVector(0.0, 2.0, 0.0),
                new ColumnVector(0.0, 0.0, 2.0)
            };

            FrameTable table    = new FrameTable();
            string     alphabet = "abcdefghijklmnopqrstuvwxyz";

            for (int j = 0; j < 3; j++)
            {
                table.AddColumn <double>(alphabet[j].ToString());
            }


            List <int>          inputAssignments = new List <int>();
            List <ColumnVector> inputVectors     = new List <ColumnVector>();
            Random rng = new Random(2);
            ContinuousDistribution dist = new NormalDistribution(0.0, 1.0);

            for (int i = 0; i < 100; i++)
            {
                int inputAssignment = rng.Next(0, centers.Length);
                inputAssignments.Add(inputAssignment);
                ColumnVector inputVector = centers[inputAssignment].Copy();
                for (int k = 0; k < inputVector.Dimension; k++)
                {
                    inputVector[k] += dist.GetRandomValue(rng);
                }
                inputVectors.Add(inputVector);
                table.AddRow <double>(inputVector);
            }

            MeansClusteringResult result = table.AsColumns <double>().MeansClustering(centers.Length);

            //MultivariateSample s = new MultivariateSample(3);
            //foreach (ColumnVector v in inputVectors) { s.Add(v); }
            //MeansClusteringResult result = s.MeansClustering(centers.Length);

            List <int> outputAssignments = new List <int>();

            for (int i = 0; i < inputVectors.Count; i++)
            {
                int assignment = result.Classify(inputVectors[i]);
                outputAssignments.Add(assignment);
            }

            // Map the output centroids to the original centroids
            Dictionary <int, int> map = new Dictionary <int, int>();

            for (int outputIndex = 0; outputIndex < result.Count; outputIndex++)
            {
                ColumnVector centroid            = result.Centroid(outputIndex);
                int          mappedInputIndex    = -1;
                double       mappedInputDistance = Double.MaxValue;
                for (int inputIndex = 0; inputIndex < centers.Length; inputIndex++)
                {
                    double distance = (centroid - centers[inputIndex]).Norm();
                    if (distance < mappedInputDistance)
                    {
                        mappedInputIndex    = inputIndex;
                        mappedInputDistance = distance;
                    }
                }
                Assert.IsTrue(mappedInputIndex >= 0);
                Assert.IsTrue(mappedInputDistance < 1.0);
                map.Add(outputIndex, mappedInputIndex);
            }

            int correctCount = 0;

            for (int i = 0; i < outputAssignments.Count; i++)
            {
                if (map[outputAssignments[i]] == inputAssignments[i])
                {
                    correctCount++;
                }
            }
            Assert.IsTrue(correctCount >= 0.50 * outputAssignments.Count);
        }
예제 #13
0
파일: DOMethods.cs 프로젝트: formozov/VTS
 private static void PrintMatrix(ColumnVector M)
 {
     PrintMatrix(new RectangularMatrix(M.RowCount, M.ColumnCount));
 }
예제 #14
0
        public void PC()
        {
            Random rng = new Random(1);
            double s   = 1.0 / Math.Sqrt(2.0);

            MultivariateSample MS = new MultivariateSample(2);
            RectangularMatrix  R  = new RectangularMatrix(1000, 2);

            for (int i = 0; i < 1000; i++)
            {
                double r1 = 2.0 * rng.NextDouble() - 1.0;
                double r2 = 2.0 * rng.NextDouble() - 1.0;
                double x  = r1 * 4.0 * s - r2 * 9.0 * s;
                double y  = r1 * 4.0 * s + r2 * 9.0 * s;
                R[i, 0] = x; R[i, 1] = y;
                MS.Add(x, y);
            }

            Console.WriteLine("x {0} {1}", MS.Column(0).Mean, MS.Column(0).Variance);
            Console.WriteLine("y {0} {1}", MS.Column(1).Mean, MS.Column(1).Variance);

            Console.WriteLine("SVD");

            SingularValueDecomposition SVD = R.SingularValueDecomposition();

            for (int i = 0; i < SVD.Dimension; i++)
            {
                Console.WriteLine("{0} {1}", i, SVD.SingularValue(i));
                ColumnVector v = SVD.RightSingularVector(i);
                Console.WriteLine("  {0} {1}", v[0], v[1]);
            }

            Console.WriteLine("PCA");

            PrincipalComponentAnalysis PCA = MS.PrincipalComponentAnalysis();

            Console.WriteLine("Dimension = {0} Count = {1}", PCA.Dimension, PCA.Count);
            for (int i = 0; i < PCA.Dimension; i++)
            {
                PrincipalComponent PC = PCA.Component(i);
                Console.WriteLine("  {0} {1} {2} {3}", PC.Index, PC.Weight, PC.VarianceFraction, PC.CumulativeVarianceFraction);
                RowVector v = PC.NormalizedVector();
                Console.WriteLine("  {0} {1}", v[0], v[1]);
            }

            // reconstruct
            SquareMatrix U  = SVD.LeftTransformMatrix();
            SquareMatrix V  = SVD.RightTransformMatrix();
            double       x1 = U[0, 0] * SVD.SingularValue(0) * V[0, 0] + U[0, 1] * SVD.SingularValue(1) * V[0, 1];

            Console.WriteLine("x1 = {0} {1}", x1, R[0, 0]);
            double y1 = U[0, 0] * SVD.SingularValue(0) * V[1, 0] + U[0, 1] * SVD.SingularValue(1) * V[1, 1];

            Console.WriteLine("y1 = {0} {1}", y1, R[0, 1]);
            double x100 = U[100, 0] * SVD.SingularValue(0) * V[0, 0] + U[100, 1] * SVD.SingularValue(1) * V[0, 1];

            Console.WriteLine("x100 = {0} {1}", x100, R[100, 0]);
            double y100 = U[100, 0] * SVD.SingularValue(0) * V[1, 0] + U[100, 1] * SVD.SingularValue(1) * V[1, 1];

            Console.WriteLine("y100 = {0} {1}", y100, R[100, 1]);

            ColumnVector d1 = U[0, 0] * SVD.SingularValue(0) * SVD.RightSingularVector(0) +
                              U[0, 1] * SVD.SingularValue(1) * SVD.RightSingularVector(1);

            Console.WriteLine("d1 = ({0} {1})", d1[0], d1[1]);
            ColumnVector d100 = U[100, 0] * SVD.SingularValue(0) * SVD.RightSingularVector(0) +
                                U[100, 1] * SVD.SingularValue(1) * SVD.RightSingularVector(1);

            Console.WriteLine("d100 = ({0} {1})", d100[0], d100[1]);

            Console.WriteLine("compare");
            MultivariateSample     RS  = PCA.TransformedSample();
            IEnumerator <double[]> RSE = RS.GetEnumerator();

            RSE.MoveNext();
            double[] dv1 = RSE.Current;
            Console.WriteLine("{0} {1}", dv1[0], dv1[1]);
            Console.WriteLine("{0} {1}", U[0, 0], U[0, 1]);
            RSE.Dispose();
        }