Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 06.04.2012, 21:08
Noqrax Noqrax вне форума
Прохожий
 
Регистрация: 06.04.2012
Сообщения: 8
Репутация: 10
Восклицание Рекуррентное нахождение определителя матрицы по правилу Лапласа

Здравствуйте!
В ходе работы над моей программой, у меня возникло много проблем с динамическими массивами. Дело в том, что я хочу задать рекуррентную функцию для нахождения определителя матрицы любого размера по правилу Лапласа.
В принципе с самим алгоритмом мне все ясно, если заменить динамические массивы на статические, то всё нормально работает. Однако я совсем не понимаю как это сделать через динамические массивы.
Подскажите, что не так в моём коде. =D

Код:
program LaplasRule;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  arr:array of array of real; {исходная матрица}
  det:integer;

function lap(arr:array of array of real): real; {собственно тут ошибка}

var
  i,j,l,s:integer; {i-строка; j-столбец; l-столбец, по которуму расскладываем; s-размер исходной матрицы}
  brr:array of array of real; {матрица алгеброического дополнения}

begin
  s:=high(arr);
  if s<>0 then
    begin
      setlength(brr,s,s);
      for l:=0 to s do {выбираем столбец по которому раскладываем}
      begin
        for j:=0 to dec(l) do {перенос элементов из исх. матрицы в матрицу алг. доп.}
          for i:=1 to s do
            brr[i-1,j]:=arr[i,j];
        for j:=inc(l) to s do
          for i:=1 to s
            brr[i-1,j-1]:=arr[i,j];
        lap:=arr[1,l]*lap(brr)*intpower(-1,l+1)+lap
      end
    end
  else
    lap:=arr[1,1] {для случая когда матрица 1x1 :3}
end;


begin
  setlength(arr,4,4); {исходная матрица}
  arr[0,0]:=3;
  arr[0,1]:=3;
  arr[0,2]:=4;
  arr[0,3]:=2;
  arr[1,0]:=1;
  arr[1,1]:=2;
  arr[1,2]:=2;
  arr[1,3]:=1;
  arr[2,0]:=1;
  arr[2,1]:=3;
  arr[2,2]:=4;
  arr[2,3]:=1;
  arr[3,0]:=0;
  arr[3,1]:=1;
  arr[3,2]:=1;
  arr[3,3]:=1; {определитель исходной матрицы равен 1}
  det:=lap(arr);
  writeln(det) {вывод определителя}
end.

Заранее спасибо,
Noqrax.
Ответить с цитированием
  #2  
Старый 06.04.2012, 21:55
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Ну не понимаю я стремления передавать в процедуры/функции указатель на глобальную переменную.
Код:
  function lap(locarr : arr) : Single;
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #3  
Старый 06.04.2012, 22:04
Аватар для cotseec
cotseec cotseec вне форума
Активный
 
Регистрация: 16.07.2008
Сообщения: 353
Версия Delphi: D7,TDE06,RAD09
Репутация: 1443
По умолчанию

Код:
uses
  SysUtils;

type
   TArr:array of array of single;

var
  arr:TArr; {исходная матрица}
  det:integer;

function lap(locarr :TArr): single;
......
Ответить с цитированием
  #4  
Старый 06.04.2012, 22:06
Noqrax Noqrax вне форума
Прохожий
 
Регистрация: 06.04.2012
Сообщения: 8
Репутация: 10
Злость

1) А разве имеет значение какую переменную я укажу внутри функции?
2) Почему я вообще должен вводить новый тип чтобы использовать в процедуре/функции?
3) И даже если произвести все изменения выводит ошибку о несовместимых типах. Тут я уже совсем не пойму... =/

Последний раз редактировалось Noqrax, 06.04.2012 в 22:19.
Ответить с цитированием
  #5  
Старый 06.04.2012, 22:37
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Noqrax
В принципе с самим алгоритмом мне все ясно, если заменить динамические массивы на статические, то всё нормально работает.
Уверен?

