2013-07-11 5 views
1

Je dois ajuster une courbe gaussienne à un ensemble de données bruyant, puis utiliser FWHM pour une application donnée. J'ai utilisé MATLAB pour faire la démonstration du concept, et l'ajustement des courbes dans MATLAB est extrêmement facile. Cependant, j'ai finalement besoin de traduire le code en Java/Android. J'ai essayé de chercher des bibliothèques dans Android qui m'aideraient à adapter une courbe gaussienne à l'ensemble de données, mais je n'ai rien trouvé. Par conséquent, j'ai commencé à essayer d'apprendre toutes les mathématiques impliquées afin que je puisse le faire manuellement.Ajustement de la courbe gaussienne - Estimation des paramètres - Android/Java

Ma question: Comment puis-je estimer les trois paramètres (centre, largeur, hauteur) pour un modèle gaussien à un terme? J'ai essayé de regarder dans l'algorithme Expectation-Maximization mais cela m'a beaucoup dépassé.

En général, je suppose que cela aurait quelque chose à voir avec la minimisation des erreurs? J'ai juste du mal à trouver la méthode pas à pas pour ajuster une courbe gaussienne à mes données.

EDIT:

L'une des choses que j'ai essayé déjà impliqué de prendre le logarithme naturel de mes données, un montage au résultat parabola utilisant LSQR, puis transformer en arrière. Cependant, les résultats que je reçois ne sont pas précis, probablement parce que cette méthode est biaisée d'une manière ou d'une autre.

Si vous ne savez pas comment faire l'estimation des paramètres, avez-vous d'autres suggestions pour adapter une courbe à mes données? (Rappelez-vous, il doit être manuel puisque Android semble être assez limité sur ses bibliothèques de statistiques)

+0

Ceci est hors-sujet. SO est pour la programmation des questions, pas des questions de mathématiques. Vérifiez [MathematicsSE] (http://math.stackexchange.com/). –

+0

Mais c'est une question de programmation, haha. –

Répondre

2

J'ai récemment fait une chose similaire en utilisant la classe de mathématiques Apache Commons, en particulier les classes Levenberg-Marquardt Optimizer, CurveFitter et GaussianFunction.

Le code je pour obtenir les données prêt était quelque chose comme:

// 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]); 

puis d'effectuer réellement l'ajustement:

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; 
     } 
    } 
} 

Vous avez mentionné vos données est bruyant; J'ai inclus les suppositions parce que je devais m'adapter aux pics avec des distributions gaussiennes qui formaient elles-mêmes une forme gaussienne. La condition initiale doit être très précise. Si mes suppositions étaient décalées de quelques pixels, j'ai eu un ajustement sur l'ensemble des données au lieu de seulement le pic. J'imagine que s'il n'y a pas de solution de repli/tendance plus grande à s'adapter, cela échouerait tout simplement.

GaussianFunction possède les paramètres cryptiques A, B, C et D qui sont, respectivement, le décalage y, l'amplitude, la position du centroïde et le sigma.

Je ne connais pas une seule chose à propos d'Android, donc je ne sais pas si vous serez en mesure d'utiliser ce paquet, mais j'ai trouvé cette question en cherchant une question connexe (je reproduis aussi un Application Matlab en Java, pas amusant) et figuré si vous ne l'avez pas encore compris, cela pourrait aider!

2

Avec la version 3.3 de org.apache.commons.math3 est encore plus facile l'utilisation 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()); 

Les résultats seront la norme, moyenne, sigma, où la norme sera votre amplitude.

Questions connexes