Вы точно это хотели сделать? Или имелось в виду так:
Вы правы, имелся в виду Ваш вариант. Плохо ещё знаю язык.
Интересно, что скрипт работает и без этих двух операторов с
zeros. Но я решил, что так яснее: сразу видна размерность матриц
S и
cc. Обе эти матрицы содержат
столбцов, по числу значений
.
Матрица
S хранит невязки, а матрица
cc — коэффициенты, найденные методом наименьших квадратов. При данном
невязка — одно число, а коэффициентов три. Поэтому
S — матрица
, а
cc — матрица
.
Под "невязкой" (по-Вашему, "отклонение") понимается
, где
— наилучшая аппроксимирующая функция для данного
. По техническим причинам (теория этого не требует) в данной программе из этого выражения ещё извлекается квадратный корень, подробности ниже.
В первой строке цикла вы создаёте матрицу: в первом столбце единицы, во втором столбце значения косинуса во всех временных точках для
-го коэффициента
, в третьем – то же самое, но для синуса. Для чего первый столбец – не понимаю. Остальные два, видимо, выглядят так, потому что вы использовали описанное выше преобразование, чтобы сделать задачу линейной. Но куда делись
и
?
Рассмотрим выражение, которое надо минимизировать при заданном
:
Согласно МНК, аппроксимирующая функция
ищется в виде линейной комбинации
заданных базисных функций
с неизвестными коэффициентами
:
Возьмём
известных базисных функции
с неизвестными коэффициентами
(вот куда они делись!)
Тогда наша аппроксимирующая функция принимает нужную форму:
Функция
в действительности является константой. Но это особенно ничего не упрощает, и я её всё равно должен ввести, чтобы обеспечить форму
.
Пусть
— матрица
с элементами
, где
.
В нашем случае это матрица
. Каждая её строка соответствует одной из
точек
. Каждый из её столбцов соответствует одной из
базисных функций
. А на их пересечении стоит значение этой базисной функции
в этой точке
.
Поскольку
при любом
, в первом столбце матрицы
стоят только единицы. Во втором и третьем столбцах стоят соответственно
и
.
2)Рассмотрим цикл:
for j=1:N
A=[ones(n,1), cos(2*pi*b(j)*x), sin(2*pi*b(j)*x)];
c=pinv(A)*y;
S(j)=norm(y-A*c);
cc(:,j)=c;
end
Что происходит дальше мне вообще не ясно. Что это за метод и откуда эти выражения появляются? То есть я понимаю, что вы ищете какую-то псевдообратную матрицу, ищете норму, но не понимаю, зачем. Какой смысл у вектора
(вернее, почему в нём в итоге оказываются те самые
,
и даже
? Как я понял, вектор
определяет отклонение функции от заданного значения при
-том
.
Про вектор
Вы поняли правильно.
Про вектор
я уже рассказал — это вектор
из неизвестных коэффициентов:
Вычисленный вектор
потом с помощью оператора
cc(:,j)=c становится
-м столбцом матрицы
cc, хранящей такие векторы для всех
.
Вообще, MATLAB разрабатывался так, чтобы в матричных вычислениях пользователю приходилось писать как можно меньше явных циклов. Составив из
вектор
, я могу их находить или использовать "одним махом". В противном случае пришлось бы всюду, где идёт работа с этими коэффициентами, записать что-то с участием
, потом что-то аналогичное с
, а потом аналогичное с
.
Итак, матрица
заполнена.
Согласно теории, минимальную невязку обеспечивает вектор
.
Здесь написано (в пересчёте на вещественный случай), что если столбцы
линейно независимы (а у нас это
почти всегда так), то псевдообратная матрица
. Значит,
. Но для псевдообратной матрицы есть функция
pinv. Получаем оператор
c=pinv(A)*y;Сама невязка равна
Это можно закодировать так:
(y-A*c)'*(y-A*c). Но мне хотелось записать это короче. Я искал в MATLAB функцию, которая бы для произвольного вектора
возвращала
. Не нашёл. Зато нашлась функция
norm, которая выдаёт
. Но это тоже подходит: точки минимума
и
совпадают. Итак,
S(j)=norm(y-A*c);3)Тут вы находите минимальное отклонение и его номер в массиве, откуда можно вытащить
, которое соответствует этому отклонению:
Тут вы вытаскиваете искомые коэффициенты и соответствующий им коэффициент
:
b_=b(Ind(1))
c_=cc(:,Ind(1))
Концовку, как мне кажется, я правильно понял.
Да, тут Вы всё поняли правильно, отлично.