public void PollutionWithWeights() { var obj = ObjectiveFunction.NonlinearModel(PollutionModel, PollutionX, PollutionY, PollutionW, accuracyOrder: 6); var solver = new LevenbergMarquardtMinimizer(); var result = solver.FindMinimum(obj, PollutionStart); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(PollutionBest[i], result.MinimizingPoint[i], 4); } }
public void Thurber_TRNCG_Dif() { var obj = ObjectiveFunction.NonlinearModel(ThurberModel, ThurberX, ThurberY, accuracyOrder: 6); var solver = new TrustRegionNewtonCGMinimizer(); var result = solver.FindMinimum(obj, ThurberStart, scales: ThurberScales); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(ThurberPbest[i], result.MinimizingPoint[i], 3); AssertHelpers.AlmostEqualRelative(ThurberPstd[i], result.StandardErrors[i], 3); } }
public void BoxBod_TRNCG_Dif() { var obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodX, BoxBodY, accuracyOrder: 6); var solver = new TrustRegionNewtonCGMinimizer(); var result = solver.FindMinimum(obj, BoxBodStart2); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 3); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 3); } }
public void Thurber_LM_Dif() { var obj = ObjectiveFunction.NonlinearModel(ThurberModel, ThurberX, ThurberY, accuracyOrder: 6); var solver = new LevenbergMarquardtMinimizer(); var result = solver.FindMinimum(obj, ThurberStart); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(ThurberPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(ThurberPstd[i], result.StandardErrors[i], 6); } }
public void Rat43_TRDL_Dif() { var obj = ObjectiveFunction.NonlinearModel(Rat43Model, Rat43X, Rat43Y, accuracyOrder: 6); var solver = new TrustRegionDogLegMinimizer(); var result = solver.FindMinimum(obj, Rat43Start2); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(Rat43Pbest[i], result.MinimizingPoint[i], 2); AssertHelpers.AlmostEqualRelative(Rat43Pstd[i], result.StandardErrors[i], 2); } }
//public static void SpecTest(double[] realY, int begin, double ctrd, double fwhm) public static void SpecTest(Sample sample) { Console.WriteLine($"------ Testing with real spectrum: {sample.description}, PeakWidth={sample.spectrum.Length} ------"); //prepare data double[] realX = new double[sample.spectrum.Length]; double max = double.MinValue; int maxPos = 0; for (int i = 0; i < realX.Length; i++) { realX[i] = sample.binOffset + i + 0.5; if (sample.spectrum[i] > max) //find max value and position for initial guess. { max = sample.spectrum[i]; maxPos = (int)realX[i]; } } Vector <double> XValues = new DenseVector(realX); Vector <double> YValues = new DenseVector(sample.spectrum); Vector <double> initGuess = new DenseVector(new double[] { 0, max, maxPos, 8 }); Console.WriteLine("initial guess is: {0}", ToTokenSeparatedString <double>(initGuess, ", ")); var watch = System.Diagnostics.Stopwatch.StartNew(); var obj = ObjectiveFunction.NonlinearModel(GaussianFunc, GaussianPrime, XValues, YValues); var solver = new LevenbergMarquardtMinimizer(); var result = solver.FindMinimum(obj, initGuess); watch.Stop(); Console.WriteLine($"Algorithm takes: {watch.ElapsedTicks} ticks {watch.ElapsedTicks*1000.0d/System.Diagnostics.Stopwatch.Frequency:F3} ms; " + $"exit={result.ReasonForExit}; iterations={result.Iterations}"); Console.WriteLine("results are : {0}", ToTokenSeparatedString <double>(result.MinimizingPoint, ", ")); Console.WriteLine("StdErrors are : {0}", ToTokenSeparatedString <double>(result.StandardErrors, ", ")); //Console.WriteLine("MinimizedValues : {0}", ToTokenSeparatedString<double>(result.MinimizedValues, ", ")); Console.WriteLine("chi-square : {0}", chisquare(YValues, result.MinimizedValues)); const double ratio = 2.35482; // fwhm = 2*sqrt(2*ln(2))*a3 = 2.35482*a3 Console.WriteLine("Math.NET result: Ctrd = {0,8:N2}, FWHM = {1,8:N2}", result.MinimizingPoint[2], result.MinimizingPoint[3] * ratio); Console.WriteLine("WinISA NR result: Ctrd = {0,8:N2}, FWHM = {1,8:N2}", sample.ctrd, sample.fwhm); }
public void Rosenbrock_LM_Dif() { // unconstrained var obj = ObjectiveFunction.NonlinearModel(RosenbrockModel, RosenbrockX, RosenbrockY, accuracyOrder: 2); var solver = new LevenbergMarquardtMinimizer(maximumIterations: 10000); var result = solver.FindMinimum(obj, RosenbrockStart1); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(RosenbrockPbest[i], result.MinimizingPoint[i], 2); } // box constrained obj = ObjectiveFunction.NonlinearModel(RosenbrockModel, RosenbrockX, RosenbrockY, accuracyOrder: 6); solver = new LevenbergMarquardtMinimizer(maximumIterations: 10000); result = solver.FindMinimum(obj, RosenbrockStart1, lowerBound: RosebbrockLowerBound, upperBound: RosenbrockUpperBound); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(RosenbrockPbest[i], result.MinimizingPoint[i], 2); } }
public void BoxBod_LM_Dif() { // unconstrained var obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodX, BoxBodY, accuracyOrder: 6); var solver = new LevenbergMarquardtMinimizer(); var result = solver.FindMinimum(obj, BoxBodStart1); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } // box constrained obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodX, BoxBodY, accuracyOrder: 6); solver = new LevenbergMarquardtMinimizer(); result = solver.FindMinimum(obj, BoxBodStart1, lowerBound: BoxBodLowerBound, upperBound: BoxBodUpperBound); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } }
internal static double Fit(IEnumerable <GeoPoint2D> points, ref GeoPoint2D center2d, ref double radius) { GeoPoint2D[] pnts = null; if (points is GeoPoint2D[] a) { pnts = a; } else if (points is List <GeoPoint2D> l) { pnts = l.ToArray(); } else { List <GeoPoint2D> lp = new List <GeoPoint2D>(); foreach (GeoPoint2D point2D in points) { lp.Add(point2D); } pnts = lp.ToArray(); } Vector <double> observedX = new DenseVector(pnts.Length); // there is no need to set values Vector <double> observedY = new DenseVector(pnts.Length); // this is the data we want to achieve, namely 0.0 LevenbergMarquardtMinimizer lm = new LevenbergMarquardtMinimizer(gradientTolerance: 1e-12, maximumIterations: 20); IObjectiveModel iom = ObjectiveFunction.NonlinearModel( new Func <Vector <double>, Vector <double>, Vector <double> >(delegate(Vector <double> vd, Vector <double> ox) // function { // parameters: 0:cx, 1:cy, 3: radius GeoPoint2D cnt = new GeoPoint2D(vd[0], vd[1]); DenseVector res = new DenseVector(pnts.Length); for (int i = 0; i < pnts.Length; i++) { res[i] = (pnts[i] | cnt) - vd[2]; } #if DEBUG double err = 0.0; for (int i = 0; i < pnts.Length; i++) { err += res[i] * res[i]; } #endif return(res); }), new Func <Vector <double>, Vector <double>, Matrix <double> >(delegate(Vector <double> vd, Vector <double> ox) // derivatives { // parameters: 0:cx, 1:cy, 3: radius GeoPoint2D cnt = new GeoPoint2D(vd[0], vd[1]); var prime = new DenseMatrix(pnts.Length, 3); for (int i = 0; i < pnts.Length; i++) { double d = pnts[i] | cnt; prime[i, 0] = -(pnts[i].x - vd[0]) / d; prime[i, 1] = -(pnts[i].y - vd[1]) / d; prime[i, 2] = -1; } return(prime); }), observedX, observedY); NonlinearMinimizationResult mres = lm.FindMinimum(iom, new DenseVector(new double[] { center2d.x, center2d.y, radius })); if (mres.ReasonForExit == ExitCondition.Converged || mres.ReasonForExit == ExitCondition.RelativeGradient) { center2d = new GeoPoint2D(mres.MinimizingPoint[0], mres.MinimizingPoint[1]); radius = mres.MinimizingPoint[2]; double err = 0.0; for (int i = 0; i < pnts.Length; i++) { err += Math.Abs((pnts[i] | center2d) - radius); } return(err); } else { return(double.MaxValue); } }
public void BoxBod_LM_Der() { // unconstrained var obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodPrime, BoxBodX, BoxBodY); var solver = new LevenbergMarquardtMinimizer(); var result = solver.FindMinimum(obj, BoxBodStart1); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } // lower < parameters < upper // Note that in this case, scales have no effect. obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodPrime, BoxBodX, BoxBodY); solver = new LevenbergMarquardtMinimizer(); result = solver.FindMinimum(obj, BoxBodStart1, lowerBound: BoxBodLowerBound, upperBound: BoxBodUpperBound); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } // lower < parameters, no scales obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodPrime, BoxBodX, BoxBodY); solver = new LevenbergMarquardtMinimizer(); result = solver.FindMinimum(obj, BoxBodStart1, lowerBound: BoxBodLowerBound); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } // lower < parameters, scales obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodPrime, BoxBodX, BoxBodY); solver = new LevenbergMarquardtMinimizer(); result = solver.FindMinimum(obj, BoxBodStart1, lowerBound: BoxBodLowerBound, scales: BoxBodScales); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } // parameters < upper, no scales obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodPrime, BoxBodX, BoxBodY); solver = new LevenbergMarquardtMinimizer(); result = solver.FindMinimum(obj, BoxBodStart1, upperBound: BoxBodUpperBound); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } // parameters < upper, scales obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodPrime, BoxBodX, BoxBodY); solver = new LevenbergMarquardtMinimizer(); result = solver.FindMinimum(obj, BoxBodStart1, upperBound: BoxBodUpperBound, scales: BoxBodScales); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } // only scales obj = ObjectiveFunction.NonlinearModel(BoxBodModel, BoxBodPrime, BoxBodX, BoxBodY); solver = new LevenbergMarquardtMinimizer(); result = solver.FindMinimum(obj, BoxBodStart1, scales: BoxBodScales); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(BoxBodPbest[i], result.MinimizingPoint[i], 6); AssertHelpers.AlmostEqualRelative(BoxBodPstd[i], result.StandardErrors[i], 6); } }
public static Ellipse2D FromPoints(IEnumerable <GeoPoint2D> points) { GeoPoint2D[] pnts = null; if (points is GeoPoint2D[] a) { pnts = a; } else if (points is List <GeoPoint2D> l) { pnts = l.ToArray(); } else { List <GeoPoint2D> lp = new List <GeoPoint2D>(); foreach (GeoPoint2D point2D in points) { lp.Add(point2D); } pnts = lp.ToArray(); } Vector <double> observedX = new DenseVector(pnts.Length + 1); // there is no need to set values Vector <double> observedY = new DenseVector(pnts.Length + 1); // this is the data we want to achieve, namely 1.0, points on the unit circle distance to origin for (int i = 0; i < observedY.Count; i++) { observedY[i] = 1; } observedY[pnts.Length] = 0; // the scalar product of minor and major axis LevenbergMarquardtMinimizer lm = new LevenbergMarquardtMinimizer(gradientTolerance: 1e-12, maximumIterations: 20); IObjectiveModel iom = ObjectiveFunction.NonlinearModel( new Func <Vector <double>, Vector <double>, Vector <double> >(delegate(Vector <double> vd, Vector <double> ox) // function { // parameters: the homogeneous matrix that projects the ellipse to the unit circle ModOp2D m = new ModOp2D(vd[0], vd[1], vd[2], vd[3], vd[4], vd[5]); DenseVector res = new DenseVector(pnts.Length + 1); for (int i = 0; i < pnts.Length; i++) { GeoPoint2D pp = m * pnts[i]; res[i] = pp.x * pp.x + pp.y * pp.y; } res[pnts.Length] = m[0, 0] * m[0, 1] + m[1, 0] * m[1, 1]; // the axis should be perpendicular #if DEBUG double err = 0.0; for (int i = 0; i < pnts.Length; i++) { err += (res[i] - 1) * (res[i] - 1); } err += res[pnts.Length] * res[pnts.Length]; #endif return(res); }), new Func <Vector <double>, Vector <double>, Matrix <double> >(delegate(Vector <double> vd, Vector <double> ox) // derivatives { // parameters: the homogeneous matrix that projects the ellipse to the unit circle ModOp2D m = new ModOp2D(vd[0], vd[1], vd[2], vd[3], vd[4], vd[5]); var prime = new DenseMatrix(pnts.Length + 1, 6); for (int i = 0; i < pnts.Length; i++) { GeoPoint2D pp = m * pnts[i]; prime[i, 0] = 2 * pnts[i].x * pp.x; prime[i, 1] = 2 * pnts[i].y * pp.x; prime[i, 2] = 2 * pp.x; prime[i, 3] = 2 * pnts[i].x * pp.y; prime[i, 4] = 2 * pnts[i].y * pp.y; prime[i, 5] = 2 * pp.y; } prime[pnts.Length, 0] = m[0, 1]; prime[pnts.Length, 1] = m[0, 0]; prime[pnts.Length, 2] = 0; prime[pnts.Length, 3] = m[1, 1]; prime[pnts.Length, 4] = m[1, 0]; prime[pnts.Length, 5] = 0; return(prime); }), observedX, observedY); BoundingRect ext = new BoundingRect(pnts); NonlinearMinimizationResult mres = lm.FindMinimum(iom, new DenseVector(new double[] { 2.0 / ext.Width, 0, -ext.GetCenter().x, 0, 2.0 / ext.Height, -ext.GetCenter().y })); if (mres.ReasonForExit == ExitCondition.Converged || mres.ReasonForExit == ExitCondition.RelativeGradient) { Vector <double> vd = mres.MinimizingPoint; ModOp2D m = new ModOp2D(vd[0], vd[1], vd[2], vd[3], vd[4], vd[5]); m = m.GetInverse(); return(new Ellipse2D(m * GeoPoint2D.Origin, m * GeoVector2D.XAxis, m * GeoVector2D.YAxis)); } else { return(null); } }