VisualBasic Matrizen Rechner ( Fehler bei der Addition und Subtraktion)

inversematrix

Ensign
Registriert
Dez. 2009
Beiträge
155
Ich habe hier ein kleines Projekt am laufen. Es geht um ein Programm, welches Matrizen addiert, subtrahiert und multipliziert. Allerdings happert es bei der Addition und Subtraktion, sobald bei der Dimensionierung die Anzahl der Spalten ungleich der Anzahl der Zeilen ist. z. B. lässt sich eine 2x3 Matrix nicht mit einer 2x3 Matrix addieren.

Bei der 2x2 oder 3x3 Matrix + die Matrix mit der selben Dimension klappt es.
{"Der Index war außerhalb des Arraybereichs."}(IndexOutOfRangeExeption) ist die Fehlermeldung

Das Programm wird mit einen Stack realisiert. Dort werden die Matrizen gespeichert. Und später über die Buttons addiert subtrahiert oder multipliziert.

Der Anwender muss wie folgt vorgehen, damit das ganze überhaupt einigermassen funktioniert.
1. Matrix Dimensionieren. Zeile und Spalte eingeben ( dürfen nur ganzzahlen sein im Integer bereich) und den Button "matrix erstellen" drücken
2. Werte in die Textfelder eingeben und Matrix im Stack speichern. über den button "push matrix"
3. neue matrix erstellen, wie in punkt 2 und 3 beschrieben.


Die Multiplikation funktioniert.
Die Addition und Subtraktion auch, allerdings nicht, wenn die anzahl der spalten ungleich der anzahl der zeilen ist obwohl eine 2x3 matrix addierbar ist mit einer 2x3 matrix.

Code folgt hier:
Code:
Public Class Matrix
    Inherits Operand    ' Matrix ist eine Teilklasse von Operand

    Private m_value(,) As Double
    ' als erstes wird ein 2 Dimensionales Array mit den 
    ' Typ Double initialisiert
    ' Mit der Public Porperty werden die Zugriffe auf die Klassenvariablen gesteuert

    Public Property value(Z As Integer, S As Integer) As Double
        Get
            Return m_value(Z, S)
        End Get
        Set(value As Double)
            m_value(Z, S) = value
        End Set
    End Property
    ' Zeilen und Spalten werden als Membervariablen deklariert vom Typ Integer
    Private m_Zeile As Integer
    Public ReadOnly Property Zeile() As Integer
        Get
            Return m_Zeile
        End Get
    End Property

    Private m_Spalte As Integer
    Public ReadOnly Property Spalte() As Integer
        Get
            Return m_Spalte
        End Get
    End Property
    ' Der Kontruktor erzeugt ein 2 Dimensionales Array mit der Anzal der Spalten und Zeilen
    Public Sub New(ByVal Z, ByVal S)
        ReDim m_value(Z - 1, S - 1)
        m_Spalte = S
        m_Zeile = Z
    End Sub

    Public Overrides Function ToString() As String
        'Dim str As String = "{"

        'For z As Integer = 0 To m_Zeile - 1
        '    str &= "("
        '    For s As Integer = 0 To m_Spalte - 1
        '        str &= m_value(z, s) & ","
        '    Next
        '    str &= ")"
        'Next
        'str &= "}"
        Return "bla"
        'count = +1
    End Function

End Class

