Pers.narod.ru. Алгоритмы. Метод наименьших квадратов (МНК)

Если набор экспериментальных данных получен со значительной погрешностью, то не имеет смысла использовать интерполяцию Лагранжа полиномами и сплайнами для обработки результатов. В этом случае необходимо провести аппроксимирующую кривую, которая не проходит через экспериментальные точки, но в то же время отражает исследуемую зависимость и сглаживает "выбросы", возможные за счет погрешности эксперимента.

Обозначим узлы исходной таблицы данных через хi, где 0<= i<= n - номер узла. Считаем известными значения экспериментальных данных в узловых точках f(xi) = fi. Введем непрерывную функцию φ(х) для аппроксимации дискретной зависимости f(xi). В узлах функции φ(х) и f(x) будут отличаться на величину еi = φ(хi)-f(xi). Отклонения еi могут принимать положительные и отрицательные значения. Чтобы не учитывать знаки, возведем каждое отклонение в квадрат и просуммируем квадраты отклонений по всем узлам:

(1)

Метод построения аппроксимирующей функции φ(х) из условия минимума величины Q называется методом наименьших квадратов (МНК).

Наиболее распространен способ выбора функции φ(х) в виде линейной комбинации:

(2)

φ0(х), φ1(х),…, φm(х) - базисные функции; m <= n; c0, c1,...,cm - коэффициенты, определяемые при минимизации величины Q.

Математически условия минимума суммы квадратов отклонений Q запишем, приравнивая нулю частные производные от Q по коэффициентам сk, 0<=k<=n:

(3)

Из системы линейных алгебраических уравнений (3) определяются все коэффициенты сk. Система (3) называется системой нормальных уравнений. Матрица этой системы имеет следующий вид:

(4)

и называется матрицей Грама. Элементы матрицы Грама являются скалярными произведениями базисных функций

(5)

Расширенная матрица системы уравнений (3) получится добавлением справа к матрице Грама столбца свободных членов

(6)

где скалярные произведения, являющиеся элементами столбца, определяются аналогично (5):

(7)

Отметим основные свойства матрицы Грама, полезные при программной реализации алгоритмов МНК:

1) матрица симметрична, т.е. аi,j = аj,i, что позволяет сократить объем вычислений при заполнении матрицы;

2) матрица является положительно определенной, следовательно, при решении системы нормальных уравнений методом исключения Гаусса можно отказаться от процедуры выбора главного элемента;

3) определитель матрицы будет отличен от нуля, если в качестве базиса выбраны линейно независимые функции φk(х), при этом система (3) имеет единственное решение.

При обработке экспериментальных данных, определенных с погрешностью e в каждой узловой точке, обычно начинают с аппроксимации функцией φ(x), представимой одной-двумя базисными функциями. После определения коэффициентов ck вычисляют величину Q по формуле (1). Если получится, что корень(Q) > e , то необходимо расширить базис добавлением новых функций φk(х). Расширение базиса необходимо осуществлять до тех пор, пока не выполнится условие корень(Q)~=е.

Выбор конкретных базисных функций зависит от свойств аппроксимируемой функции f(x), таких, как периодичность, экспоненциальный или логарифмический характер, свойства симметрии, наличие асимптотики и т.д. На практике чаще всего используется решение, показанное далее.

Степенной базис

Выберем базисные функции φk(х) в виде последовательности степеней аргумента х, которые линейно независимы,

(8)

В этом случае мы будем аппроксимировать экспериментальную зависимость полиномом. Степень полинома m выбираем m<<n (при лагранжевой интерполяции m=n). Аппроксимирующая кривая в МНК не проходит через значения исходной функции в узлах, но проведена из условия наименьшего суммарного квадратичного отклонения. Экспериментальные данные "сглаживаются" с помощью функции φ(х). Если же выбрать m=n, то на основании единственности интерполяционного полинома получим функцию φ(х), совпадающую с каноническим интерполяционным полиномом степени n, аппроксимирующая кривая пройдет через все экспериментальные точки и величина Q будет равна нулю. Последнее обстоятельство используется для отладки и тестирования программ, реализующих алгоритмы МНК.

Запишем расширенную матрицу системы нормальных уравнений для базиса (8):

(9)

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

Для решения систем уравнений с матрицей Грама разработаны методы сингулярного разложения. Если же m <= 4..5, то такие системы можно решать и более простым методом исключения Гаусса.

Ниже приводится консольная программа на Паскале, реализующая метод МНК со степенным базисом. С клавиатуры вводятся число узлов n, степень полинома m, затем n пар точек (xi, fi). После вычисления коээфициентов полинома МНК степени m можно ввести границы по оси X и шаг по X для построения значений полинома.