Цитата:
Сообщение от Noqrax
... И даже если произвести все изменения выводит ошибку о несовместимых типах. Тут я уже совсем не пойму... =/
Вот когда все свои ляпы исправишь, в якобы рабочем коде, тогда и все вопросы сами собой решатся.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #6  
Старый 06.04.2012, 23:32
Noqrax Noqrax вне форума
Прохожий
 
Регистрация: 06.04.2012
Сообщения: 8
Репутация: 10
Злость

Уверен? Конечно, потому, что первым делом я написал программу со статическими массивами. Самое интересное, что я использовал глобальные переменные в задании функции и это мне ничем не помешало написать рабочую программу. Может это и дурной тон, но лично я в этом не вижу смысла, если работает и так. Да и поменять single на real не так важно.

Что касается остальных недочетов... Да я мог что-то из-за невнимательности не дописать:
Код:
 for j:=inc(l) to s do
          for i:=1 to s
            brr[i-1,j-1]:=arr[i,j];
Только подобные ошибки никак не влияют на типы переменных. И честно говоря, других ошибок я не нашел. Буду рад, если вы на них укажете. И ещё сильнее, если объясните почему это ошибка.
Ответить с цитированием
  #7  
Старый 06.04.2012, 23:49
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Ну тогда с вами всё ясно:
Код:
for j:=0 to dec(l)
компилятор просто обожает такие конструкции
Код:
  s:=high(arr);
...
      setlength(brr,s,s);
задать массив заведомо меньше оригинала, конечно это не ляп.
Код:
lap:=arr[1,l]*lap(brr)*intpower(-1,l+1)+lap
забыл включить модуль Math? Да пусть компилятор сам разбирается что нужно.
это вообще шедевр программирования
Код:
  det:=lap(arr);
  writeln(det) {вывод определителя}
К тому же хочу, чтобы он сам сконвертировал число с плавающей запятой в целое.

P.S. Уважаемый, идите пудрить мозги в другое место.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #8  
Старый 07.04.2012, 10:27
nixel nixel вне форума
Начинающий
 
Регистрация: 12.12.2011
Адрес: Москва
Сообщения: 150
Версия Delphi: XE2-U4
Репутация: 131
По умолчанию

To angvelem
Уважаемый, Вы хотя бы день можете провести без оскорблений и переходов на личности на форуме?
Ответить с цитированием
Этот пользователь сказал Спасибо nixel за это полезное сообщение:
Noqrax (07.04.2012)
  #9  
Старый 07.04.2012, 10:51
Noqrax Noqrax вне форума
Прохожий
 
Регистрация: 06.04.2012
Сообщения: 8
Репутация: 10
Сообщение

Спасибо за найденные ошибки. Но проблему не решило.

Что касается массива brr, то он и должен быть меньше оригинального. Т.к. если раскладывать по одной строке то в качестве алг. дополнения будет выступать матрица меньшей размерности.

Вот исправленная версия:
Код:
program LaplasRule;

{$APPTYPE CONSOLE}

uses
  SysUtils,Math;

type
  darr = array of array of single;

var
  arr:darr; {исходная матрица}
  det:real;

function lap(crr:darr): single; {собственно тут ошибка}

var
  i,j,l,s:integer; {i-строка; j-столбец; l-столбец, по которуму расскладываем; s-размер исходной матрицы}
  brr:array of array of single; {матрица алгеброического дополнения}

begin
  s:=high(crr);
  if s<>0 then
    begin
      setlength(brr,s,s);
      for l:=0 to s do {выбираем столбец по которому раскладываем}
      begin
        for j:=0 to l-1 do {перенос элементов из исх. матрицы в матрицу алг. доп.}
          for i:=1 to s do
            brr[i-1,j]:=crr[i,j];
        for j:=l+1 to s do
          for i:=1 to s do
            brr[i-1,j-1]:=crr[i,j];
        lap:=crr[1,l]*lap(brr)*intpower(-1,l+1)+lap
      end
    end
  else
    lap:=crr[1,1] {для случая когда матрица 1x1 :3}
end;


