2013-07-11 9 views
1

Я должен соответствовать кривой Гаусса для шумного набора данных, а затем принять его FWHM для определенного приложения. Я использовал MATLAB для демонстрации концепции, а кривая в MATLAB чрезвычайно проста.Гауссовская кривая - оценка параметров - Android/Java

Однако в конечном итоге мне нужно перевести код на Java/Android. Я пробовал искать библиотеки в Android, которые помогли бы мне подогнать гауссову кривую к набору данных, но я ничего не мог найти. Следовательно, я начал изучать всю математику, поэтому я мог бы сделать это вручную.

Мой вопрос: Как мне оценить три параметра (центр, ширина, высота) для одномерной гауссовской модели? Я попытался изучить алгоритм «Ожидание-Максимизация», но это перешло мне на голову.

В целом, я предполагаю, что это будет связано с минимизацией ошибок? У меня просто возникают проблемы с выработкой пошагового метода подбора гауссовой кривой для моих данных.

EDIT:

Одна из вещей, которые я пробовал уже вовлечено принимая естественный журнал моих данных, установку параболы к результату, используя LSQR, а затем преобразования назад. Тем не менее, результаты, которые я получаю, неточны, вероятно, потому, что этот метод так или иначе предвзято.

Если вы не знаете, как выполнить оценку параметров, есть ли у вас какие-либо другие предложения по подгонке кривой к моим данным? (Помните, что это должно быть ручным, так как Android, похоже, довольно ограничен в своих библиотеках статистики)

+0

Это не по теме. SO - это вопросы программирования, а не математические вопросы. Проверьте [MathematicsSE] (http://math.stackexchange.com/). –

+0

Но это вопрос программирования, ха-ха. –

ответ

2

Недавно я сделал аналогичную вещь, используя класс математики Apache Commons, в частности классы Levenberg-Marquardt Optimizer, CurveFitter и GaussianFunction.

Код я использовал, чтобы получить данные готовы что-то вроде:

// Initialize analyzers 
    _optimizer = new LevenbergMarquardtOptimizer(); 
    _fitter = new CurveFitter(_optimizer); 

    // Initialize the analysis results 
    _gaussians = new ArrayList<GaussianFunction>(); 

    // Load the data into the gaussian fitter 
    for (int i = 0; i != data.length; i++) 
     _fitter.addObservedPoint(i, data[i]); 

, а затем на самом деле выполнить подгонку:

public void analyze() { 
    // Calculate Mean 
    double sum_yx = 0.0; 
    double sum_y = 0.0; 
    for (int i = 0; i != _data.length; i++) { 
     sum_yx += _data[i] * (i + 1); 
     sum_y += _data[i]; 
    } 

    double mean = sum_yx/sum_y; 

    // Peform the gaussian fit 

    // If no guesses given, fit to the mean of the data 
    if (_guesses.size() == 0) { 
     double[] guess = new double[] { 0, 1, mean, 1 }; 
     double ret[]; 
     try { 
      ret = _fitter.fit(new ParametricGaussianFunction(), guess); 
      _gaussians.add(new GaussianFunction(ret[0], ret[1], ret[2], 
        ret[3])); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

    // If guesses are given, fit to each one 
    else { 
     try { 
      for (double[] guess : _guesses) { 
       double ret[] = _fitter.fit(
         new ParametricGaussianFunction(), guess); 
       _gaussians.add(new GaussianFunction(ret[0], ret[1], ret[2], 
         ret[3])); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      // _gaussian = null; 
     } 
    } 
} 

Вы упоминали ваши данные шумно; Я включил догадки, потому что мне приходилось соответствовать пикам с гауссовскими распределениями, которые сами формировали гауссову форму. Исходное условие должно быть очень точным. Если мои догадки были отключены на несколько пикселей, я получил подгонку по всему набору данных, а не только к пику. Я предполагаю, что если нет подходящей альтернативы/большей тенденции, она просто потерпит неудачу.

GaussianFunction имеет критические параметры A, B, C и D, которые, соответственно, являются смещением y, амплитудой, положением центроида и сигмой.

Я ничего не знаю об Android, поэтому я не знаю, сможешь ли вы использовать этот пакет, но я нашел этот вопрос, ища родственный (я также реплицирую Приложение Matlab на Java, а не весело), ​​и подумал, что если вы еще не поняли это, это может помочь!

2

С 3.3 версии org.apache.commons.math3 еще проще с помощью GaussianCurveFitter:

 GaussianCurveFitter fitter = GaussianCurveFitter.create(); 

     WeightedObservedPoints obs = new WeightedObservedPoints(); 

     for (int index = 0; index < data.length; index++) { 
      obs.add(data[i].x, data[i].y); 
     } 

     double[] bestFit = fitter.fit(obs.toList()); 

Результаты будут нормой, значит, сигма, где норма будет ваша амплитуда.