Witam,
Mam napisany program liczący wyznaczniki metodą Laplace'a. Pozostaje tylko obliczyć wartości własne. Wzór wygląda tak :
wyznacznik z |A-I*lambda|=0, gdzie A-dana macierz, I-macierz jednostkowa, lambda-niewiadome, które mam znaleźć.
I właśnie tutaj pojawia się problem. Wyznacznik jest typu integer, a lambda typu char. Nie wiem jak to wymnożyć(liczbę i znak).
Moglibyście mi podsunąć jakiej pomysły? Z miejscami zerowymi wielomianu sobie już poradzę.
lambda nie jest typu char, lambda to macierz typu double. Poczytaj trochę więcej o zagadnieniu.
Ok,dzięki za cenną uwagę, ale dalej nie mam pojęcia jak zapisać lambdę w programie, żeby można było przez nią mnożyć (np. (1-lambda)*(2-lambda)) i doprowadzić do postaci wielomianowej.
var lambde:array of Double
- A mnożenie to sobie zrealizujesz.
Wiem że temat wisi od prawie dziewięciu lat ale że nikt nie dał sensownej odpowiedzi to napiszę jak znaleźć współczynniki wielomianu charakterystycznego
choć obecnie nie jest to zalecana metoda poszukiwania wartości własnych
Obecne preferowane metody polegają na sprowadzeniu macierzy do postaci trójkątnej (dla elementów zespolonych) lub postaci Schura (dla elementów rzeczywistych)
przez zastosowanie ciągu operacji zachowujących podobieństwo macierzy
On chciał wartości własne liczyć metodą Kryłowa i to jeszcze z wyznacznika
współczynnik przy x^k będzie miał wtedy n \choose {n-k} minorów a wszystkich potrzebnych minorów będzie 2^n
A może on pisał jakiś program do obliczeń symbolicznych
Jeżeli koniecznie ktoś z was chciałby wartości własne liczyć jak pierwiastki wielomianu charakterystycznego to
Wielomian charakterystyczny można dostać w następujący sposób
1.
Ślad m. potęgi macierzy jest sumą m. potęg wartości własnych
Suma taka jest funkcją symetryczną więc może być wyrażona za pomocą funkcji symetrycznych podstawowych
Wzory Newtona-Girarda wiążą funkcje symetryczne będące sumami jednakowych potęg z funkcjami symetrycznymi podstawowymi
Wzory Vieta wiążą natomiast funkcje symetryczne podstawowe z współczynnikami wielomianu
2. Stosujemy twierdzenie Cayleya-Hamiltona (Macierz spełnia swoje równanie charakterystyczne)
Mnożymy prawostronnie równanie przez pewien wektor (najlepiej niezerowy)
i zadanie znalezienia współczynników równania charakterystycznego sprowadza się nam do rozwiązania układu równań liniowych
Kod w Pascalu do pierwszego pomysłu
program characteristic;
uses crt;
type TVector = array of Double;
TMatrix = array of TVector;
procedure PrintMatrix(m,n:integer;A:TMatrix);
var i,j:integer;
begin
for i := 0 to m - 1 do
begin
for j := 0 to n - 1 do
Write(A[i,j]:1:12,' , ');
WriteLn;
end;
WriteLn;
end;
procedure MultiplyMatrix(m,n,p:integer;A,B:TMatrix;var C:TMatrix);
var i,j,k:integer;
begin
for i := 0 to m-1 do
for k := 0 to p-1 do
begin
C[i,k] := 0;
for j := 0 to n-1 do
C[i,k] := C[i,k] + A[i,j] * B[j,k];
end;
end;
procedure CopyMatrix(m,n:integer;A:TMatrix;var B:TMatrix);
var i,j:integer;
begin
for i := 0 to m-1 do
for j := 0 to n-1 do
B[i,j] := A[i,j];
end;
procedure CharPoly(n:integer;A:TMatrix;var w:TVector);
var i,j,k:integer;
B,temp:TMatrix;
c:TVector;
sum:double;
begin
SetLength(B,n,n);
SetLength(temp,n,n);
SetLength(c,n+1);
CopyMatrix(n,n,A,B);
for i := 1 to n do
begin
c[i] := 0;
for j := 0 to n - 1 do
c[i] := c[i] + B[j,j];
MultiplyMatrix(n,n,n,B,A,temp);
CopyMatrix(n,n,temp,B);
end;
w[n] := 1;
for k := n-1 downto 0 do
begin
sum := 0;
for j := 1 to n-k do
sum := sum + w[k + j] * c[j];
w[k] := -1/(n-k)*sum;
end;
end;
var i,j,m,n:integer;
A:TMatrix;
c:TVector;
esc:char;
begin
clrscr;
WriteLn('Obliczanie wspolczynnikow wielomianu charakterystycznego');
randomize;
repeat
Writeln('Podaj stopien macierzy');
readln(n);
WriteLn('Podaj gorny kraniec dla losowanych liczb');
readln(m);
SetLength(A,n,n);
SetLength(c,n+1);
for i := 0 to n - 1 do
for j := 0 to n - 1 do
A[i,j] := (1-2*random(2))*random(m);
WriteLn('Wylosowana macierz');
PrintMatrix(n,n,A);
CharPoly(n,A,c);
WriteLn('Wspolczynniki wielomianu charakterystycznego');
for i := n downto 0 do
if(c[i] < 0) then
Write(c[i]:1:10,' *x^',i)
else
Write('+',c[i]:1:10,' *x^',i);
WriteLn;
esc := Readkey;
until esc = #27;
end.