WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Programm zur Bestimmung der Determinante beliebiger Matrizen

 

jamesbizarre
Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 27.11.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.11.2009, 20:12     Titel: Programm zur Bestimmung der Determinante beliebiger Matrizen
  Antworten mit Zitat      
Hallo, ich bin neu hier.
Ich bin Maschinenbaustudent und möchte mich nebenbei mal etwas in Matlab-Programmierung einarbeiten. Dazu habe ich mir eine kleine Funktion überlegt, nämlich das bestimmen der Determinante einer beliebig großen Matrix. (ich weiß die Funktion gibt es schon, aber es soll ja nur zu Übungszwecken sein Wink )

Hier ist der Quellcode:


Ich möchte die Determinante über das Unterdeterminanteverfahren (Cramersche Regel) lösen.
Jetzt habe ich das Problem, dass ich immer das erste Element einer Zeile mit der Determinante der kleineren Matrix (also ohne der Zeile und Spalte des ersten Elements) multiplizieren muss.
Ich müsste also in diesem Teil "sum = sum + (-1)^(k+1)*A(1,k)* detn(A([C],[B]));" bei dem Aufruf der Rekursion die Matrix A um eine Spalte und Zeile verkleinern. Da die Spalte die weg kommt immer die Gleiche ist (nämlich die erste) ist das ganz einfach. Das ist mit der Menge C umgesetzt. Bei der Zeile springt die zu entfernende Zeile aber immer, sie ist immer das k, weshalb ich die Menge B so definiert habe.

Vom Gedanken her müsste das alles passen, ich bekomme aber dennoch nur Fehlermeldungen:

>> detn(A)
Nur quadratische Matrizen!
Error in ==> detn at 3
[n,m]=size(A);

??? Output argument "det" (and maybe others) not assigned during call
to "C:\Users\Frank\Documents\MATLAB\detn.m>detn".

Error in ==> detn at 15
sum = sum + (-1)^(k+1)*A(1,k)* detn(A([C],[B]));


Kann mir vielleicht jemand sagen was ich falsch mache?
Ich hoffe ich hab alles verständlich beschrieben, fällt mir gar nicht so leicht das verständlich auszudrücken Smile

Danke schon mal!
Frank
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 27.11.2009, 20:35     Titel:
  Antworten mit Zitat      
Hallo,

das Problem, in das du läufst: die erste Matrix oder eine bei den rekursiven Matrizen ist nicht quadratisch. Damit wird das Rückgabeargument det im Laufe des Codes nicht definiert, und es gibt den Fehler.

Das Problem dürfte sein, dass B in jeder Iteration der for-Schleife kleiner wird, was aber nicht beabsichtigt sein dürfte. Solchen Problemen kommt man am besten mit dem Debugger auf die Spur.
Hier vermutlich zu korrigieren:
Code:
Bk = B(B~=k);
...
... * detn(A(C, Bk))


Bitte den Code per copy-paste einfügen, damit man ggf. auch was damit ausprobieren kann.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
jamesbizarre
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 27.11.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.11.2009, 15:06     Titel:
  Antworten mit Zitat      
Zitat:
Hallo,

das Problem, in das du läufst: die erste Matrix oder eine bei den rekursiven Matrizen ist nicht quadratisch. Damit wird das Rückgabeargument det im Laufe des Codes nicht definiert, und es gibt den Fehler.

Das Problem dürfte sein, dass B in jeder Iteration der for-Schleife kleiner wird, was aber nicht beabsichtigt sein dürfte. Solchen Problemen kommt man am besten mit dem Debugger auf die Spur.
Hier vermutlich zu korrigieren:
Code:
Bk = B(B~=k);
...
... * detn(A(C, Bk))


Bitte den Code per copy-paste einfügen, damit man ggf. auch was damit ausprobieren kann.

Grüße,
Harald


Danke erst mal, werde das ganze mal weiter ausprobieren und dann den Erfolg/Probleme schildern.
Nächstes mal werde ich den Code pasten, alles klar!

Gruß
Frank
Private Nachricht senden Benutzer-Profile anzeigen
 
jamesbizarre
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 27.11.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.11.2009, 16:01     Titel:
  Antworten mit Zitat      
Unglaublich, es läuft, also hier noch mal der funktionierende Code:

Code:
function[det]=detn(A)

[n,m]=size(A); %Bestimmung der Anzahl an Spalten n und Zeilen m
B=1:n;
C=2:n;

if n == m %Abfrage: Ist Matrix quadratisch?
        if n == 2 %Bei Dim. 2 einfache Lösung
        det = A(1,1)*A(2,2)-A(2,1)*A(1,2);
       
        elseif n>2 %Bei größerer Matrix Lösung durch Rekursion
            det=0; %Lösung durch Unterdeterminantenverfahren
                for k=1:n
                Bk = B(B~=k);
                det = det + (-1)^(k+1)*A(1,k)* detn(A([C],[Bk]));  
                end
                 
         end
   
else disp('Nur quadratische Matrizen!');
end
return


Ich hab das ganze mal für kleinere Determinanten geprüft, läuft.
Jetzt hab ich eine quadratische Matrix der 23ten Dimension eingegeben, und mein PC ist schon seit ner halben Stunde am rechnen Smile
Bin mal gespannt ob er auf ein Ergebnis kommt.

Ist so eine Lösung über Rekursion eigentlich sinnvoll oder im Allgemeinen nicht zu empfehlen? Das geht doch sicherlich ganz schön auf den Arbeitsspeicher und die CPU?!?
Ich werd mal versuchen eine zweite Funktion zu schreiben, die die Determinante anders löst, habe hier auf diesem Javascript ne relativ schnelle Variante gefunden http://www.arndt-bruenner.de/mathe/scripts/determinanten.htm
Mal sehn ob ich das hinbekomme.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 28.11.2009, 19:20     Titel:
  Antworten mit Zitat      
