/// <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))); }
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)); }
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); }
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}."); }
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); */ }
/// <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)); }
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)); }
/// <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)); }
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); }
private static void PrintMatrix(ColumnVector M) { PrintMatrix(new RectangularMatrix(M.RowCount, M.ColumnCount)); }
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(); }