Приведение квадратичной формы поверхности к каноническому виду методом Якоби
Здравствуйте. Пытаюсь написать программу, которая приводит уравнение поверхности
к каноническому виду, т.е. к сумме квадратов. Использую метод Якоби, при котором, как я понял, матрица из коэффициентов приводится к треугольному виду. Программа для приведения матрицы к треугольному виду есть:
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, Spin;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
SpinEdit1: TSpinEdit;
Label3: TLabel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type Tmatrix=array of array of real;
var
Form1: TForm1;
a:Tmatrix;
n:integer;
implementation
{$R *.dfm}
//перестановка строк, чтобы исключить, если это возможно
//деление на ноль, или число, близкое к нолю
procedure Per(k,n:integer;var a:Tmatrix);
var j,i,p:integer;z:Real;
begin
z:=a[k,k];i:=k; //текущая строка
for j:=k+1 to n-1 do //ниже ее
begin
if abs(a[j,k])>z then //ищем в этом столбце максимальный элемент
begin
z:=a[j,k];
i:=j;
end;
end;
if i>k then //если нашли
begin
for p:=k to n do //переставляем строки
begin
z:=a[i,p];a[i,p]:=a[k,p];a[k,p]:=z;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
n:=SpinEdit1.Value;
StringGrid1.ColCount:=n;
StringGrid1.RowCount:=n;
StringGrid2.ColCount:=n;
StringGrid2.RowCount:=n;
Showmessage('Введите в таблицу коэффициенты a[i,j]');
end;
procedure TForm1.Button2Click(Sender: TObject);
var i,j,k:integer;
r:real;
begin
//создание матрицы
Setlength(a,n,n);
for i:=0 to n-1 do
for j:=0 to n-1 do
a[i,j]:=StrToFloat(StringGrid1.Cells[j,i]);
//преобразование
for k:=0 to n-1 do
begin
Per(k,n,a); //перестановка
for j:=k+1 to n-1 do
begin
r:=a[j,k]/a[k,k];
for i:=k to n-1 do
a[j,i]:=a[j,i]-r*a[k,i];
a[j,n]:=a[j,n]-r*a[k,n];
end;
end;
//вывод результата
for i:=0 to n-1 do
for j:=0 to n-1 do
StringGrid2.Cells[j,i]:=FloatToStrF(a[i,j],ffFixed,6,2);
end;
end.
Вот только есть одно НО: если один из миноров матрицы равен нулю, то нужно делать перенумерацию переменных, а как это задать-не знаю... Например(Ссылка на сайт)
[SPOILER]http://mathhelpplanet.com/static.php?p=privedenie-kvadratichnoi-formy-k-kanonicheskomu-vidu[/SPOILER]
У матрицы
минор второго порядка равен нулю, поэтому там меняют x1<->x3, при этом получаем
И диагональные элементы полученной матрицы являются коэффициентами канонического уравнения.
|