Количество событий ODE изменяется при различных условиях простой ODE

У меня есть следующий простой ODE:

dx/dt=-1

При начальном условии x(0)=5 меня интересует, когда x(t)==1. Итак, у меня есть следующая функция событий:

function [value,isterminal,direction] = test_events(t,x)
    value = x-1;
    isterminal = 0;
    direction = 0;
end

Это должно привести к событию в момент времени t=4. Однако, если я запускаю следующий код, я получаю два события: одно в t=4 и одно в соседнем месте t=4+5.7e-14:

options = odeset('Events',@test_events);
sol = ode45(@(t,x)-1,[0 10],5,options);
fprintf('%.16f\n',sol.xe)
% 4.0000000000000000
% 4.0000000000000568

Если я запускаю аналогичные коды, чтобы найти, когда x(t)==0 или x(t)==-1 (значение = x; или значение = x+1; соответственно), у меня есть только одно событие. Почему это генерирует два события?

ОБНОВЛЕНИЕ: если структура параметров изменена на следующую:

options = odeset('Events',@test_events,'RelTol',1e-4);

...тогда ODE возвращает только одно событие в t=4+5.7e-14. Если для параметра «RelTol» установлено значение 1e-5, он возвращает одно событие в момент времени t=4. Если для параметра «RelTol» установлено значение 1e-8, возвращаются те же два события, что и по умолчанию («RelTol» = 1e-3). Кроме того, изменение начального условия с x(0)=5 на x(0)=4 приводит к одному событию, а установка x(0)=4 и 'RelTol'=1e-8 приводит к возникновению двух событий.

ОБНОВЛЕНИЕ 2: Наблюдая за выводами sol.x и sol.y (t и x соответственно), время прогрессирует как целые числа [0 1 2 3 4 5 6 7...], а x прогрессирует как целые числа до тех пор, пока x (t =5) вот так: [5 4 3 2 1 1.11e-16 -1.000 -2.000...]. Это указывает на то, что между t=4 и t=5 происходит что-то, что создает «выпуклость» в решении ОДУ. Почему?


person dweth    schedule 04.03.2019    source источник
comment
Взгляните на параметры «RelTol» и «AbsTol». Если я установлю options = odeset('Reltol',1e-5,'Events',@test_events); У меня есть только одно мероприятие в "x-1"   -  person Anton    schedule 05.03.2019
comment
Я тоже получаю только одно событие, устанавливая RelTol на 1e-5. Тем не менее, я до сих пор не понимаю, почему это должно влиять на что-либо с таким простым и хорошо масштабируемым ODE. Я обновлю вопрос, чтобы включить эту информацию.   -  person dweth    schedule 05.03.2019
comment
решатель оды имеет ограниченную точность, которую вы можете изменить с помощью этих двух свойств. Полученные вами значения t одинаковы для решателя. Он не может отличить их друг от друга.   -  person Anton    schedule 05.03.2019
comment
Это по-прежнему оставляет следующие проблемы: - Более строгий допуск может снизить точность решателя во многих случаях. В таком простом случае более строгий допуск не требуется, и выбор является совершенно произвольным. -Установка RelTol=1e-8 дает то же решение, что и при RelTol=1e-3 по умолчанию. -Изменение определения 'value' в @test_events или изменение начальное условие может изменить результаты (RelTol не должен влиять на них по-разному). Я обновлю вопрос, чтобы включить эту информацию   -  person dweth    schedule 05.03.2019
comment
Вы также можете просмотреть внутренние точки выборки, содержащиеся в объекте sol. Может случиться так, что в некоторых примерах число близко к 4, однако, поскольку размер шага должен быть достаточно большим, это должно быть событие с низкой вероятностью.   -  person Lutz Lehmann    schedule 07.03.2019
comment
Я только что посмотрел на это, интересно, что вывод sol.y выглядит следующим образом: [5 4 3 2 1 1.11e-16 -1.000 -2.000...]. Итак, что-то происходит между t=4 и t=5, что регулирует вывод, так что это не совсем прямая линия. Запуск без функции событий дает тот же результат. Я обновлю вопрос, чтобы включить эту информацию.   -  person dweth    schedule 07.03.2019


Ответы (1)


Одно предположение, которое могло бы объяснить, как могут возникать ошибки округления в этой простой задаче: решение интерполируется между внутренними шагами с использованием оценок k_n функции производных ОДУ, также называемой "плотным выводом". Теоретическая форма

b_1(u)k_1 + b_2(u)k_2 + ...b_s(u)k_s

где 0 <= u<= 1 это параметр на интервале между внутренними точками, то есть t = (1-u)*t_k+u*t_{k+1}.

Полиномы коэффициентов нетривиальны. В то время как в примере все k_i=1 являются постоянными, оценка суммы b_1(u)+...+b_s(u) может накапливать ошибки округления, которые становятся видимыми в значении решения близко к корню, даже если y_k и y_{k+1} точны. В этом диапазоне накопленного шума с плавающей запятой значение может колебаться вокруг корня, что приводит к обнаружению нескольких пересечений нуля.

person Lutz Lehmann    schedule 07.03.2019
comment
Я ценю ваш вдумчивый ответ. Я думал об этом немного, но я не уверен, что полностью понимаю. Однако я обращусь к тому, что могу понять: если есть несколько пересечений корня функции событий, то не будет ли это означать, что мне потребуется нечетное количество событий для удовлетворения значения (t = 0) > 0 и значения (t=t_end) ‹ 0? Кроме того, не должно ли в этом случае наложение ограничения направления привести к одному событию? Я проверил эту последнюю идею, и установка направления = -1 не решает проблему. - person dweth; 22.03.2019
comment
Это было бы так, если бы интерполирующие полиномы полностью непрерывно согласовывались друг с другом. Я не знаю, что именно происходит, но я думаю, что из-за ошибок с плавающей запятой есть пробелы. Но чтобы точно знать, что происходит, нужно, насколько это возможно, копаться в промежуточных результатах и ​​коде. Можно начать с построения решения близко к корню, используя оценку sol для получения значений интерполяционных полиномов. - person Lutz Lehmann; 22.03.2019