Подбор сплайна к тестовым данным на титан

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

Ручной выбор узла для сплайн интерполяции

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

[xx,yy] = titanium;

График данных показывает довольно резкий пик.

plot(xx,yy,'bx');
frame = [-10 10 -.1 .3]+[min(xx),max(xx),min(yy),max(yy)];
axis(frame);

Figure contains an axes. The axes contains an object of type line.

Мы выбираем несколько точек данных из этих несколько приблизительных данных, так как мы хотим интерполировать. Вот изображение данных с отмеченными выбранными точками данных.

pick = [1 5 11 21 27 29 31 33 35 40 45 49];
tau = xx(pick);
y = yy(pick);
hold on
plot(tau,y,'ro');
hold off

Figure contains an axes. The axes contains 2 objects of type line.

Поскольку сплайн порядка k с n + k узлами имеет n степеней свободы, и у нас есть 12 точек данных, для подгонки со сплайном четвертого порядка требуется 12 + 4 = 16 узлов. Кроме того, эта последовательность узлов t должна быть такой, чтобы i-й сайт данных лежал в поддержке i-го B-сплайна. Мы достигаем этого, используя сайты данных как узлы, но добавляем два простых узла на любом конце.

dl = tau(2) - tau(1);
dr = tau(end) - tau(end-1);
t = [tau(1)-dl*[2 1] tau tau(end)+dr*[1 2]];  % construct the knot sequence
plot(tau,y,'ro');
hold on
axis(frame+[-2*dl 2*dr 0 0])
plot(t,repmat(frame(3)+.03,size(t)),'kx')
hold off
legend({'Data Values' 'Knots'},'location','NW')

Figure contains an axes. The axes contains 2 objects of type line. These objects represent Data Values, Knots.

Мы используем эту последовательность узлов, чтобы создать интерполирующий кубический сплайн.

sp = spapi(t,tau,y);

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

plot(tau,y,'ro')
axis(frame)
hold on
fnplt(sp,[tau(1) tau(end)], 'k')
hold off

Figure contains an axes. The axes contains 2 objects of type line.

Более близкий взгляд на левую часть сплайна подгонки показывает некоторые волнистости.

xxx = linspace(tau(1),tau(5),41);
plot(xxx, fnval(sp, xxx), 'k', tau, y, 'ro');
axis([tau(1) tau(5) 0.6 1.2]);

Figure contains an axes. The axes contains 2 objects of type line.

Неразумный отбойник в первом интервале проистекает из того, что наш сплайн плавно переходит в нуль в своём первом узле. Чтобы увидеть это, вот изображение всего сплайна, вместе с его последовательностью узлов и точками данных.

fnplt(sp,'k');
hold on
plot(tau,y,'ro', t,repmat(.1,size(t)),'kx');
hold off
legend({'Spline Interpolant' 'Data Values' 'Knots'},'location','NW')

Figure contains an axes. The axes contains 3 objects of type line. These objects represent Spline Interpolant, Data Values, Knots.

Вот простой способ обеспечить более разумное граничное поведение. Мы добавляем еще две точки данных за пределами заданного интервала данных и выбираем в качестве наших данных значения прямой линии через первые две точки данных.

tt = [tau(1)-[4 3 2 1]*dl tau tau(end)+[1 2 3 4]*dr];
xx = [tau(1)-[2 1]*dl tau tau(end)+[1 2]*dr];
yy = [y(1)-[2 1]*(y(2)-y(1)) y y(end)+[1 2]*(y(end)-y(end-1))];
sp2 = spapi(tt,xx,yy);
plot(tau,y,'ro', xx([1 2 end-1 end]),yy([1 2 end-1 end]),'bo');
axis(frame+[-2*dl 2*dr 0 0]);
hold on
fnplt(sp2,'b',tau([1 end]))
hold off
legend({'Original Data' 'Data Added for End Conditions' ...
        'Fit with Added Data'},'location','NW')

Figure contains an axes. The axes contains 3 objects of type line. These objects represent Original Data, Data Added for End Conditions, Fit with Added Data.

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

hold on
fnplt(sp,'k',tau([1 end]))
hold off
legend({'Original Data' 'Data Added for End Conditions' ...
        'Fit with Added Data' 'Original Fit'},'location','NW')

Figure contains an axes. The axes contains 4 objects of type line. These objects represent Original Data, Data Added for End Conditions, Fit with Added Data, Original Fit.

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

plot(tau,y,'ro',xxx,fnval(sp2,xxx),'b',xxx,fnval(sp,xxx),'k');
axis([tau(1) tau(5) .6 1.2]);
legend({'Original Data' 'Fit with Added Data' ...
        'Original Fit'},'location','NW')

Figure contains an axes. The axes contains 3 objects of type line. These objects represent Original Data, Fit with Added Data, Original Fit.

Автоматический выбор узла для интерполяции

Если вся эта деталь отключает вас, пусть Curve Fitting Toolbox выберет узлы для вас. Задайте требуемый порядок интерполяции в качестве первого входного параметра в команду сплайн интерполяции spapi, а не последовательность узлов.

autosp = spapi(4, tau, y);
knots = fnbrk(autosp,'knots');
plot(tau, y, 'ro')
hold on
fnplt(autosp,'g')
plot(knots, repmat(.5,size(knots)),'gx')
hold off
legend({'Data Values' 'Fit With Knots Chosen by SPAPI' ...
        'Knots Chosen by SPAPI'}, 'location','NW')

Figure contains an axes. The axes contains 3 objects of type line. These objects represent Data Values, Fit With Knots Chosen by SPAPI, Knots Chosen by SPAPI.

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

knots([7 12]) = [851, 971];
adjsp = spapi(knots, tau, y);
hold on
fnplt(adjsp,'r',2)
plot(knots, repmat(.54,size(knots)),'rx')
hold off
legend({'Data Values' 'Fit With Knots Chosen by SPAPI' ...
        'Knots Chosen by SPAPI' 'Fit With Knots Adjusted' ...
        'Adjusted Knots'}, 'location','NW')

Figure contains an axes. The axes contains 5 objects of type line. These objects represent Data Values, Fit With Knots Chosen by SPAPI, Knots Chosen by SPAPI, Fit With Knots Adjusted, Adjusted Knots.

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

autocs = csapi(tau, y);
plot(tau, y, 'ro')
hold on
fnplt(autocs,'c')
hold off

Figure contains an axes. The axes contains 2 objects of type line.

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

plot(tau, y, 'ro')
hold on
fnplt(sp,'k',tau([1 end]))  % black: original
fnplt(sp2,'b',tau([1 end])) % blue:  with special end conditions
fnplt(autosp,'g')           % green: automatic knot choice by SPAPI
fnplt(autocs,'c')           % cyan:  automatic knot choice by CSAPI
fnplt(adjsp,'r',2)          % red:   knot choice by SPAPI slightly changed
hold off
legend({'Data Values' 'Original Fit' 'Special End Conditions' ...
        'With Knots Chosen by SPAPI' 'With Knots Chosen by CSAPI' ...
        'With Adjusted Knots'},'location','NW')

Figure contains an axes. The axes contains 6 objects of type line. These objects represent Data Values, Original Fit, Special End Conditions, With Knots Chosen by SPAPI, With Knots Chosen by CSAPI, With Adjusted Knots.