Matrix Vektor Multiplikation

Die Member-Variable heißt immer noch “Matrix” (siehe Zeile 1 in #40) und ist auch noch immer public und nicht private. Der “Konstruktor” (Zeile 6) darf keinen Rückgabewert haben: das void muss weg.
Durch die Umbenennung des Konstruktorparameters in matrix musst du jetzt natürlich auch noch den Rumpf an den neuen Variablennnamen anpassen.
In “zeile” und “spalte” steht das selbe, weil die Matrix ja quadratisch ist. Das kann man also noch vereinfachen und die eine Zeile dann weglassen. Die Variable sollte aber trotzdem besser “zeilen” oder “spalten” heißen, weil darin nicht eine Zeile gespeichert ist, sondern die Anzahl der Zeilen.
Deine Zählschleife beginnt bei 1 und geht bis Matrix.length (inklusive). Statt Matrix.length möchtest du aber den maximalen Zeilenindex des übergebenen Parameters matrix haben. Der steht nun in der Variablen zeilen.
Wie oben schon geschrieben, beginnen die Indizes eines Arrays immer bei 0. Die Schleifen müssen also von 0 bis zeilen - 1 gehen. Das - 1 spart man sich bei den Schleifen zugunsten der Lesbarkeit, indem man als Vergleichsoperation im Schleifenkopf i < zeilen nutzt (statt i <= zeilen - 1).

okay, hab jetzt nochmal probier dass zuverstehen und habe nun das hier:

	   
	public double i , j;    
	public double maxI, maxJ;
	
	
	     public Matrix(double [][] matrix) {
	         
	    	 int zeilen = matrix.length;
	    	 int spalten = matrix[0].length;
	    	 
	    	 
	    	 for (int i = 0; i < zeilen; i++) {
	    		    for (int j = 0; j < spalten; j++) {
	    		    	
	    		    	
	         matrix = new double[(int) maxI][(int) maxJ];
	    		        
	    		    	
	             
	         if (j <= i){
	          this.matrix**[j] = matrix**[j];
	         }
	         else{
	          matrix**[j] = matrix [j]**;
	          }
	         }
	         }
	         }
	   
	    public double get(int zeilen, int spalten) {
	        return matrix [zeilen][spalten];
	    }
	   
	    public void set(int zeilen, int spalten, double wert){
	        this.matrix [zeilen][spalten] = wert;
	    }
	
	
}

Warum i, j, maxI, maxJ als double und vor allem warum als public Member?
i und j werden lokal im Schleifenkopf deklariert und initialisiert. maxI und maxJ werden zwar verwendet - dabei allerdings auf int gecastet, was ein Zeichen dafür ist, dass der passendere Datentyp eigentlich int ist. Ganz davon ab werden die Variablen aber nicht initialisiert, es steht also nicht das darin, was du erwartest.
Der Fehler, dass du das ganze Array austauschst, ist auch wieder drin. Das new double[zeilen][spalten]; muss vor den Schleifen einmalig passieren.

okay als muss das new double vor die schleifen.
initialisieren heißt ich muss den variablen maxI und maxJ einen Wert zuweisen?
wenn ich private vor i und j nehme, dann zeigt er mir eine fehlermeldung inform von "the value of the field Matrix.i is not used. bei public geschieht dies nicht, ich weiß nicht genau was mir das sagt.

	   
	private int i , j;    
	private int maxI, maxJ;
	
	
	     public Matrix(double [][] matrix) {
	         
	    	 int zeilen = matrix.length;
	    	 int spalten = matrix[0].length;
	    	 
	    	 matrix = new double[(int) maxI][(int) maxJ];
	    	 
	    	 
	    	 for (int i = 0; i < zeilen; i++) {
	    		    for (int j = 0; j < spalten; j++) {
	    		    	
	    		    	
	          if (j <= i){
	          this.matrix**[j] = matrix**[j];
	         }
	         else{
	          matrix**[j] = matrix [j]**;
	          }
	         }
	         }
	         }
	   
	    public double get(int zeilen, int spalten) {
	        return matrix [zeilen][spalten];
	    }
	   
	    public void set(int zeilen, int spalten, double wert){
	        this.matrix [zeilen][spalten] = wert;
	    }
	
	
}

