|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 13.06.2011, 01:44 Titel: Matix Inverse, Adjunkte und Detamination, irgendein fehler |
|
|
Hi, ich habe gerade an Vectoren und Matrix Typen gearbeitet und wollte dann auch mal die functionen Inverse, Adjunkte und Detamination einbauen. leinder gibt nicht jede matrix wenn ich Mat*inv(Mat) rechne eine Identitaetsmatrix. Vieleich finden die guten mathematicer ja irgendeinen fehler in meinem code.
Code: | ''Matrix aufbau
''+- -+
''| 0 4 8 12 |
''| 1 5 9 13 |
''| 2 6 10 14 |
''| 3 7 11 15 |
''+- -+
''+- -+
''| 0 3 6 |
''| 1 4 7 |
''| 2 5 8 |
''+- -+
''+- -+
''| 0 2 |
''| 1 3 |
''+- -+
Type FLOAT As Single
Function VecMat_Matf_Det ( ByVal In1 As FLOAT Ptr, ByVal LX As Long, ByVal LY As Long ) As FLOAT
If LX = LY Then
Select Case LX
Case 1
Return In1[0] '' Detamination orden 1X1
Case 2
Return In1[0]*In1[3]-In1[1]*In1[2] '' Detamination orden 2X2
Case Else '' Detamination 3X3 +
Dim Mat(0 To (LX-1)*(LX-1)-1) As FLOAT '' UnterMatix zur Detamination
Dim er As FLOAT
Dim mom As Long = 1 '' Ob man gerade minus oder plus rechnet
For i As Long = 0 To LX-1 '' Geht die laenge der matrix durch
For ii As Long = 0 To LX-2
For jj As Long = 0 To LY-2
Mat(ii*(LY-1)+jj) = In1[IIf(ii>=i,ii+1,ii)*LY+jj+1] '' Bildet eine neue matrix ohne die spalte der aktuellen i position und der ersten reihe
Next
Next
er += In1[i*LY] * VecMat_Matf_Det ( @Mat(0), LX-1, LY-1 ) * mom '' Ergebnis += Aktuelle zahl in der ersten reihe i * det * minus oder plus eins
mom *= -1 '' wenn minus plus, wenn plus das minus
Next
Return er
End Select
EndIf
End Function
Sub VecMat_Matf_Adjunkte ( ByVal In1 As FLOAT Ptr, ByVal LX As Long, ByVal LY As Long )
If LX = LY Then
Select Case LX
Case 1
'' Adjunkle orden 1X1 weis ich nicht
Case 2'' Adjunkle orden 2X2
Dim Temp As FLOAT
Temp = In1[0]
In1[0] = In1[3]
In1[3] = Temp
In1[1] = -In1[1]
In1[2] = -In1[2]
Case Else'' Adjunkle orden 3X3 +
Dim Mat(0 To LX*LY-1) As FLOAT'' Temp Matrix
Dim Mat1(0 To (LX-1)*(LY-1)-1) As FLOAT '' Matrix zur detamination
Dim mom As Long = 1 '' ob gerade minus oder plus
For j As Long = 0 To LY-1
For i As Long = 0 To LX-1
For ii As Long = 0 To LX-2
For jj As Long = 0 To LY-2
Mat1(ii*(LY-1)+jj) = In1[IIf(ii>=i,ii+1,ii)*LY+IIf(jj>=j,jj+1,jj)] '' Bilden der Matrix zur detamination
Next
Next
Mat(i*LY+j) = VecMat_Matf_Det ( @Mat1(0), LX-1, LY-1 ) * mom '' Mat(i,j) = Det ( Mat(ohne reihe i und zeile j)) * plus oder minus
mom *= -1
Next
Next
For z As Long = 0 To LX*LY-1
In1[z] = mat(z) '' Temp Matix zu eigentliche Matrix compieren
Next
End Select
EndIf
End Sub
Sub VecMat_Matf_Inverse ( ByVal In1 As FLOAT Ptr, ByVal LX As Long, ByVal LY As Long )
If LX = LY Then
Dim Temp As FLOAT
Temp = 1/VecMat_Matf_Det ( In1, LX, LY )
VecMat_Matf_Adjunkte ( In1, LX, LY )
For z As Long = 0 To LX*LY-1
In1[z] *= Temp
Next
EndIf
End Sub
|
|
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4676 Wohnort: ~/
|
Verfasst am: 13.06.2011, 09:01 Titel: |
|
|
Ein Anwendungsbeispiel wäre nicht schlecht.
Meinst du, dass nicht exakt die Einheitsmatrix heraus kommt, oder erhältst du manchmal ein völlig anderes Ergebnis? Die Berechnung wird auf jeden Fall ganz massiv unter der verfügbaren Rechengenauigkeit leiden. Selbst wenn das (exakte) Inverse nur Integerwerte aufweist, wirst du mit den Computer öfters eine Gleitkommazahl erhalten. Das wirkt sich natürlich auf die Berechnung von Mat*Inv(Mat) aus.
Sonst hilft dir vielleicht auch FBMath weiter, da gibt es (unter vielem anderen) auch Matrixberechnung, ebenfalls mit genannter Genauigkeitsbeschränkung. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 13.06.2011, 20:33 Titel: |
|
|
seh ich das richtig dass die bibiothek maximal 3x3 matrizen kann? unter 4x4 kannst du das fast zu nichts gebrauchen x.X Und matrizen sind eigentlich so schön einfach, dass man auch gleich nxn unterstützung einbauen kann, so fallunterscheidungen sollte man *eigentlich* nirgends brauchen. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
ytwinky
Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 13.06.2011, 21:12 Titel: |
|
|
Zitat: | Ein Anwendungsbeispiel wäre nicht schlecht. |
Der Code ist schon sehr gross und die Matrixen bauen auf den Vectoren auf, weshalb ich dann alles hochladen muesste.
Zitat: | Meinst du, dass nicht exakt die Einheitsmatrix heraus kommt |
Meine 3X3 matrix:
det = -15
inv =
Code: | -0.73333 0.33333 0.06666
0.66666 0.33333 -0.33333
0.53333 -0.33333 0.13333 |
zusammen als mat*inv(mat)
Code: | 5.13333 -0.33333 -0.46666
1.13333 0.66666 -0.46666
4.26666 -0.66666 0.06666 |
solle aber
Zitat: | unter 4x4 kannst du das fast zu nichts gebrauchen |
das sollte eigentlich auck fuer 4X4 sein und nXn
@ytwinky
super schau ich mir mal an, so sehe ich nun jedenfals wo der fehler liegt. |
|
Nach oben |
|
|
ytwinky
Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 13.06.2011, 21:18 Titel: |
|
|
das war der Sinn der Übung..
gruß
ytwinky _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 13.06.2011, 21:33 Titel: |
|
|
So jetzt geht's.
Danke an ytwinky
noch schnell der richtige code:
Code: | Function VecMat_Matf_Det ( ByVal In1 As FLOAT Ptr, ByVal LX As Long, ByVal LY As Long ) As FLOAT
If LX = LY Then
Select Case LX
Case 1
Return In1[0]
Case 2
Return In1[0]*In1[3]-In1[1]*In1[2]
Case Else
Dim Mat(0 To (LX-1)*(LX-1)-1) As FLOAT
Dim er As FLOAT
Dim mom As Long = 1
For i As Long = 0 To LX-1
For ii As Long = 0 To LX-2
For jj As Long = 0 To LY-2
Mat(ii*(LY-1)+jj) = In1[IIf(ii>=i,ii+1,ii)*LY+jj+1]
Next
Next
er += In1[i*LY] * VecMat_Matf_Det ( @Mat(0), LX-1, LY-1 ) * mom
mom *= -1
Next
Return er
End Select
EndIf
End Function
Sub VecMat_Matf_Transpose ( ByVal In1 As FLOAT Ptr, ByVal LX As Long, ByVal LY As Long )
Dim Temp As FLOAT
If LX = LY Then
For l As Long = 0 To LX-2
For i As Long = 1+l To LX-1
Temp = In1[i*LY+l]
In1[i*LY+l] = In1[l*LY+i]
In1[l*LY+i] = Temp
Next
Next
EndIf
End Sub
Sub VecMat_Matf_Adjunkte ( ByVal In1 As FLOAT Ptr, ByVal LX As Long, ByVal LY As Long )
If LX = LY Then
Select Case LX
Case 1
Case 2
Dim Temp As FLOAT
Temp = In1[0]
In1[0] = In1[3]
In1[3] = Temp
In1[1] = -In1[1]
In1[2] = -In1[2]
Case Else
VecMat_Matf_Transpose ( In1, LX, LY )
Dim Mat(0 To LX*LY-1) As FLOAT
Dim Mat1(0 To (LX-1)*(LY-1)-1) As FLOAT
Dim mom As Long = 1
Dim mom1 As Long = 1
For j As Long = 0 To LY-1
mom = mom1
For i As Long = 0 To LX-1
For ii As Long = 0 To LX-2
For jj As Long = 0 To LY-2
Mat1(ii*(LY-1)+jj) = In1[IIf(ii>=i,ii+1,ii)*LY+IIf(jj>=j,jj+1,jj)]
Next
Next
Mat(i*LY+j) = VecMat_Matf_Det ( @Mat1(0), LX-1, LY-1 ) * mom
mom *= -1
Next
mom1 *= -1
Next
For z As Long = 0 To LX*LY-1
In1[z] = mat(z)
Next
End Select
EndIf
End Sub
Sub VecMat_Matf_Inverse ( ByVal In1 As FLOAT Ptr, ByVal LX As Long, ByVal LY As Long )
If LX = LY Then
Dim Temp As FLOAT
Temp = 1/VecMat_Matf_Det ( In1, LX, LY )
VecMat_Matf_Adjunkte ( In1, LX, LY )
For z As Long = 0 To LX*LY-1
In1[z] *= Temp
Next
EndIf
End Sub
|
|
|
Nach oben |
|
|
ytwinky
Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 14.06.2011, 19:40 Titel: |
|
|
Hi XOR,
kennst du egtl. den Befehl Swap ? XOR hat Folgendes geschrieben: | Temp = In1[0]
In1[0] = In1[3]
In1[3] = Temp
| wäre dann Code: | Swap In1[0], In1[3] | Swap kann auch gleich ganze Records austauschen, aber das steht ja alles in der Hilfe..
Der Vorteil wäre hier auf alle Fälle, daß die zusätzliche Variable Temp wegfällt )
Gruß
ytwinky _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 14.06.2011, 20:58 Titel: |
|
|
Hi,
Zitat: | Swap In1[0], In1[3] |
danke habe ich gleich gemacht.
Ich habe jetzt folgende funktionen umgesetzt:
Zu Vektoren:
+, -, *, /, ^, =, >, <, >=, <=, <>, AnyTrue, AllTrue, Abs, Sing, Floor, Ceil, Fract, Min, Max, Length, Distance, Normalize, Clamp, Mix, SmootStep, Dot, Sqrt, Mod, FaceForward, Reflect, ToString
Zu Matrixen:
+, -, *, /, ^, =, >, <, >=, <=, <>, AnyTrue, AllTrue, CompMult, Det, Transpose, Adjunkte, Inverse, ToString
fallen euch vielleicht noch andere funktionen ein die ich einbauen koennte? |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 16.06.2011, 14:52 Titel: |
|
|
allgemein: fehlertolerante gleichheit (braucht man bei numerik, weil = bei kommazahlen viel zu oft nicht hinhaut), runden auf gegebene genauigkeiten, modulorechnung (wenn man zB winkel in vektoren stehen hat wärs cool wenn man sagen könnte "mein vektor soll im moduls-bereich (0,0,0,2pi,2pi,2pi) abgeschnitten werden")
methoden für block-updates und kopien (sowas wie untermatrix von zeile 1 bis 3 und spalte 5 bis 7 lesen oder durch ne andere matrix ersetzen)
für vektoren: kreuzprodukt, n-norm
für matrizen: potenzieren, pseudoinverse, untermatrix, test auf (semi-)definitheit, choleski-zerlegung, LDU-zerlegung (oder wie die hieß), solve (zum lösen Ax=b nach x, wenn A nicht invertierbar ist), teilmatrizen, spur, zeilennorm, spaltennorm, kronecker-produkt, eigenwerte und -vektoren berechnen, es gibt ne definition für exp(matrix), ..
du könntest fertige matrizen anbieten, sowas wie scale, rotate, translate, sheer und project zum geometrischen rechnen, kreuzproduktmatrix, einheitsmatrix, allgemeine diagonalmatrizen, was auch immer einem einfällt
wenn du ganz lustig werden willst machst du write-through block-matrizen, dass du dir also die erste spalte einer matrix als vektor holen kannst, und wenn du den vektor oder die matrix änderst ändert sich das andere jeweils mit
wenn du ganz besonders lustig werden willst bau support für symbolisches rechnen ein (aber das ist dann echt ein anderes thema eigentlich)
willst du mehr vorschläge? _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
Lutz Ifer Grillmeister
Anmeldungsdatum: 23.09.2005 Beiträge: 555
|
Verfasst am: 16.06.2011, 15:07 Titel: |
|
|
Empfehlung:
W. Dahmen & A. Reusken, Numerik für Ingenieure und Naturwissenschaftler, Springer Verlag, ISBN 978-3-540-76492-2
beschäftigt sich mit genau dieser Thematik.
Persönliche Meinung: Benutz 'ne QR-Zerlegung für die Inverse, weil numerisch stabil.
MfG,
Lutz Ifer _________________ Wahnsinn ist nur die Antwort einer gesunden Psyche auf eine kranke Gesellschaft. |
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 16.06.2011, 19:40 Titel: |
|
|
@MisterD
Danke erstmal.
Zitat: | fehlertolerante gleichheit (braucht man bei numerik, weil = bei kommazahlen viel zu oft nicht hinhaut) |
Meinst du damit, dass ich 0 = 1E-23 als Richtig ansehen soll?
Zitat: | modulorechnung (wenn man zB winkel in vektoren stehen hat wärs cool wenn man sagen könnte "mein vektor soll im moduls-bereich (0,0,0,2pi,2pi,2pi) abgeschnitten werden") |
Wird dann -1 zu 0 oder -1+2pi?
Was ist das?
Zitat: | du könntest fertige matrizen anbieten, sowas wie scale, rotate, translate, sheer und project zum geometrischen rechnen, kreuzproduktmatrix, einheitsmatrix, allgemeine diagonalmatrizen, was auch immer einem einfällt |
Scale,Rotate,Translate und project habe ich schon.
zur einheitsmatrix: Bei Mat2, Mat3, Mat4 ist der konstructor eine einheitsmatrix.
Zitat: | wenn du ganz lustig werden willst machst du write-through block-matrizen, dass du dir also die erste spalte einer matrix als vektor holen kannst, und wenn du den vektor oder die matrix änderst ändert sich das andere jeweils mit |
Muss ich mal schauen, eine reihe oder spalte kann man sich schon in einem vector geben lassen und schreibe aber der aufbau meiner Vectoren ist dafuer nicht so gut geeignet.
Zitat: | willst du mehr vorschläge? |
Fuers erste reichen diese, wenn ich mehr brauche weiss ich ja wer helfen kann.
Zu meinen vectoren:
Man kann z.B. wenn man einen Vector vom type Vec3 hat und nur die X und Y wissen will, kann man sich X und Y in einem Vec2 ueber Var.xy geben lassen, kann natuerlich auch so geschrieben werden.
Die OpenGL'er kennen das aus der GLSL.
Die matrixen sind uebrigens Spaltenweise aufgebaut, damit man sie einfach an GL uebergeben kann. |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 16.06.2011, 20:35 Titel: |
|
|
ja, sowas ungefähr meine ich mit fehlertoleranter gleichheit. Je nach numerik könnten die werte aber auch größer sein, ich weiß nich was da als toleranzwert sinnvoll ist. maschinengenauigkeit könnte aber einfach funktionieren.
modulo heißt du hast sprünge in intervallbreite, -1 würde also 2pi-1
die n-norm ist die verallgemeinerte norm. Es gibt die 1-norm als "manhatten-distanz", die 2-norm als euklidsche distanz, die unendlich-norm is auch noch halbwegs bekannt
so prinzpiell ist die n-norm von nem vektor (a_1 ... a_n) = n. wurzel der summe aller |a_i|^n
warum kann das forum hier eigentlich kein jsMath? ;P _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 16.06.2011, 20:48 Titel: |
|
|
Zitat: | so prinzpiell ist die n-norm von nem vektor (a_1 ... a_n) = n. wurzel der summe aller |a_i|^n |
ist das nich Length
Code: | Function VecMat_Vecf_Length ( ByVal In1 As FLOAT Ptr, ByVal L As Long ) As FLOAT
Dim er As FLOAT
For i As Long = 0 To L-1
er += In1[i]*In1[i]
Next
Return Sqr(er)
End Function
|
|
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 16.06.2011, 21:27 Titel: |
|
|
length ist die euklidische distanz, die 2-norm. da machst du sqrt(sum a_i^2), sqrt ist die 2. wurzel.
es gibt aber eben auch andere normen, wie eben die manhatten-distanz etc. Die haben dann ne andere zahl als wurzel und potenz da stehen (und bei ungeraden zahlen werden eben betragsstriche nötig, da sich sonst distanzen in x-richtung mit distanzen in negativer y-richtung (oder umgekehrt natürlich) gegenseitig auslöschen könnten, bildlich im 2D gesprochen). _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 16.06.2011, 21:45 Titel: |
|
|
So also:
Code: | Function VecMat_Vecf_ManhattenDistanz ( ByVal In1 As FLOAT Ptr, ByVal L As Long ) As FLOAT
Dim er As FLOAT
For i As Long = 0 To L-1
er += Abs(In1[i])^L
Next
Return Sqr(er)
End Function |
ich hatte das ^n nicht richtig wahrgenommen.
Ich binn nicht so gut in englisch, derhalb:
Wie heist runden in englisch? round
das = hat jetzt eine tolleranz, runden ist fertig genauso wie Cross.
beim runden: round(Vector,zahl) zahl = -1 bedeutet auf eine nachkommastelle runden, -3 auf drei 2 bedeutet auf 100er runden usw. |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 16.06.2011, 21:56 Titel: |
|
|
haha jetzt hast du ne interessante norm gemacht
deine norm ist jetzt a1 + a2*a2 + a3*a3*a3 + a4*a4*a4*a4 das is falsch
du hast normal sowas wie
Code: | double norm(Vector vector, int n){
double sum = 0;
foreach(double a : vector.elements()) sum += abs(a)^n;
return sum^(1.0/n);
} |
damit kannst du dann ganz einfach definieren
Code: | double length(Vector vector){
return norm(vector, 2);
} |
_________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 16.06.2011, 22:06 Titel: |
|
|
Zitat: | haha jetzt hast du ne interessante norm gemacht
deine norm ist jetzt a1 + a2*a2 + a3*a3*a3 + a4*a4*a4*a4 das is falsch |
Code: | For i As Long = 0 To L-1
er += Abs(In1[i])^L
Next |
L ist die anzahl der elemente in In1 als fuer jedes element abs(in1[i])^L.
Wenn man jetze 3 elemente hat also
(|a*a*a|+|b*b*b|+|c*c*c|)^0.5 |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4676 Wohnort: ~/
|
Verfasst am: 16.06.2011, 22:53 Titel: |
|
|
Es sollte
Code: | (|a*a|+|b*b|+|c*c|)^0.5 |
sein für eine 2-Norm, bzw.
Code: | (|a*a*a|+|b*b*b|+|c*c*c|)^(1/3) |
für eine 3-Norm (usw.) _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 17.06.2011, 00:42 Titel: |
|
|
Habs jetzt.
Danke.
Koennte mir vielleicht jemand pseudoinverse und LDU-zerlegung fuer einen 10-11 klaessler realschule erklaeren. |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht 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.
|
|