Задали написать програму вычисления собственных значений матрицы (можно еще и вектора) прямым методом. Поясните пожалуйста, что это за метод такой? Вот этот или нет? У меня есть исходники метода Якоби. Он подойдет в качестве прямого или нет?
Shmaniche
12.04.2013 9:26
В одной книжке нашел код программы, которая как раз вычисляет собственные значения матрицы прямым ходом. Но она не компилируется, компилятор ругается на строку «procedure Secant(var x0, x, e: real; function F:real);», а именно на «function F:real». Подскажите где что пропущено. Свою процедуру вывода я закомментировал, оставил все как учебнике за исключением своей процедуры ввода матрицы.
Полный код:
program sobst_znach_matr; {Найти собстсвенное значение матрицы прямым ходом}
uses crt; const c=10; type mat=array [1..c, 1..c] of real; var A, B: mat; n: integer; x0, x, e: real;
{Процедура ввода матрицы} procedure Matr_Vvod(n: integer; var A:mat); var i, j: integer; begin writeln('Вводите коэфф-ты матpицы A по стpокам нажимая ENTER:'); for i:=1 to n do for j:=1 to n do begin write ('a[',i,',',j,']='); {Ввод матрицы} read(a[i,j]); end; end;
{Процедура вывода матрицы} {procedure Matr_Vivod(n: integer; var A:mat); var i, j: integer; begin for i:=1 to n do begin for j:=1 to n do write (a[i, j]:5:3,' ':2); {Вывод матрицы с отступами} { writeln; end; end;
{Процедура вычисления определителя} procedure Det(n: integer; var A:mat; var s:real); var i, j, k, k1: integer; p, r: real; begin p:=1.0; for k:=1 to n-1 do begin k1:=k+1; s:=A[k,k]; j:=k; for i:=k1 to n do begin r:=A[i,k]; if abs® > abs(s) then begin s:=r; j:=i; end; end; if s=0.0 then exit; if j<>p then begin p:=-p; for i:=k to n do begin r:=A[k,i]; A[k,i]:=A[j,i]; A[j,i]:=r; end; end; for j:=k1 to n do A[k,j]:=A[k,j] / s; for i:=k1 to n do begin r:=A[i,k]; for j:=k1 to n do A[i,j]:=A[i,j] - A[k,j] * r; end; p:=p * s; end; s:=p * A[n,n]; end;
function F(x:real):real; var i, j: integer; s: real; begin for i:=1 to n do for j:=1 to n do if i=j then A[i,i]:=B[i,i] - x else A[i,j]:=B[i,j]; Det(n,a,s); F:=s; end;
{Метод секущих} procedure Secant(var x0, x, e: real; function F:real); var d, y, r: real; begin r:=x-x0; d:=F(x0); repeat y:=F(x); r:=r / (d - y) * y; d:=y; x:=x + r; until abs® < e; end;
begin clrscr;
writeln('Вычислить собстывенное значение матрицы.'); writeln; { writeln('Введите кол-во элементов в строке матрицы и нажмите ENTER'); writeln('(Число элементов в строке будет равно числу элементов в столбце!):'); readln (n); writeln; }
From this example, the difference with Turbo Pascal is clear: In Turbo Pascal it isn’t necessary to use the address operator (@) when assigning a procedural type variable, whereas in Free Pascal it is required. In case the -MDelphi or -MTP switches are used, the address operator can be dropped.
Или, в данном случае
Код
Secant(x0,x,e,@F);
Shmaniche
16.04.2013 15:33
Цитата(Федосеев Павел @ 14.04.2013 22:58)
Или, в данном случае
Код
Secant(x0,x,e,@F);
Компилятор прордлжает ругаться на эту строку: "Error 122: Invalid varibale reference".
Shmaniche
17.04.2013 9:46
Похоже, что «function F:real» в строке «procedure Secant(var x0, x, e: real; function F:real);» вовсе и не нужна, она уже объявлена выше, также в строке «Secant(x0,x,e,F);» убрать F. Тогда все компилируется.
IUnknown
17.04.2013 10:52
Цитата
Тогда все компилируется
И в итоге получается слабая тень той программы, которая была написана в книге. Потому что основная цель программы, приведенной в посте №2 - это вызов Secant с ЛЮБОЙ функцией, которая передается в качестве параметра. А то, что получилось у тебя - это тупой вызов вышеописанной функции, строго заданной, и ТОЛЬКО ОДНОЙ. Работать, возможно, будет, но только... О гибкости программы, приведенной в книге здесь и речи уже не идет.
А вообще, по правилам хорошего тона, надо в первом посте указывать, какой у тебя компилятор, а не устраивать тут филиал форума гадалок на кофейной гуще. Хотя о чем это я... Тебе что говори, что нет. Были прецеденты. Всё равно сделаешь по своему, еще и все виноватыми окажутся...
Shmaniche
17.04.2013 18:44
IUnknown
Компилирую в Турбо Паскале 7.0, ест-но. А что толку? Все равно же не скажите как правильно исправить процедуру?! Ой, зануда... Да еще и злопамятный видать! Я вооще забыл о чем мы тогда спорили.
Добавлено через 12 мин. Меня еще пара вопросов интереует. Строки
write ('n, x0, x, e :'); readln (n, x0, x, e);
предназначены для ввода размера матрицы ”n”, два начальных приближения ”x0”, ”x” к одному из собственных значений матрицы и допустимую погрешность решения характеристического уравнения ”e”. Собственно, что это за начальные приближения ”x0”, ”x”? Охота разобраться. Для удобства ввода этих параметров я изменил эти две строки на такие:
writeln('Вычислить собственные значения матрицы.'); writeln; writeln('Введите кол-во элементов в строке матрицы и нажмите ENTER'); writeln('(Число элементов в строке будет равно числу элементов в столбце!):'); readln (n); writeln; writeln('Введите 1-ое начальное приближение "x0" и нажмите ENTER:'); readln (x0); writeln; writeln('Введите 2-ое начальное приближение "x" и нажмите ENTER:'); readln (x); writeln; writeln('Введите допустимую погрешность и нажмите ENTER:'); readln (e); writeln;
Shmaniche
18.04.2013 8:16
Короче, раз некоторые здесь страдают манией величия и пальцем не пошевелят, чтобы помочь студенту, конечно приходиться перебирать варианты самому . Вот нашел подходящий пример:
Метод секущих для решения трансцендентного уравнения f(x) = 0. x, x0 – два начальных приближения, e - оценка точности получаемого решения, итерационный процесс прекращается при приближении f(x) к нулю меньше, чем на e, x – искомый корень.