Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Delphi] Операция над матрицей


Автор: Digo 6.1.2007, 21:33
Доброго времени суток!
Есть функция(подключаю из модуля) по работе с матрицами(например транспонирование)
Код

Unit Matrix; 

interface 

type 
   MatrixPtr = ^MatrixRec; 
   MatrixRec = record 
     MatrixRow   : byte; 
     MatrixCol   : byte; 
     MatrixArray : pointer; 
   end; 
   MatrixElement = real; 
(* Функция транспонирует матрицу *) 
function TransponeMatrix(MPtr : MatrixPtr) : MatrixPtr; 

implementation 

function TransponeMatrix(MPtr : MatrixPtr) : MatrixPtr; 
var 
  TempPtr : MatrixPtr; 
  i,j     : byte; 
begin 
  if (MPtr <> nil) or (MPtr^.MatrixArray <> nil) then with MPtr^ do begin 
    TempPtr:= CreateMatrix(MatrixCol,MatrixRow); 
    for i:= 1 to MatrixRow do 
      for j:= 1 to MatrixCol do 
        SetMatrixElement(TempPtr,j,i,GetMatrixElement(MPtr,i,j)); 
    TransponeMatrix:= TempPtr; 
  end else TransponeMatrix:= nil; 
end; 


 и stringgrid1.Cells[i,j] где задается матрица с которой будем делать разные операции вопрос возможно очень дуратский.... как обработать грид с помощью этой функции(т.е. передать данные из таблицы в функцию) и вывести результат например в другой stringgrid... 

Автор: Sunvas 6.1.2007, 22:00
Цитата(Digo @  6.1.2007,  21:33 Найти цитируемый пост)
как обработать грид с помощью этой функции(т.е. передать данные из таблицы в функцию) и вывести результат например в другой stringgrid

А в чем, собственно вопрос - как "подкрутить" функцию под работу с гридом или как в переменную матрицы забить значения грида?

Автор: Digo 7.1.2007, 13:21
Помоему будет проще просто перекидывать данные из stringgrid в функцию(т.е. создавать матрицу и запихивать в нее данные из грида) далее расчитываем получаем уже транспонированную матрицу, проблема в том что не пойму как перенести содержимое гирда в функцию для расчета...

Автор: Sunvas 7.1.2007, 13:25
Digo, недоконца ты привел исходны код.
Вот тебе пример:
Код

var i,j:word;
begin
for i to StringGrid1.rowcount do
for j to StringGrid1.ColCount do
a[i,j]:=StringGrid1.Cells[i,j];

Поможет?

Автор: VICTAR 7.1.2007, 13:36
а что такое a[i,j]? этот массив тоже ж надо объявить?

и 
Код

var a: array of array of real;
    i,j: word;
begin
SetLength(a,StringGrid1.ColCount);
for i:=0 to pred(StringGrid1.ColCount)
  do SetLength(a[i],StringGrid1.rowcount);

for j:=0 to pred(StringGrid1.rowcount) do
for i:=0 to pred(StringGrid1.ColCount) do
a[i,j]:=StrToFloat(StringGrid1.Cells[i,j]);



Автор: Digo 7.1.2007, 15:41
Собственно модуль довольно извесный весь его код тут(я привел только 1 функцию чтобы не загромождать всеsmile) http://www.megalib.com/books/478/1584.htm
То что вы описали это понятно - перевод в масив из гирда... мне интересно как это все запихать в функцию вызываемую из того модуля что я привел, ну например matirx.TransponeMatrix(????); нужно соответствие типов, там вообще все через record сделано...

Автор: Sunvas 7.1.2007, 15:44
Цитата(Digo @  7.1.2007,  15:41 Найти цитируемый пост)
там вообще все через record сделано...

Ну тогда записывай и грида в рекорд. В чем проблеммы?

Автор: Digo 7.1.2007, 16:12
проблема как раз в том что плохо себе представляю как это сделать smile 

Автор: VICTAR 7.1.2007, 16:27
Код

procedure TForm1.Button1Click(Sender: TObject);
var i,j: word;
    mtr,mtr2: MatrixPtr;
begin
mtr:=CreateMatrix(StringGrid1.rowcount,StringGrid1.ColCount);

for j:=0 to pred(StringGrid1.rowcount) do
  for i:=0 to pred(StringGrid1.ColCount) do
    SetMatrixElement(mtr,j+1,i+1,StrToFloat(StringGrid1.Cells[i,j]));

mtr2:=TransponeMatrix(mtr);
StringGrid2.RowCount:=mtr2.MatrixRow;
StringGrid2.ColCount:=mtr2.MatrixCol;

for j:=0 to pred(StringGrid2.rowcount) do
  for i:=0 to pred(StringGrid2.ColCount) do
    StringGrid2.Cells[i,j]:=FloatToStr(GetMatrixElement(mtr2,j+1,i+1));

DeleteMatrix(mtr);
DeleteMatrix(mtr2);
end;