begin
  setlength(arr,4,4); {исходная матрица}
  arr[0,0]:=3;
  arr[0,1]:=3;
  arr[0,2]:=4;
  arr[0,3]:=2;
  arr[1,0]:=1;
  arr[1,1]:=2;
  arr[1,2]:=2;
  arr[1,3]:=1;
  arr[2,0]:=1;
  arr[2,1]:=3;
  arr[2,2]:=4;
  arr[2,3]:=1;
  arr[3,0]:=0;
  arr[3,1]:=1;
  arr[3,2]:=1;
  arr[3,3]:=1; {определитель исходной матрицы равен 1}
  det:=lap(arr);
  writeln(det) {вывод определителя}
end.

Здесь компилятор выдает:
Код:
lap:=crr[1,l]*lap(brr)*intpower(-1,l+1)+lap
      end
Такие ошибки:
Код:
[Error] LaplasRule.dpr(34): Incompatible types
[Error] LaplasRule.dpr(35): Not enough actual parameters
Ответить с цитированием
  #10  
Старый 07.04.2012, 11:07
nixel nixel вне форума
Начинающий
 
Регистрация: 12.12.2011
Адрес: Москва
Сообщения: 150
Версия Delphi: XE2-U4
Репутация: 131
По умолчанию

Цитата:
Сообщение от Noqrax
Здесь компилятор выдает:
Код:
lap:=crr[1,l]*lap(brr)*intpower(-1,l+1)+lap
      end
Такие ошибки:
Код:
[Error] LaplasRule.dpr(34): Incompatible types
[Error] LaplasRule.dpr(35): Not enough actual parameters

Попробуйте lap без параметров заменить на Result.
Ответить с цитированием
  #11  
Старый 07.04.2012, 11:26
Noqrax Noqrax вне форума
Прохожий
 
Регистрация: 06.04.2012
Сообщения: 8
Репутация: 10
Сообщение

Вторая ошибка решилась.
Но по-прежнему ошибка несовместимости данных.
Ответить с цитированием
  #12  
Старый 07.04.2012, 11:42
nixel nixel вне форума
Начинающий
 
Регистрация: 12.12.2011
Адрес: Москва
Сообщения: 150
Версия Delphi: XE2-U4
Репутация: 131
По умолчанию

Цитата:
Сообщение от Noqrax
Вторая ошибка решилась.
Но по-прежнему ошибка несовместимости данных.
Вообще, power и intpower возвращают extended. Попробуйте вызов через round(intpower(x, y)) для перевода результата возведения в степень в тип integer.
Тогда компилятору нужно будет расширять инт до сингл, а не пытаться изменить тип возвращаемого функцией значения,
Ответить с цитированием
  #13  
Старый 07.04.2012, 12:02
Noqrax Noqrax вне форума
Прохожий
 
Регистрация: 06.04.2012
Сообщения: 8
Репутация: 10
Сообщение

Я нашел проблему. Она банальная. Заменил brr: array of array of single;
на brr: darr; и программа наконец скомпилировалась. Но теперь новая проблема. Программа считает, что рекурсия бесконечна, хотя это не так. (Ну или должно быть не так =3)
Ответить с цитированием
  #14  
Старый 07.04.2012, 20:24
nixel nixel вне форума
Начинающий
 
Регистрация: 12.12.2011
Адрес: Москва
Сообщения: 150
Версия Delphi: XE2-U4
Репутация: 131
По умолчанию

Цитата:
Сообщение от Noqrax
Я нашел проблему. Она банальная. Заменил brr: array of array of single;
на brr: darr; и программа наконец скомпилировалась. Но теперь новая проблема. Программа считает, что рекурсия бесконечна, хотя это не так. (Ну или должно быть не так =3)
Вряд ли конечно поможет, но попробуйте сделать brr глобальной переменной.
Ответить с цитированием
  #15  
Старый 07.04.2012, 21:32
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от nixel
To angvelem
Уважаемый, Вы хотя бы день можете провести без оскорблений и переходов на личности на форуме?
Где я перешёл на личности и оскорбил? Ткнул носом в ляпы человека упорно доказывающего невозможное? Или, если я всё исправлю за ТС, то стану белым и пушистым? Ну-ну...
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:17.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter