public CircleFitter2D(IEnumerable<Point3D> initialPoints) { this.points = initialPoints.ToList(); // Compute point centroid Point3D center = Point3D.Centroid(this.points); var distances = from x in this.points select x.DistanceTo(center); double radius = distances.Average(); var solver = new LMSolver(); // Guess for x, y, and r double[] guess = new[] {center.X, center.Y, radius}; var fit = solver.Minimize((p, r) => { // unpack the minimization parameters, x, y, and r double x = p[0]; double y = p[1]; double rad = p[2]; Point3D testCenter = new Point3D(x, y, this.points.First().Z); // compute the residuals for (int i = 0; i < this.points.Count; i++) { r[i] = this.points[i].DistanceTo(testCenter) - rad; } }, guess, this.points.Count); this.CircleCenter = new Point3D(fit.OptimizedParameters[0], fit.OptimizedParameters[1], this.points.First().Z); this.CircleRadius = fit.OptimizedParameters[2]; }
public double[] Solve(IReadOnlyList <EquationNode> nodes, IReadOnlyList <double[]> indices) { var indexList = nodes.FormatIndexList(indices); var solver = new LMSolver(); var optimizationResult = solver.Minimize( (p, r) => { indexList.AsParallel() .Select((x, i) => new { Result = nodes.Calculate(x, p), Row = i }) .ForAll(x => r[x.Row] = x.Result); }, new double[indexList.First().Length], indexList.Count); return(optimizationResult.OptimizedParameters); }
/// <summary> /// Demonstrantes the usage of the generic minimization API /// LMSolver.Minimize /// </summary> static void GenericMinimizationExamples(LMBackend solverType) { var solver = new LMSolver(optimizerBackend: solverType); // grid points var xs = new[] { -1.0, -1.0, 1.0, 1.0 }; var zs = new[] { -1.0, 1.0, -1.0, 1.0 }; // data points/samples var ys = new[] { 0.0, 1.0, 1.0, 2.0 }; // Aim: fit a regression model to the samples // Model: y' = β0 + β1 * x + β2 * z // Regressors: x and z (provided as grid points) // Unknown paramters: β0, β1, β2 // Design matrix X = [1 xs zs] (4x3 matrix) // Parameter vector ε = [β0 β1 β2]^T // Residue: ε = y - y' = y - X β // Find β' = argmin_β sum(ε²) var fit = solver.Minimize((p, r) => { // compute the residue vector ε = y - y' based on the // current parameters p (== β0, β1, β2) var β0 = p[0]; var β1 = p[1]; var β2 = p[2]; for (int i = 0; i < ys.Length; ++i) { r[i] = ys[i] - (β0 + β1 * xs[i] + β2 * zs[i]); } }, new[] { 0.0, 0.0, 0.0 }, // initial guess for β' ys.Length); // number of samples Console.WriteLine(); Console.WriteLine("Aim: fit a linear 2D regression model to four samples"); Console.WriteLine(" Model: y' = β0 + β1 * x + β2 * z"); Console.WriteLine(" Regressors: x and z (grid points)"); Console.WriteLine(" Unknown paramters: β0, β1, β2"); Console.WriteLine(" Design matrix X = [1 xs zs] (4x3 matrix)"); Console.WriteLine(" Parameter vector ε = [β0 β1 β2]^T"); Console.WriteLine(" Residue: ε = y - y' = y - X β"); Console.WriteLine(" Find β' = argmin_β sum(ε²)"); Console.WriteLine("Fit: y' = {0} + {1} x + {2} z", fit.OptimizedParameters[0], fit.OptimizedParameters[1], fit.OptimizedParameters[2]); }