Несимволическая производная во всех точках выборки, включая граничные точки

Предположим, у меня есть вектор t = [0 0.1 0.9 1 1.4] и вектор x = [1 3 5 2 3]. Как я могу вычислить производную x по времени, которая имеет ту же длину, что и исходные векторы?

Я не должен использовать никаких символических операций. Команда diff(x)./diff(t) не создает вектор одинаковой длины. Должен ли я сначала интерполировать функцию x(t), а затем взять ее производную?


person Alex    schedule 06.07.2017    source источник
comment
дифференциал никогда не может иметь одинаковую длину, если только вы не определите его значение в какой-то начальной точке. Что-то вроде dx/dt = 0 при t = 0. Затем вы можете добавить это начальное значение в начале diff(x) ./ diff(t)   -  person ammportal    schedule 06.07.2017
comment
@ammportal Я с вами не согласен, смотрите мой ответ. Ты согласен?   -  person m7913d    schedule 07.07.2017
comment
я думаю, что я был немного неясен в моем комментарии. Дифференциал никогда не будет иметь одинаковую длину с подходом, используемым OP, то есть с использованием diff(x) ./ diff(t). Конечно, метод, который вы описали, лучше подходит.   -  person ammportal    schedule 07.07.2017


Ответы (1)


Существуют разные подходы для вычисления производной в тех же точках, что и исходные данные:

  1. Конечные разности. Используйте схему центральной разности во внутренних точках и схему прямого/обратного хода в первой/последней точке.

or

  1. Аппроксимация кривой. Сопоставьте кривую с вашими точками, вычислите производную этой подобранной функции и выберите их в тех же точках, что и исходные данные. Типичными подгоночными функциями являются полиномы или сплайн-функции.

Обратите внимание, что метод подгонки кривой дает лучшие результаты, но требует больше параметров настройки и работает медленнее (примерно в 100 раз).

Демонстрация

В качестве примера я вычислю производную синусоидальной функции:

t = 0:0.1:1;
y = sin(t);

Его точная производная хорошо известна:

dy_dt_exact = cos(t);

Производную можно приблизительно рассчитать как:

  1. Конечные отличия:

    dy_dt_approx = zeros(size(y));
    dy_dt_approx(1) = (y(2) - y(1))/(t(2) - t(1)); % forward difference
    dy_dt_approx(end) = (y(end) - y(end-1))/(t(end) - t(end-1)); % backward difference
    dy_dt_approx(2:end-1) = (y(3:end) - y(1:end-2))./(t(3:end) - t(1:end-2)); % central difference
    

or

  1. Полиномиальная подгонка:

    p = polyfit(t,y,5); % fit fifth order polynomial
    dp = polyder(p); % calculate derivative of polynomial
    

Результаты можно визуализировать следующим образом:

figure('Name', 'Derivative')
hold on
plot(t, dy_dt_exact, 'DisplayName', 'eyact');
plot(t, dy_dt_approx, 'DisplayName', 'finite difference');
plot(t, polyval(dp, t), 'DisplayName', 'polynomial');
legend show

figure('Name', 'Error')
hold on
plot(t, abs(dy_dt_approx - dy_dt_exact)/max(dy_dt_exact), 'DisplayName', 'finite difference');
plot(t, abs(polyval(dp, t) - dy_dt_exact)/max(dy_dt_exact), 'DisplayName', 'polynomial');
legend show

введите здесь описание изображения введите здесь описание изображения

На первом графике показаны сами производные, а на втором — относительные ошибки, допущенные обоими методами.

Обсуждение

Хорошо видно, что метод подбора кривой дает лучшие результаты, чем метод конечных разностей, но он в ~100 раз медленнее. Методы подбора кривой имеют относительную погрешность порядка 10^-5. Обратите внимание, что метод конечных разностей становится лучше, когда ваши данные выбираются более плотно или вы используете схему более высокого порядка. Недостатком подхода подбора кривой является то, что необходимо выбрать хороший полиномиальный порядок. В общем случае сплайн-функции могут лучше подходить.

В 10 раз более быстрый выборочный набор данных, т. е. t = 0:0.01:1;, приводит к следующим графикам:

введите здесь описание изображения введите здесь описание изображения

person m7913d    schedule 06.07.2017
comment
Уважаемые, спасибо за ваши сообщения и полезные ответы. Можно ли найти точную числовую производную, используя не полидерную, а сплайн-интерполяцию? - person Alex; 08.07.2017
comment
Для подгонки сплайна вы можете посмотреть документацию Matlab для spline и подбор сплайна. Этот пост может быть полезен для вычисления его производной. - person m7913d; 08.07.2017
comment
Я хотел сказать, что в приведенном выше примере вместо p = polyfit(t,y,5); dp = polyder(p), можно ли написать p = spline(t,y,y), dp = polyder(p)? Будет ли это точно вычислять производные? Сплайн позволяет избежать феномена Рунге, но я не уверен, что его можно здесь использовать. - person Alex; 08.07.2017
comment
Вы можете использовать сплайны, но ваш синтаксис неверен. Вы должны проверить руководство. - person m7913d; 08.07.2017
comment
Я проверил руководство, и теперь я использую простую сплайн-интерполяцию. т = 0:0,1:1; время_новое = [0:0,01:1]; у = грех (т); dy_dt_exact = потому что (т); p = interp1 (t, y, time_new, 'сплайн'); дп = полидер (р); Но не похоже, что dp близко соответствует cos(t). Кроме того, как сделать так, чтобы dp имел ту же длину, что и вектор dy_dt_exact? Они имеют разную длину. - person Alex; 09.07.2017
comment
@alex Вы не должны использовать interp1, так как он не возвращает внутреннее представление сплайна. Также polyder предназначен только для получения полиномиальной функции, а не для интерполированных данных. Я думаю, вам следует лучше прочитать мою третью ссылку, или вы можете опубликовать новый вопрос о сплайн-интерполяции и ее (точных) производных, поскольку это выходит за рамки этого вопроса (вы не упомянули сплайны в своем вопросе). - person m7913d; 09.07.2017
comment
Привет. Честно говоря, я не уверен, почему нельзя использовать interp1. Я обнаружил, что во многих приложениях он работает довольно хорошо. Например, эта команда работает нормально.clc;clear; т = [0:0,1:1]; t_new = [0:0,01:1]; у = грех (т); dy_dt_exact = потому что (т); p = interp1 (t, y, t_new, 'сплайн'); plot(t,y,'o',t_new,p) Я последую вашему совету и задам новый вопрос. - person Alex; 09.07.2017
comment
Потому что вы хотите вычислить его производную, что можно сделать сразу после того, как вы подогнали модель к своим данным. - person m7913d; 09.07.2017