{Метод наименьших квадратов}
program Mnk;
uses crt; {модуль управления экраном}
type matrix=array[0..100,0..100] of real;
     vector=array [0..100] of real; {Нумеруем точки с нуля}
var n,m,k,i:integer;
    x,f,c:vector;
    a:matrix;
    x0,x9,h,x1:real;
 
procedure InputData (n:integer; var x,f:vector); {Ввод исходных данных}
begin
 for i:=0 to n do begin
  write ('Введите пару значений X(',i,'),F(',i,'):');
  readln (x[i],f[i]);
 end;
end;
 
function ex (a:real; n:integer):real;
 {Показательная функция для формирования матрицы Грама}
var i:integer;
    e:real;
begin
 e:=1;
 for i:=1 to n do e:=e*a;
 ex:=e;
end;
 
procedure Gram (n,m:integer; var x,f:vector; var a:matrix);
{Формирование матрицы Грама A по векторам данных X,F}
var i,j:integer;
    p,q,r,s:real;
begin
 for j:=0 to m do begin
  s:=0; r:=0; q:=0;
  for i:=0 to n do begin
   p:=ex(x[i],j);
   s:=s+p;
   r:=r+p*f[i];
   q:=q+p*ex(x[i],m);
  end;
  a[0,j]:=s;
  a[j,m]:=q;
  a[j,m+1]:=r;
 end;
 {Надо формировать только 1-ю строку и 2 последних столбца матрицы Грама,
  остальные элементы легко получить циклическим копированием:}
 for i:=1 to m do
 for j:=0 to m-1 do a[i,j]:=a[i-1,j+1];
end;
 
procedure Gauss(n:integer; var a:matrix; var x:vector);
{Решение СЛАУ методом Гаусса}
{a - расширенная матрица системы, x - вектор результата}
var i,j,k,l,k1,n1:integer;
    r,s:real;
begin
 {Прямой ход:}
 n1:=n+1;
 for k:=0 to n do begin
  k1:=k+1;
  s:=a[k,k];
  for j:=k1 to n1 do a[k,j]:=a[k,j]/s;
  for i:=k1 to n do begin
   r:=a[i,k];
   for j:=k1 to n1 do a[i,j]:=a[i,j]-a[k,j]*r;
  end;
 end;
 {Обратный ход:}
 for i:=n downto 0 do begin
  s:=a[i,n1];
  for j:=i+1 to n do s:=s-a[i,j]*x[j];
  x[i]:=s;
 end;
end;
 
function fi (m:integer; var c:vector; x1:real):real;
{Аппроксимирующая функция по найденным коэффициентам МНК}
{m - степень полинома, c - вектор коэффициентов,
 x1 - точка, в которой ищем значение}
var i:integer; p:real;
begin
 p:=c[m];
 for i:=m-1 downto 0 do p:=c[i]+x1*p;
 fi:=p;
end;
 
begin
 clrscr; {очистить экран}
 writeln ('Подбор зависимости методом наименьших квадратов');
 write ('Введите число узлов (1<n<100):');
 read (n);
 n:=n-1; {нумерация будет с нуля!}
 write ('Введите степень полинома (1<=m<=',n,'):');
 read (m);
 InputData (n,x,f); {вводим данные}
 Gram (n,m,x,f,a); {считаем матрицу Грама}
 Gauss (m,a,c); {решаем систему линейных уравнений}
 
 writeln ('Коэффициенты полинома МНК ',m,' степени:');
 for i:=0 to m do write (c[i]:10:4);
 writeln;
 
 writeln ('Введите границы по оси X для построения полинома:');
 read (x0,x9);
 writeln ('Введите шаг по X для построения значений полинома:');
 read (h);
 k:=round((x9-x0)/h+1);
 x1:=x0;
 for i:=1 to k do begin
  {строим и выводим полином по найденным коэффициентам}
  writeln (x1:10:4,fi(m,c,x1):10:4);
  x1:=x1+h;
 end;
 reset (input); readln;
end.

Пример вывода программы:

Подбор зависимости методом наименьших квадратов
Введите число узлов (1<n<100):4
Введите степень полинома (1<=m<=3):2
Введите пару значений X(0),F(0):0 0
Введите пару значений X(1),F(1):1 1
Введите пару значений X(2),F(2):2 4
Введите пару значений X(3),F(3):3 9
Коэффициенты полинома МНК 2 степени:
    0.0000    0.0000    1.0000
Введите границы по оси X для построения полинома:
-1 4
Введите шаг по X для построения значений полинома:
1
   -1.0000    1.0000
    0.0000    0.0000
    1.0000    1.0000
    2.0000    4.0000
    3.0000    9.0000
    4.0000   16.0000

Рейтинг@Mail.ru

вверх гостевая; E-mail
Hosted by uCoz