hier die wichtige calculator klasse
Code:
Public Class Calculator
    Inherits Stack(Of Operand)
    ' Die Klasse Stack vom Typen Operand wird hinzugefügt, damit man den Stack benutzen kann

    ' Die Methode ist für die Addition zuständig

    ' Es werden erstmal 2 Operanden aus den Stack geholt
    ' Deklaration zweier Matrizen
    ' Überprüfung, ob die vom Stack geholten Operanden Matrizen sind
    ' Wenn Bedingung zutrifft, werden M1 bzw M2 mit den vom Stack geholten Operanden
    ' initialisiert


    ' Überprüfung ob Matrizen leer sind
    ' Wenn die Dimensionen nicht stimmen, kommt eine Fehlermeldung
    ' Das Ergebnis wird in einer neuen Matrix gespeichert

    ' Algorithmus zur Addition von Matrizen
    ' Jedes Element einer Matrix wird mit den Element der anderen addiert und in einer neuen Matrix gespeichert

    Public Sub Add()
        If CheckStack(2) Then

            Dim Operand1 As Operand = Me.Pop
            Dim Operand2 As Operand = Me.Pop

            If TypeOf Operand1 Is Matrix And TypeOf Operand2 Is skalar Then
                MsgBox("Matrix mit Skalar kann man nicht addieren.")
            ElseIf TypeOf Operand1 Is skalar And TypeOf Operand2 Is Matrix Then
                MsgBox("Matrix mit Skalar kann man nicht addieren.")
            ElseIf TypeOf Operand1 Is skalar And TypeOf Operand2 Is skalar Then
                Dim S1 As skalar = Operand1
                Dim S2 As skalar = Operand2
                Dim erg As skalar
                erg = New skalar
                erg.value = S2.value - S1.value
                Me.Push(erg)
            ElseIf TypeOf Operand1 Is Matrix And TypeOf Operand2 Is Matrix Then
                Dim M1 As Matrix = Operand1
                Dim M2 As Matrix = Operand2
                Dim erg As Matrix = Me.Add(M1, M2)
                Me.Push(erg)
            Else
                MsgBox("Matrix ist leer.")
            End If
        End If
    End Sub
       

    Private Function add(m1 As Matrix, m2 As Matrix) As Matrix
        If m1.Spalte <> m2.Spalte Or m1.Zeile <> m2.Zeile Then
            MsgBox("Falsche Dimensionen der Matrizen")
        End If
        Dim erg As Matrix
        erg = New Matrix(m1.Spalte, m1.Zeile)
        For i As Integer = 0 To m1.Spalte - 1
            For j As Integer = 0 To m1.Zeile - 1
                erg.value(i, j) = m2.value(i, j) + m1.value(i, j)
            Next
        Next
        Return erg
    End Function
    'Die Methode funktioniert analog zur Addition, nur diesmal werden Elementweise die Werte subtrahiert
    Public Sub Subt()
        If CheckStack(2) Then
            Dim Operand1 As Operand = Me.Pop
            Dim Operand2 As Operand = Me.Pop

            If TypeOf Operand1 Is Matrix And TypeOf Operand2 Is skalar Then
                MsgBox("Matrix mit Skalar kann man nicht addieren.")
            ElseIf TypeOf Operand1 Is skalar And TypeOf Operand2 Is Matrix Then
                MsgBox("Matrix mit Skalar kann man nicht addieren.")
            ElseIf TypeOf Operand1 Is skalar And TypeOf Operand2 Is skalar Then
                Dim S1 As skalar = Operand1
                Dim s2 As skalar = Operand2
                Dim erg As skalar
                erg = New skalar
                erg.value = s2.value - S1.value
                Me.Push(erg)
            ElseIf TypeOf Operand1 Is Matrix And TypeOf Operand2 Is Matrix Then
                Dim M1 As Matrix = Operand1
                Dim M2 As Matrix = Operand2
                Dim erg As Matrix = Me.Subt(M1, M2)
                Me.Push(erg)
            Else
                MsgBox("Matrix ist leer.")
            End If
        End If
    End Sub
    Private Function subt(m1 As Matrix, m2 As Matrix) As Matrix
        If m1.Spalte <> m2.Spalte Or m1.Zeile <> m2.Zeile Then
            MsgBox("Falsche Dimensionen der Matrizen")
        End If
        Dim erg As Matrix
        erg = New Matrix(m1.Spalte, m1.Zeile)
        For i As Integer = 0 To m1.Spalte - 1
            For j As Integer = 0 To m1.Zeile - 1
                erg.value(i, j) = m1.value(i, j) - m2.value(i, j)
            Next
        Next
        Return erg
    End Function

    ' Es werden 2 Operanden vom Stack geholt und es wird überprüft ob sie Matrizen sind
    ' wenn die Bedingung stimmt, werden sie in die zuvor deklarierten Matrizen initialisiert
    Public Sub Mul()
        If CheckStack(2) Then
            Dim Operand1 As Operand = Me.Pop
            Dim Operand2 As Operand = Me.Pop

            If TypeOf Operand1 Is Matrix And TypeOf Operand2 Is skalar Then

                Dim M As Matrix = Operand1
                Dim S As skalar = Operand2
                Dim erg As Matrix = Me.Mul(S, M)

                Me.Push(erg)

            ElseIf TypeOf Operand1 Is skalar And TypeOf Operand2 Is Matrix Then
                Dim M As Matrix = Operand2
                Dim S As skalar = Operand1
                Dim erg As Matrix = Me.Mul(S, M)

                Me.Push(erg)

            ElseIf TypeOf Operand1 Is skalar And TypeOf Operand2 Is skalar Then
                Dim S1 As skalar = Operand1
                Dim S2 As skalar = Operand2
                Dim erg As skalar
                erg = New skalar
                erg.value = S2.value * S1.value
                Me.Push(erg)
            ElseIf TypeOf Operand1 Is Matrix And TypeOf Operand2 Is Matrix Then
                ' Überprüfung, ob die Matrix leer ist, wenn nicht, dann werden die Zeilen der ersten Matrix
                ' mit den Spalten der zweiten Matrix verglichen, stimmen sie nicht überein, erscheint eine Fehlermeldung
                Dim M1 As Matrix = Operand2
                Dim M2 As Matrix = Operand1

                Dim erg As Matrix = Me.Mul(M1, M2)

                ' Ergebnis kommt auf den Stack
                Me.Push(erg)
            Else
                ' Fehlermeldung, dass die Matrix leer ist.
                MsgBox("Matrix ist leer.")
            End If

        End If

    End Sub

    Private Function Mul(s As skalar, m As Matrix) As Matrix
        Dim erg As Matrix
        erg = New Matrix(m.Zeile, m.Spalte)
        For i As Integer = 0 To m.Zeile - 1
            For j As Integer = 0 To m.Spalte - 1
                erg.value(i, j) = m.value(i, j) * s.value
            Next
        Next
        Return erg
    End Function

    Private Function mul(m1 As Matrix, m2 As Matrix) As Matrix
        If m1.Zeile <> m2.Spalte Then
            MsgBox("Falsche Dimensionen der Matrizen")
        End If
        Dim erg As Matrix
        erg = New Matrix(m2.Zeile, m1.Spalte)
        'Es wird eine neue Matrix mit erstellt, wo später das Ergebnis gespeichert wird
        ' Algorithmus zur Berechnung der Multiplikation beider Matrizen
        For j As Integer = 0 To m1.Spalte - 1
            For i As Integer = 0 To m2.Zeile - 1
                For k As Integer = 0 To m1.Zeile - 1 ' or 0 to C.N -1
                    erg.value(i, j) += m1.value(k, j) * m2.value(i, k)
                Next
            Next
        Next
        Return erg
    End Function

    Private Function CheckStack(ByVal Count As Integer) As Boolean

        If Me.Count >= Count Then
            Return True
        Else
            MsgBox("Es müssen mindestens " & Count & " Zahlen auf dem Stack liegen!")
            Return False

        End If

    End Function
    'Public Sub Inv()
    '    Dim A1 As Operand = Me.Pop

    '    Dim M1 As Matrix

    '    If TypeOf A1 Is Matrix Then
    '        M1 = A1
    '    End If
    '    If Not M1 Is Nothing Then
    '        If M1.Zeile <> M1.Spalte Then
    '            Throw New Exception("Matrix nicht invertierbar.")
    '        End If
    '    End If
    'End Sub
End Class
hier noch ein link von der projektmappe, falls ihr das ganze sofort testen wollt
projektdownload
 
Das hat leider nicht geklappt. Erstmal ein Nickerchen und dann schau ich mal weiter. Grüße
 
Zurück
Oben