Автор: Guedda 7.1.2007, 17:44
Я считаю, что просто необходимо переделать структуру record, и переписать функцию под StringGrid.

Автор: VICTAR 7.1.2007, 17:49
Да вроде и так все удобно... ИМХО хороший модуль

Автор: Digo 7.1.2007, 19:35
Спасибо VICTAR,  за пример, работает все! А модуль действительно хороший,  почти все операции стандартные с матрицами есть...

Автор: Digo 8.1.2007, 18:22
Сейчас копнул глубже столкнулся с проблемой:
функция обращения матрицы не желает работать  ReverseMatrix(MPtr : MatrixPtr) : MatrixPtr; 
в приведенном выше коде ошибка выскакивает на 12 строке (StringGrid2.RowCount:=mtr2.MatrixRow;) то же самое и с умножением матрицы на матрицу... Пишет Access Volation at address...
хотя умножение на число и транспонирование работают

Автор: VICTAR 8.1.2007, 20:40
Да, ты прав. Похоже проблема в самом модуле. Поэтому надо его как следует поизучать.
ЗЫ я нашел еще один похожий модуль, но я его пока еще не смотрел http://matrix.kladovka.net.ru/

Автор: Digo 9.1.2007, 11:42
Там все куда более наворочено(в приведенном новом модуле), а ошибка выскакивает уже в новой матрице которя расчитывается, кстати заметил определитель тоже не считает всегда 0...

Автор: VICTAR 9.1.2007, 17:38
По ходу, я погорячился, сказав, что модуль хороший... Определитель считается только тогда, когда матрица является квадратной. Плюс, я нашел еще несколько ошибок. Короче говоря, придется или конкретно исправлять этот модуль, или писать свой, или использовать Matrix32.  smile 

Автор: Digo 9.1.2007, 18:22
Ясно, чувствую придется так и делать, но matrix32 для моих задач довольно мудренный...
Кстати как вариант http://sources.codenet.ru/download/1157/TMatrix.html
как потестю его отпишусьsmile

Автор: Digo 9.1.2007, 23:19
Пока могу сказать следущее: по функциональности модуль ничем не уступает matrix помоему даже нагляднее и удобнее организован ввод и другие моменты... 
Особено понравилась возможность
 constructor Create(AArray: TMatrixData); overload;    // Создаёт матрицу из массива
я только не разобрался как помещать данные из Stringgrid...
приходится юзать mtr.Items[i,j] 
Протестировал опять те же функции транспонирование работает, обращение нет, пишет якобы детерменант =0 поэтому не считает... похоже проблема в этом, прям тенденция какая то, очень станно не может же быть что все глючит...

Автор: VICTAR 9.1.2007, 23:35
Не работает все по той же причине, что дет-нант вычисляется только у квадратной матрицы. 
mtr.Items[i,j]  - правильный ход

Автор: Digo 10.1.2007, 00:03
у меня даже NxN не считает... возможно ввожу не так что-то а так думаю и квадратная сгодилась быsmile лишь бы считала, можешь код скинуть или пример для ввода который  считает?
наверно алгоритм для неквадратных сложен... от того и не делают его нигде...

Автор: VICTAR 10.1.2007, 00:18
Код

var i,j: word;
    mtr1, mtr2:TMatrix;
begin
mtr1:=TMatrix.Create(StringGrid1.rowcount,StringGrid1.ColCount);
  for j:=0 to pred(StringGrid1.rowcount) do
    for i:=0 to pred(StringGrid1.ColCount) do
      StringGrid1.Cells[i,j]:=IntTosTR(random(9));
 for j:=0 to pred(StringGrid1.rowcount) do
  for i:=0 to pred(StringGrid1.ColCount) do
    mtr1.Items[j,i]:=StrToFloat(StringGrid1.Cells[i,j]);


Только не могу понять это:
Код

Create(Matrix: TMatrix); 
Clone(var Matrix: TMatrix): Boolean;

Они работаю явно не так как должны. Создаются пустые матрицы и при любом обращении к ее элементам возникает ошибка.

Автор: VICTAR 10.1.2007, 01:18
Все, я нашел ошибку и в этом модуле smile. Постараюсь завтра исправить и выложить готовый проект. Код, приведенный выше будет работать не всегда.

Автор: VICTAR 10.1.2007, 15:49
Ок. Теперь все работает. Косяк был в том, что при созданиии TMatrix.Create(const ARows, ACols: Word);  Origin был равен 0, а не 1, как должен быть по-умолчанию. 
Выкладываю http://victar.megann.net/Downloads/MatrixPrj.rar с основными действиями

Автор: Digo 11.1.2007, 11:43
VICTAR,  Спасибо большое за пример, теперь проверю точность операций этого модуля, тогда отпишусь об результате...

Автор: Digo 20.1.2007, 17:54
вообщем можно юзать вроде неплохо считаетsmile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)