Hallo,

das schnellste wird immer noch der in MATLAB eingebaute Befehl det sein.
Rechenzeit bei einer 23x23-Matrix: 0,3s.
Ob Rekursion sinnvoll ist oder nicht, hängt vom konkreten Problem ab. Wenn dadurch Rechenoperationen eingespart werden können, ist es sinnvoll. Wenn nicht, dann nicht.
Natürlich sind Rekursionen effizienter, bei denen man im nächsten Schritt mit einem Problem halber Größe rechnet, als Rekursionen, bei denen man (wie hier) in der nächsten Iteration mit einer nur minimal kleineren Matrix rechnet.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
jamesbizarre
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 27.11.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.11.2009, 12:44     Titel:
  Antworten mit Zitat      
Zitat:

Hallo,

das schnellste wird immer noch der in MATLAB eingebaute Befehl det sein.
Rechenzeit bei einer 23x23-Matrix: 0,3s.
Ob Rekursion sinnvoll ist oder nicht, hängt vom konkreten Problem ab. Wenn dadurch Rechenoperationen eingespart werden können, ist es sinnvoll. Wenn nicht, dann nicht.
Natürlich sind Rekursionen effizienter, bei denen man im nächsten Schritt mit einem Problem halber Größe rechnet, als Rekursionen, bei denen man (wie hier) in der nächsten Iteration mit einer nur minimal kleineren Matrix rechnet.

Grüße,
Harald


Stimmt, Sinn macht es nur wenn der Rechenaufwand des Programms abnimmt. Bei mir mach ich mir aber weniger Gedanken um die Rechenkomplexität als über die Anzahl der Rekursionen.
Also in meinem Fall wird die ganze Geschichte schnell intensiv. Bei einer 3x3Matrix muss das System 3 mal das Programm neu laden, bei einer 4x4 Matrix 4*3 also gleich 12 mal. Das heißt die Anzahl der neu zu ladenenden Programme wäre bei einer 23x23 Matrix 23!/2, was immerhin
dieser Zahl enspricht: 12926008369442488320000.
Ich glaub da muss ich mir einen Supercomputer aus einem Forschungszentrum mieten.
Private Nachricht senden Benutzer-Profile anzeigen
 
jamesbizarre
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 30
Anmeldedatum: 27.11.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.11.2009, 23:41     Titel:
  Antworten mit Zitat      
So, hier das Alternativprogramm, welches die Determinante mittels Bilden einer Dreiecksmatrix löst um dann das Produkt der Diagonalen zu nehmen:

Code:
function [det]=detn2(A)

[n,m]=size(A); %Bestimmung der Anzahl an Spalten n und Zeilen m
B=1:n;
C=2:n;

if n == m %Abfrage: Ist Matrix quadratisch?
        if n == 2 %Bei Dim. 2 einfache Lösung
        det = A(1,1)*A(2,2)-A(2,1)*A(1,2);
       
        elseif n<5 %Bei Matrix bis Grad 4 Lösung durch Rekursion
            det=0; %Lösung durch Unterdeterminantenverfahren
               
            for k=1:n
                Bk = B(B~=k);
                det = det + (-1)^(k+1)*A(1,k)* detn(A([C],[Bk]));  
            end
           
           
        elseif n>=5 %Bei höheren Matrizen Lösung durch Bildung einer
                   %Dreiecksmatrix und Produkt der Diagonale
           
            for j=1:(n-1)  %Zählschleife der Spalten
               
                for i=1:(n-j)   %Zählschleife der Zeilen
               
                    if (A(i+j-1,j)~=0) && (A(i+j,j)~=0)
                       Wert1=A(i+j-1,j); %Wert in Spalte j auf der Diagonalen
                       Wert2=A(i+j,j); %Darunter liegender Wert
                       x(i)=Wert2/Wert1;
                       A(j+i,:)=A(j+i,:)/x(i); %Gleichmachen der Werte
                   
                    elseif A(i+j-1,j)==0
                        A(i+j-1,j)=A(i+j-1)+A(i+j,j);
                   
                    elseif A(j,:)==0  %Falls ganze Spalte 0 gilt det=0
                        det=0;
                   
                    else break
                    end
                end
               
                for l=(j+1):n   %Abziehen der unter der j-ten Zeile liegenden
                    A(l,:)=A(l,:)-A(j,:); %Werte von dem j-ten Wert
                end
               
                for i=1:(n-j)
                    A(j+i,:)=A(i+j,:)*x(i);
                end
               
            end
            det=1;
            for k=1:n   %Produkt der Diagonalwerte
                det=A(k,k)*det;
            end
         end
   
else disp('Nur quadratische Matrizen!');
end
return


Also beim Rang 23 ist das Programm gefühlsmäßig gleichschnell zum det(A)-Befehl vom Matlab.
Habe das ganze aber mal für 1200 gemacht, da hat mein Programm ca eine Minute gebraucht, und det(A) nur 2 oder 3 Sekunden.
Ich wüsste mal gerne, was die anders gemacht haben.
Gibt es nicht eine Möglichkeit sich den Quellcode der Befehle anzusehen?
Der ist vermutlich geheim, oder?
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.11.2009, 00:51     Titel:
  Antworten mit Zitat      
Hallo,

det ist eine built-in function, siehe
Code:


Geschwindigkeitsmäßig hat das den Vorteil, dass im Hintergrund optimierter C-Code läuft, was so ziemlich unschlagbar ist, was Performance angeht.

Edit: Ach ja... in deinem Programm solltest du noch ein paar for-Schleifen durch geschickte Vektor-Operationen ersetzen können.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.