Das ist keine Fehlermeldung, sondern ein Hinweis. Da wird erkannt, dass die Variablen überflüssig sind. Wenn du sie public setzt, dann wird das nicht erkannt, weil die Variablen auch von außerhalt des Objektes benutzt werden können.
maxI und maxJ brauchst du auch nicht. Der Wert, den du darin erwartest, steht in zeilen bzw in spalten.

Achso, noch eine Kleinigkeit zur Namensgebung von Parametern: in der get und in der set-Methode sollten die Variablen wiederum “zeile” und “spalte” heißen, weil sie den Index einer Zeile angeben und nicht die Gesamtzahl der Zeilen / Spalten.

*** Edit ***

In Zeile 12 muss es heißen this.matrix = new double[zeilen][spalten];. Wenn du das this weglässt, dann wird der Parameter des Konstruktors überschrieben.

okay versteh. also muss ich das maxI und maxJ mit zeilen und spalten austauschen? und zeile 12 desweiteren wiederum in das ändern this.matrix = new double[zeilen][spalten];
das this. ist wichtig. habe ich das richtig verstanden?

richtig verstanden (wie das andere im Posting auch), aber eigentlich keine Frage des Verstehens von anderen sondern des Codes an sich,
wann wird der Parameter matrix gemeint, wann das Instanzattribut?
das hängt weder von Wünschen noch Glauben ab, dafür braucht es klare Regeln, sonst kann man ja nicht programmieren

am Anfang lieber gar nicht erst gleichnamige Variablen nehmen, dann damit keine Probleme,
wobei auch wichtig es zu lernen, aber ja so viel auf einmal


wichtig wäre, die Punkte auch aufzunehmen als allgemeine Erkenntnisse, nicht nur Korrektur einer einzelnen Situation und später wieder ähnliches,
man kann das natürlich nicht erzwingen, aber bitte die Wichtigkeit würdigen,
es geht nicht um Korrektur einzelner Code-Zeilen, sondern elementare Grundlagen

ich weiß, ich klinge überkritisch hier, sorry :wink:

ja ich mache mir ja notizen.
ich möchte jetzt noch die richtigen werte für matrix und vektor eingeben, habe mich ein bisschen im internet informiert.
und nun diesen quellcode erstellt.
dann wird mir die matrix auch ausgegeben.

	   {
	double[][] matrix = {
			  { 1.0, -1.0, 0.0, 0.0 },
			  { -1.0, 2.0, -1.0, 0.0 },
			  { 0.0, -1.0, 2.0, -1.0 },
			  { 0.0, 0.0, -1.0, 2.0}
	};
	   
	{

		  int i,j;
	      for(i=0;i<4;i++)
	      {
	         for(j=0;j<4;j++)
	            System.out.print(matrix ** [j] + " ");
	         System.out.println();
	      }
	}
	   }```

ich möchte dass ja nun auch für den vektor machen, geht das genauso? nur dass der vektor ja 4 zeilen und eine spalte hat
das wäre ja dann das, jedoch gibt er mir den nicht aus

```public static void main1(String[] args)
	   {
	double[][] vektor = {
			  {0.3},
			  {0.2},
			  {0.1},
			  {0.0}
	};
	
	{
		 int i, j;
	      for(i=0;i<4;i++)
	      {
	        for (j=0; j<1; j++)
	        {
	            System.out.print(vektor ** [j] + " ");
	         System.out.println();
	      }
	   
}
	}
	   }
	   }

weil die Methode main1 heißt und wie immer main ausgeführt wird, was was anderes ist?
bei mir gehts

mit Klammern etwas mehr aufpassen, korrekt(er) formatiert sieht dein Code so aus:

{
    public static void main(String[] args)
    {
        double[][] vektor =
            {
                {0.3},
                {0.2},
                {0.1},
                {0.0}};

        { // unnötig
            int i, j;
            for (i = 0; i < 4; i++)
            {
                for (j = 0; j < 1; j++)
                {
                    System.out.print(vektor**[j] + " ");
                    System.out.println(); // wohin?
                }

            }
        } // unnötig
    }
}

