Один метод, на который стоит обратить внимание, если такого подхода, предложенного Карлом, будет недостаточно, - Кросс-корреляция . Суть этого довольно проста: если два набора данных достаточно похожи, их точечное произведение будет максимизировано при их выравнивании (потому что самые высокие значения будут умножены вместе). Таким образом, вы можете получить точную оценку того, как их выстроить, рассчитав этот продукт для каждого смещения и выбрав тот, который дает наибольший результат.
В случае, подобном вашему, идея состоит в том, чтобы иметь «идеальную» версию искомой формы кривой - либо сгенерированную из теории / моделирования, либо путем усреднения результатов ряда определенных экспериментальных кривых, определенных и выровнять на глаз - и сравнить его с экспериментальными данными.
Для простоты давайте предположим, что набор данных длиннее идеального и имеет достаточно свободного места на обоих концах, чтобы мы могли игнорировать любые проблемы с границами. Так как вы ищете одно конкретное событие, должно быть тривиально урезать ваш идеал, чтобы соответствовать этому предположению. Грубо закодированный в Java, процесс может выглядеть примерно так:
int offset ( double[] data, double[] ideal )
{
double cMax = -Double.MAX_VALUE;
int tMax = 0;
for ( int t = 0; t < data.length - ideal.length; ++t )
{
double c = 0;
for ( int i = 0; i < ideal.length; ++i )
{
c += data[t + i] * ideal[i];
}
if ( c > cMax )
{
cMax = c;
tMax = t;
}
}
return tMax;
}
Очевидно, что существует множество ситуаций, в которых этот подход может потерпеть неудачу, особенно, если имеется значительное количество независимых сигналов или если в сигнале есть периодичности, которые вызывают алиасинг . Кроме того, этот пример отбрасывает много информации, чтобы сфокусироваться только на абсолютном максимуме, который может быть подвержен ошибкам, если в кросс-корреляции нет большого узкого пика. Но из твоего описания кажется, что твоя проблема вполне поддается чему-то подобному.