Я работаю над кодом, анализирующим периодический шумовой сигнал. Сигнал подается в моем примере в виде файла CSV, содержащего около 382 периодов сигнала в 25000 бинов, которые загружаются в мой класс. Я разбил данные на подмножества, представляющие по одному пику каждый, и применил GaussianCurveFitter к каждому из наборов данных. В определенных случаях - я думаю, если данные, переданные Fitter, являются дрянными и очень негауссовыми - CurveFitter просто заходит в тупик или бесконечный цикл и никогда не возвращается к жизни. Я не понимаю, почему.
Вот код:
package de.gsi.sdbe.playground.wgeithner.BpmFitTest.main;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import org.apache.commons.math3.fitting.GaussianCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import de.gsi.chart.data.spi.DefaultDataSet;
public class TemplateAppModel {
final private WeightedObservedPoints _fitDataSet = new WeightedObservedPoints(); // datasets for curve fitting
private final ArrayList<Double> _rawDataY = new ArrayList<>();
public DefaultDataSet loadCsvFile() {
Scanner fileScanner = null;
try {
fileScanner = new Scanner(new File("src/main/resources/YR06DX1HSignal.csv"));
} catch (final FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final DefaultDataSet dataSet = new DefaultDataSet("Signal"); // dataset for visualization
while (fileScanner.hasNextLine()) {
final String lineText = fileScanner.nextLine();
final String[] xyItems = lineText.split(",");
try {
dataSet.add(Double.valueOf(xyItems[0]), Double.valueOf(xyItems[1]));
_rawDataY.add(Double.valueOf(xyItems[1]));
} catch (final NumberFormatException ex) {
// DO NOTHING
}
}
fileScanner.close();
return dataSet;
}
public ArrayList<Double> doBoxedPeakFitting(final Double binLengthIn, final Double rfFrequencyIn) {
final ArrayList<Double> fitSummary = new ArrayList<>();
final Double binLength = 8e-9; // in nanoseconds
final Double rfFrequency = 1907440.2; // in Hz
final Double dataSetTimeLength = _rawDataY.size() * binLength;
final int peakCount = (int) Math.round(dataSetTimeLength * rfFrequency);
// move a box over the data set an perform a fit for each boxed peak
final int peakBoxSize = _rawDataY.size() / peakCount;
for (int peakBoxCounter = 0; peakBoxCounter < peakCount; peakBoxCounter++) {
final int maxRawIndex = peakBoxCounter * peakBoxSize + peakBoxSize;
final List<Double> fitWindow = _rawDataY.subList(peakBoxCounter * peakBoxSize, maxRawIndex);
final Double minimum = Collections.min(fitWindow);
System.out.println("Minimum: " + minimum);
final List<Double> fitWindowNormalized = new ArrayList<>();
// add an offset to data to get everything into positive
for (final Double item : fitWindow) {
fitWindowNormalized.add(item - minimum);
}
// perform the actual fit
final double[] fitResult = doFit(fitWindowNormalized, peakBoxCounter);
if (fitResult.length == 3) {
fitSummary.add(fitResult[2]);
}
}
return fitSummary;
}
private double[] doFit(final List<Double> dataSet, final int fitIndex) {
final WeightedObservedPoints fitData = new WeightedObservedPoints();
double xValue = 0.0;
// map the input to a format Apache GaussianCurveFitter expects
for (final double yValue : dataSet) {
fitData.add(xValue, yValue);
xValue++;
}
GaussianCurveFitter theFitter = GaussianCurveFitter.create();
theFitter.withMaxIterations(1);
try {
final double[] fitResult = theFitter.fit(fitData.toList());
theFitter = null;
return fitResult;
} catch (final Exception ex) {
System.out.println(fitIndex);
ex.printStackTrace();
for (final Double value : dataSet) {
System.out.println(value);
}
}
return new double[1];
}
public static double getMinValue(final double[] numbers) {
double minValue = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] < minValue) {
minValue = numbers[i];
}
}
return minValue;
}
public static void main(final String[] args) {
final TemplateAppModel model = new TemplateAppModel();
model.loadCsvFile();
final ArrayList<Double> result = model.doBoxedPeakFitting(null, null);
final DescriptiveStatistics stats = new DescriptiveStatistics();
result.stream().forEach(item -> {
stats.addValue(item.doubleValue());
});
System.out.println("Mean: " + stats.getMean());
}
}
Это ошибка в библиотеке Apache или я что-то не так делаю? При необходимости я могу также предоставить файл данных CSV ...