das System.out.println(); soll vielleicht erst nach allen 4 Werten kommen?
dann muss das nicht nur eine Stufe höher beim i (durch neue Klammerung trotz ähnliche Einrückung anders als im Code davor) stehen, sondern gar erst hinter der Doppelschleife


ein eindimensionales Array wäre die normalere Variante:

{
    public static void main(String[] args)
    {
        double[] vektor =
            {0.3, 0.2, 0.1, 0.0};

        for (int i = 0; i < vektor.length; i++)
        {
            System.out.print(vektor** + " ");
        }
        System.out.println();
    }
}

ich hatte ja bei beiden methoden main aber dann sagt er mir das das ein duplicat ist und macht aus dem einen main ein main1 damit ers überhaupt annimmt

dann mache es dir wiederum einfach und nenne deine Methoden test1(), test2() oder was auch immer,
und dazu eine feste main-Methode in der gleichen Klasse oder woanders, die test1() oder anderes aufruft

main startet das Programm, von dort aus gehts los,
2x main, gar noch umbenannt, da kann man nicht viel von erwarten, jedenfalls nicht dass main1 von alleine läuft,
einfache Programmkontrolle, einfache Gedanken

„Die Matrix“ hat aber nichts mit deiner Matrix-Klasse zu tun, das ist dir hoffentlich bewusst.

@SlaterB wie genau meinst du das.
sprich die methoden so nennen
public static void test1(String[] args) bzw test 2

und dann eine main methode ganz oben an den anfang setzen?
public static void main(String[ ] args)

@cmrudolph
wie meinen?
ich will ja erstmal einfach die matrix mit ihren werten speichern quasi
und wird dann nicht über import der vorigen klassen alles miteinander verknüpft?

test1() usw. braucht keine args-Paramter,

(nur) eine main-Methode ist Pflicht, egal wohin du sie haben möchtest, von dort dann z.B. test1() aufrufen,
oder auch anderes, je nachdem was aktuell zu testen

tut mir echt leid aber ich weiß echt nicht wo ich das mit dem test 1 und test2 hintun soll.
ich möchte ja die matrix und den vektor trennen, momentan werden ja beide einfach untereinander ausgegeben, aber ich will sie ja einzeln, bzw sie müssen getrennt werden

	
    
	   {
		
	double[][] matrix = {
			  { 1.0, -1.0, 0.0, 0.0 },
			  { -1.0, 2.0, -1.0, 0.0 },
			  { 0.0, -1.0, 2.0, -1.0 },
			  { 0.0, 0.0, -1.0, 2.0}
	};
	   
	{

		  int i,j;
	      for(i=0;i<4;i++)
	      {
	         for(j=0;j<4;j++)
	            System.out.print(matrix ** [j] + " ");
	         System.out.println();
	         
	      }
	}
	   }
       
	
	   double[][] vektor =
           {
               {0.3},
               {0.2},
               {0.1},
               {0.0}};

       { 
           int i, j;
           for (i = 0; i < 4; i++)
           {
               for (j = 0; j < 1; j++)
               {
                   System.out.print(vektor**[j] + " ");
                   System.out.println(); 
               }

           }
       } 
   }
}```

‘trennen’ ist kein eindeutiger Begriff,
falls du verschiedene Methoden meinst, passt das was ich meine, aber ja ganz gut,

ganz simpel: Methoden definieren und aufrufen, schreibe deinen Code in verschiede Methoden,
rufe eine davon oder mehrere auf, was immer testweise gewünscht

    public static void main(String[] args) { // main ist main, Ende aller Diskussionen dazu
        // was aber in der main tun?
        test1();
        // noch mehr/ andere Test-Methoden?
    }

    public static void test1() {
        System.out.println("Start Test1");
        // mehr Code?
    }

    public static void test2()  {
        System.out.println("Start Test2");
        // mehr Code?      
    }

}

Mit dem Import wird dir ermöglicht, die Klasse zu verwenden (was du bisher aber nicht tust). Du hast leider keinen vollständigen Code gepostet, aber anhand des Konstruktors gehe ich davon aus, dass deine Klasse jetzt „Matrix“ heißt.

Ein Matrix-Objekt erzeugst du jetzt so:


public class Testklasse {
    public static void main(String... args) {
        testMatrix();
    }

    private static void testMatrix() {
        Matrix matrix = new Matrix(new double[][]{
                {1.0, -1.0, 0.0, 0.0},
                {-1.0, 2.0, -1.0, 0.0},
                {0.0, -1.0, 2.0, -1.0},
                {0.0, 0.0, -1.0, 2.0}
        });
        for (int zeile = 0; zeile < 4; zeile++) {
            for (int spalte = 0; spalte < 4; spalte++)
                System.out.print(matrix.get(zeile, spalte) + " ");
            System.out.println();
        }
    }
}```

