IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Вычислить собственные значения матрицы и вектор, Прямым методом
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 79
Пол: Мужской

Репутация: -  0  +


Задали написать програму вычисления собственных значений матрицы (можно еще и вектора) прямым методом. Поясните пожалуйста, что это за метод такой? Вот этот или нет? У меня есть исходники метода Якоби. Он подойдет в качестве прямого или нет?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Пионер
**

Группа: Пользователи
Сообщений: 79
Пол: Мужской

Репутация: -  0  +


В одной книжке нашел код программы, которая как раз вычисляет собственные значения матрицы прямым ходом. Но она не компилируется, компилятор ругается на строку «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(r) > 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(r) < e;
  end;

 begin
  clrscr;

  writeln('Вычислить собстывенное значение матрицы.');
  writeln;
{  writeln('Введите кол-во элементов в строке матрицы и нажмите ENTER');
  writeln('(Число элементов в строке будет равно числу элементов в столбце!):');
  readln (n);
  writeln;
  }

  write ('n, x0, x, e :');
  readln (n, x0, x, e);

  Matr_Vvod(n,A); {Ввод матрицы}
  {writeln;
  Matr_Vivod(n,A); {Вывод матрицы}

  Secant(x0,x,e,F);

  writeln ('Lyamda=', x);

 readkey;

end.

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Знаток
****

Группа: Пользователи
Сообщений: 481
Пол: Мужской
Реальное имя: Федосеев Павел

Репутация: -  9  +


Думаю, что нужно объявить тип
Код
type
  TFuncReal=function (x: real): real;

И использовать этот тип при описании функции
Код
procedure Secant(var x0, x, e: real; F: TFuncReal);
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Пионер
**

Группа: Пользователи
Сообщений: 79
Пол: Мужской

Репутация: -  0  +


Цитата(Федосеев Павел @ 14.04.2013 22:13) *

Думаю, что нужно объявить тип
Код
type
  TFuncReal=function (x: real): real;

И использовать этот тип при описании функции
Код
procedure Secant(var x0, x, e: real; F: TFuncReal);



В таком случае компилятор ругается на строчку

 Secant(x0,x,e,F);



Недопустимая процедура или фукнция.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Знаток
****

Группа: Пользователи
Сообщений: 481
Пол: Мужской
Реальное имя: Федосеев Павел

Репутация: -  9  +


Читаем главу "Procedural types":
Цитата
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);
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Пионер
**

Группа: Пользователи
Сообщений: 79
Пол: Мужской

Репутация: -  0  +


Цитата(Федосеев Павел @ 14.04.2013 22:58) *

Или, в данном случае
Код
Secant(x0,x,e,@F);



Компилятор прордлжает ругаться на эту строку: "Error 122: Invalid varibale reference". wacko.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Пионер
**

Группа: Пользователи
Сообщений: 79
Пол: Мужской

Репутация: -  0  +


Похоже, что «function F:real» в строке «procedure Secant(var x0, x, e: real; function F:real);» вовсе и не нужна, она уже объявлена выше, также в строке «Secant(x0,x,e,F);» убрать F. Тогда все компилируется. cool.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Тогда все компилируется
И в итоге получается слабая тень той программы, которая была написана в книге. Потому что основная цель программы, приведенной в посте №2 - это вызов Secant с ЛЮБОЙ функцией, которая передается в качестве параметра. А то, что получилось у тебя - это тупой вызов вышеописанной функции, строго заданной, и ТОЛЬКО ОДНОЙ. Работать, возможно, будет, но только... О гибкости программы, приведенной в книге здесь и речи уже не идет.

А вообще, по правилам хорошего тона, надо в первом посте указывать, какой у тебя компилятор, а не устраивать тут филиал форума гадалок на кофейной гуще. Хотя о чем это я... Тебе что говори, что нет. Были прецеденты. Всё равно сделаешь по своему, еще и все виноватыми окажутся...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Пионер
**

Группа: Пользователи
Сообщений: 79
Пол: Мужской

Репутация: -  0  +


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 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Пионер
**

Группа: Пользователи
Сообщений: 79
Пол: Мужской

Репутация: -  0  +


Короче, раз некоторые здесь страдают манией величия и пальцем не пошевелят, чтобы помочь студенту, конечно приходиться перебирать варианты самому dry.gif . Вот нашел подходящий пример:

Метод секущих для решения трансцендентного уравнения f(x) = 0.
x, x0 – два начальных приближения, e - оценка точности получаемого решения, итерационный процесс прекращается при приближении f(x) к нулю меньше, чем на e, x – искомый корень.




function f(x: real): real;

begin

{ конкретизация функции f(x) }

end;

procedure secant(var x0, x: real; e: 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(r) < e;

end;



Источник

cool.gif

Объявление функции в строке "procedure secant(var x0, x: real; e: real);" тут даже и не пахнет!


Сообщение отредактировано: Shmaniche -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 19.04.2025 15:36
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name