最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Fitted Lorentzian Curve is upside-down compared to original data - Stack Overflow

programmeradmin4浏览0评论

I am trying to fit a Lorentzian curve on my data in c#. I am using the Math.Net library (version 5.0.0). Unfortunately, the results I get lead to a curve that is upside down compared to the input data.

My input data is:

double[] xData = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0];
double[] yData = [5.1, 5.3, 5.8, 6.0, 5.8, 5.3, 5.1]; 
with initial guesses: [x0Guess: 4.0, AGuess: 5.0, gammaGuess: 2.0]

The code is:

public static Tuple<double, double, double> FitLorentzian(double[] xDataInput, double[] yDataInput, double x0Guess, double AGuess, double gammaGuess)
{
  if (xDataInput.Length != yDataInput.Length || xDataInput.Length < 3)
  {
    throw new ArgumentException("Input data arrays must have the same length and at least 3 points.");
  }

  var xData = new DenseVector(xDataInput);
  var yData = new DenseVector(yDataInput);

  Vector<double> initialGuess = Vector<double>.Build.Dense([x0Guess, AGuess, gammaGuess]);
  IObjectiveModel objective = ObjectiveFunction.NonlinearModel(Model, xData, yData);
  var minimizer = new LevenbergMarquardtMinimizer(initialMu: 0.001, gradientTolerance: 1E-15, stepTolerance: 1E-15, functionTolerance: 1E-15, maximumIterations: 100);
  Vector<double> lowerBound = Vector<double>.Build.Dense([0, 0, 0]);
  NonlinearMinimizationResult optimizationResult = minimizer.FindMinimum(objective, initialGuess, lowerBound);

  if (optimizationResult.ReasonForExit == ExitCondition.Converged || optimizationResult.ReasonForExit == ExitCondition.RelativePoints || optimizationResult.ReasonForExit == ExitCondition.RelativeGradient)
  {
    return Tuple.Create(optimizationResult.MinimizingPoint[0], optimizationResult.MinimizingPoint[1], optimizationResult.MinimizingPoint[2]);
  }
  else
  {
    return Tuple.Create(double.NaN, double.NaN, double.NaN);
  }
}

private static Vector<double> Model(Vector<double> parameters, Vector<double> xData)
{
  double x0 = parameters[0];
  double A = parameters[1];
  double gamma = parameters[2];

  Vector<double> result = CreateVector.Dense<double>(xData.Count);
  for (int i = 0; i < xData.Count; i++)
  {
    result[i] = (A / Math.PI) * (gamma / 2.0) / (Math.Pow(xData[i] - x0, 2) + Math.Pow(gamma / 2.0, 2));
  }
  return result;
}

I am trying to fit a Lorentzian curve on my data in c#. I am using the Math.Net library (version 5.0.0). Unfortunately, the results I get lead to a curve that is upside down compared to the input data.

My input data is:

double[] xData = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0];
double[] yData = [5.1, 5.3, 5.8, 6.0, 5.8, 5.3, 5.1]; 
with initial guesses: [x0Guess: 4.0, AGuess: 5.0, gammaGuess: 2.0]

The code is:

public static Tuple<double, double, double> FitLorentzian(double[] xDataInput, double[] yDataInput, double x0Guess, double AGuess, double gammaGuess)
{
  if (xDataInput.Length != yDataInput.Length || xDataInput.Length < 3)
  {
    throw new ArgumentException("Input data arrays must have the same length and at least 3 points.");
  }

  var xData = new DenseVector(xDataInput);
  var yData = new DenseVector(yDataInput);

  Vector<double> initialGuess = Vector<double>.Build.Dense([x0Guess, AGuess, gammaGuess]);
  IObjectiveModel objective = ObjectiveFunction.NonlinearModel(Model, xData, yData);
  var minimizer = new LevenbergMarquardtMinimizer(initialMu: 0.001, gradientTolerance: 1E-15, stepTolerance: 1E-15, functionTolerance: 1E-15, maximumIterations: 100);
  Vector<double> lowerBound = Vector<double>.Build.Dense([0, 0, 0]);
  NonlinearMinimizationResult optimizationResult = minimizer.FindMinimum(objective, initialGuess, lowerBound);

  if (optimizationResult.ReasonForExit == ExitCondition.Converged || optimizationResult.ReasonForExit == ExitCondition.RelativePoints || optimizationResult.ReasonForExit == ExitCondition.RelativeGradient)
  {
    return Tuple.Create(optimizationResult.MinimizingPoint[0], optimizationResult.MinimizingPoint[1], optimizationResult.MinimizingPoint[2]);
  }
  else
  {
    return Tuple.Create(double.NaN, double.NaN, double.NaN);
  }
}

private static Vector<double> Model(Vector<double> parameters, Vector<double> xData)
{
  double x0 = parameters[0];
  double A = parameters[1];
  double gamma = parameters[2];

  Vector<double> result = CreateVector.Dense<double>(xData.Count);
  for (int i = 0; i < xData.Count; i++)
  {
    result[i] = (A / Math.PI) * (gamma / 2.0) / (Math.Pow(xData[i] - x0, 2) + Math.Pow(gamma / 2.0, 2));
  }
  return result;
}
Share Improve this question asked Mar 31 at 16:12 AlexAlex 511 silver badge6 bronze badges 3
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Bot Commented Mar 31 at 16:13
  • 1 Can you confirm ( i.e. you did check and double check ) that your maths are correct? Is it a sign error somewhere? If so, it wouldn't be a coding problem. – Fildor Commented Mar 31 at 16:38
  • Thanks guys, you were right. The math in my excel sheet was wrong. I added the answer at the bottom. – Alex Commented Apr 1 at 6:48
Add a comment  | 

1 Answer 1

Reset to default 0

Found the issue.. I inserted the y values into the final lorentzian function and plotted this in the excel sheet instead of inserting the x values. Plots look good now.

发布评论

评论列表(0)

  1. 暂无评论