In Zeile 9 wird der Konstruktor der Matrix-Klasse aufgerufen und erst dadurch ein Matrix-Objekt erzeugt.
In Zeile 17 siehst du, dass man jetzt mit der get-Methode, die du in der Matrix implementiert hast, zugreifen muss.

*** Edit ***

Was übrigens auch funktioniert ist folgendes (wie in [#35](http://forum.byte-welt.net/threads/12394-Matrix-Vektor-Multiplikation?p=97084&viewfull=1#post97084) vorgeschlagen):
```private static void testMatrix() {
    Matrix matrix = new Matrix(new double[][]{
            {1.0},
            {-1.0, 2.0},
            {0.0, -1.0, 2.0},
            {0.0, 0.0, -1.0, 2.0}
    });
    for (int zeile = 0; zeile < 4; zeile++) {
        for (int spalte = 0; spalte < 4; spalte++)
            System.out.print(matrix.get(zeile, spalte) + " ");
        System.out.println();
    }
}```

Davon aber bitte nicht verwirren lassen. Das hat nur mit dem Umstand zu tun, dass zweidimensionale Arrays entgegen der Intuition nicht unbedingt rechteckig sein müssen.

okay, das untere wäre dass weil das eine symmetrische matrix ist richtig??
wie genau muss ich das jetzt auf den Vektor übertragen? habe probiert quasi einfach Vektor für matrix einzusetzen, dann wird aber alles rot ^^

Ja, das liegt daran, dass die Matrix symmetrisch ist und auch nur die Werte aus der unteren, linken Ecke genommen werden.

Für den Vektor geht das dann so:

    Vektor vektor = new Vektor(new double[]{1.0, 2.0, 3.0, 4.0});
    for (int zeile = 0; zeile < 4; zeile++)
        System.out.println(vektor.getKoeff(zeile));
}```

Vielen dank! Hatte das fast genauso, nur mit dem print out war ich mir nicht sicher.
Jetzt fehlt mir nur noch die methode in der ich matrix und Vektor multipliziere. Könnte ich die einfach mit in die vektor klasse implementieren?

* **double multiMatVek(int*[][]*Vektor,*int*[][]*Vektor2){

* * * * * *

* * * *

* * * **for(int*i*=*0;*i*<*Vektor.length;*i++);

* * * **{

* * * * * **for(int*j*=*0;*j*<*Vektor2.length;*j++);

* * * * * *

* * * * * **{

* * * * * * * *

* * * * * * * *

* * * * * * * * Vektor2***+=*this.Matrix**[j]*this.Vektor[j];

* * * * * * * *

* * * * * *

* * * * * **}

* * * **}```


das ist ein code den ich vor ein paar tagen mit jemandem besprochen hatte und eigentlich dachte er wäre richtig,  bin mkr nur nicht so sicher, vor allem weil ich ja keine schleife für die matrix habe oder brauche ich die nicht? 
Und wie schaffe ich es, dass das ergebnis der Multiplikation auf meiner konsole ausgegeben wird? Muss ich die dann auch in die test klasse einfügen?  Also per system print out?


Danke für die ganze hilfe bis jetzt, wirklich!!!