Документация Engee
Notebook

Численное интегрирование

В этом примере мы изучим, как проинтегрировать вектор измерений скорости и сделать вывод о пройденном расстоянии.

Изучим исходные данные

Предположим, что у нас есть вектор измерений скорости автомобиля, совершенные в разные моменты времени.

In [ ]:
vel = [ 0, .45, 1.79, 4.02, 7.15, 11.18, 16.09, 21.90, 29.05, 29.05,
        29.05, 29.05, 29.05, 22.42, 17.9, 17.9, 17.9, 17.9, 14.34, 11.01,
        8.9, 6.54, 2.03, 0.55, 0 ];
vTime = 0:24;

Данные записаны через равные интервалы времени (каждую секунду, 24 секунды подряд). Выведем график наблюдаемого процесса:

In [ ]:
gr()
plot( vTime, vel, title="Скорость автомобиля", markershape=:star8,
      xlabel="Время, с", ylabel = "Скорость, м/с", legend=false )
Out[0]:

Положительный наклон соответствует интервалам, когда машина разгонялась, ровный горизонтальный график – движению с неизменной скоростью, отрицательный наклон соответствует интервалам торможения. В момент времени t=0 машина была неподвижна, скорость в этот момент равнялась 0 м/с. Машина ускорялась до достижения максимальной скорости, равной 29.05 м/с примерно при t=8. Она придерживалась этой скорости в течение 4 секунд. Затем начала сбавлять скорость до 17.9, три секунды продержала эту скорость, и продолжила неровно тормозить до полной остановки.

Эту кривую трудно описать одной непрерывной функцией, поскольку он имеет множество разрывов производной.

Рассчитаем пройденный путь

Для численного интегрирования мы воспользуемся пакетом Trapz, который можно установить следующим образом:

In [ ]:
]add Trapz

Функция trapz из этого пакета интегрирует дискретный временной ряд методом трапеций. Этот метод хорошо подходит для данных с явно наблюдаемыми разрывами и предполагает, что между двумя точками динамика системы менялась линейно.

Чтобы проиллюстрировать идею этого метода, нарисуем несколько трапеций на графике с нашими данными:

In [ ]:
plot( vTime, vel, title="Скорость автомобиля", markershape=:star8,
      xlabel="Время, с", ylabel = "Скорость, м/с", legend=false )
plot!( vTime, vel, fillrange=zeros(length(vel)), fillcolor=:blue, label=:none, lw=2, lc=:black )
for i in 1:length(vTime)
    plot!( [vTime[i],vTime[i]], [0,vel[i]], lw=2, lc=:black )
end
plot!()
Out[0]:

Функция trapz позволит рассчитать площадь под любой кусочно-линейной кривой, через сумму площадей трапеций под каждым интервалом.

Рассчитаем дистанцию, пройденную автомобилем за время наблюдения (площадь всей закрашенной области на графике) при помощи численного интегрирования.

In [ ]:
using Trapz
distance = trapz( vTime, vel )
Out[0]:
345.2199999999999

Итак, за 24 секунды автомобиль преодолел 345.22 м.

Выведем график пройденной дистанции

В библиотеке NumericalIntegration есть еще одна функция, которая нам пригодится – cumul_integrate.

In [ ]:
]add NumericalIntegration

Функция cumul_integrate тоже производит численное интегрирование, но возвращает не площадь под всей кривой, а накопленную сумму в каждой точке наблюдения исходной величины.

In [ ]:
using NumericalIntegration: cumul_integrate
cdistance = cumul_integrate( vTime, vel );

Мы рассчитали, какую часть расстояния автомобиль прошел от начала до каждой временной метки, теперь построим график.

In [ ]:
plot( cdistance, title = "Расстояние, пройденное автомобилем",
      xlabel = "Время, с", ylabel = "Расстояние (м)", legend=false )
Out[0]:

Заключение

Мы применили пару простых функций для интегрирования дискретных временных рядов (вектор измеренной скорости) и получили пройденное расстояние за все время наблюдения и график преодоления этого за каждый отрезок времени.