Anzeige:
Ergebnis 1 bis 9 von 9

Thema: Befehl zur Erstellung einer großen Diagonalmatrix

  1. #1
    Registrierter Benutzer Avatar von AureusPhoenix
    Registriert seit
    20.02.2010
    Beiträge
    91

    Befehl zur Erstellung einer großen Diagonalmatrix

    Hi Leute,
    ich bin am überlegen mir einen Befehl zu schreiben, der das Erzeugen großer Diagonalmatrizen vereinfacht. Im Prinzip so, wie der diag-Befehl von Matlab. Ich hab aber leider noch keine richtige Idee, wie man da am besten ran gehen sollte. Insbesondere, dass das Ganze für beliebig große Matrizen funktionieren soll bereitet mir Kopfschmerzen. Einen Befehl für eine 3x3 oder 4x4 ist ja kein Problem.

    Zum Füllen der Matrix hatte ich überlegt, ob man zwei geschachtelte for-Schleifen nehmen könnte. Aber selbst da ist das Problem, wie man Latex beibiegt, wieviele Schleifendurchläufe er braucht. Und wie sagt man ihm welche Einträge auf der Diagonalen stehen sollen.

    Ich wollte hier hauptsächlich nach Ideen und Teillösungen fragen. Also auch falls ihr keine vollständige Lösung parat habt, wäre ich euch für eure Hilfe sehr dankbar!


    PS: Für die Eingabesyntax hatte ich überlegt, das sowas cool wäre (falls das möglich ist): \diag{1&2&3} --> 3x3-Matrix mit 1,2,3 auf der Diagonalen.

  2. #2
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.862
    Moin moin,
    Zitat Zitat von AureusPhoenix Beitrag anzeigen
    Zum Füllen der Matrix hatte ich überlegt, ob man zwei geschachtelte for-Schleifen nehmen könnte. Aber selbst da ist das Problem, wie man Latex beibiegt, wieviele Schleifendurchläufe er braucht. Und wie sagt man ihm welche Einträge auf der Diagonalen stehen sollen.
    wenn ich das richtig verstehe, bräuchtest Du `nur' noch herauszufinden, in welcher Zeile (bei einer Diagonalmatrix gleicht das der Spalte, von oben links gesehen) Du Dich befindest?
    Code:
    \documentclass{article}
    \newcounter{diagonalmatrixline}
    \newcounter{diagonalmatrixlines}
    \makeatletter
      \newcommand*\diagonalmatrix@item{}
      \newcommand*\diagonalmatrixtest[1]{%
        \setcounter{diagonalmatrixline}{0}%
        \setcounter{diagonalmatrixlines}{0}%
        \@for\diagonalmatrix@item:=#1 \do{%
          \stepcounter{diagonalmatrixlines}%
        }%
        \@for\diagonalmatrix@item:=#1 \do{%
          \stepcounter{diagonalmatrixline}%
            Eintrag \thediagonalmatrixline/\thediagonalmatrixlines\ \ensuremath{(\diagonalmatrix@item)}\par
        }%
      }
    \makeatother
    \begin{document}
    \diagonalmatrixtest{\alpha,\beta,\gamma}
    \bigskip
    \diagonalmatrixtest{a,b,{c,d},e,f}
    \end{document}
    zeigt einen möglichen Ansatz: in der ersten \@for-Schleife wird lediglich ermittelt, wie viele Zeilen bzw. Spalten vorgegeben sind.
    In der zweiten \@for-Schleife folgt dann die Auswertung -- an der natürlich noch gebastelt werden muß. -- sie demonstriert hier lediglich, wie Du an die Info kommen könntest, in welcher Zeile (bzw. Spalte) von wieviel Zeilen (bzw. Spalten) man gerade ist.

    Nun bräuchtest Du theoretisch nur noch in jeder Diagonalmatrix-Zeile n-1 Nullen vor den eigentlichen Eintrag (hier \diagonalmatrix@item) und m-n Nullen hintendran zu stellen (wobei hier n für `diagonalmatrixline' und m für `diagonalmatrixlines' steht)

    MfG
    Rainer
    There's nothing a good whack with a hammer won't fix!

  3. #3
    Registrierter Benutzer Avatar von AureusPhoenix
    Registriert seit
    20.02.2010
    Beiträge
    91
    Das ist ja mal echt ein genialer Code!
    Vielen Dank. Sobald ich ihn fertig ausgebaut habe, werde ich ihn hier posten. Kann aber noch ein paar Tage dauern. Ich weis noch nicht wieviel Zeit ich zwischendurch finde.

    Grüße

  4. #4
    Registrierter Benutzer Avatar von AureusPhoenix
    Registriert seit
    20.02.2010
    Beiträge
    91
    Hi, ich hab da mal noch ne kleine Frage.
    Ich bin schon fast mit dem Code fertig. Ist auch richtig cool geworden. Im Moment häng ich nur noch an einem kleinen Schönheitsfehler. Das heißt, es ginge auch ohne diesen Befehl, aber mit ihm wäre der Quelltext viel besser lesbar.

    Und zwar hab ich mir nen Befehl geschrieben, der mir die Länge einer Liste bestimmt.
    Code:
    \documentclass{article}
    \usepackage[ngerman]{babel}
    \usepackage[]{xifthen}
    \usepackage{amsmath}
    
    \makeatletter
    
    \newcounter{Num}
    \newcommand*{\@listitem}{}
    \newcommand*{\sizeoflist}[1]{%
    	\setcounter{Num}{0}%
    	\@for\@listitem:=#1\do{\stepcounter{Num}}%
    	\theNum%
    }
    
    \makeatother
    
    \begin{document}
    \sizeoflist{a,b,c,d} % --> 4
    \end{document}
    Wenn ich jetzt aber folgendes versuche, dann funktioniert das nicht.
    Code:
    \newcounter{rows}
    \setcounter{rows}{\sizeoflist{a,b,c,d}}
    Mir ist im Grunde auch schon klar warum. Für TeX ist die Zahl die er ausgibt ein Zeichen und kein numerischer Wert. Gibt es da irgend eine Möglichkeit ihm zu verklickern, dass das eine Zahl ist?


    Nochmals Danke!
    Grüße

  5. #5
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.862
    Moin moin,
    Zitat Zitat von AureusPhoenix Beitrag anzeigen
    Wenn ich jetzt aber folgendes versuche, dann funktioniert das nicht.
    Code:
    \newcounter{rows}
    \setcounter{rows}{\sizeoflist{a,b,c,d}}
    Mir ist im Grunde auch schon klar warum. Für TeX ist die Zahl die er ausgibt ein Zeichen und kein numerischer Wert. Gibt es da irgend eine Möglichkeit ihm zu verklickern, dass das eine Zahl ist?
    ich würde die Ausgabe \theNum aus \sizeoflist entfernen und das in etwa so aufrufen
    Code:
    \newcounter{rows}
    \sizeoflist{a,b,c,d} % 4 --> Num
    \setcounter{rows}{\value{Num}}%<-- rows=Num
    Beim Hantieren mit Zählern ist es Imho eh besser, mit \value (oder eine Ebene tiefer mit \c@...) zu arbeiten, als sich darauf zu verlassen, daß \the<Zähler> einen auswertbaren Wert liefert (der darf ja gerne mal \Roman oder \alph oder gar eine Kombination aus mehreren Zählern (vgl. \thesubsection etc.) statt eines numerischen Wertes liefern).

    MfG
    Rainer
    There's nothing a good whack with a hammer won't fix!

  6. #6
    Registrierter Benutzer Avatar von AureusPhoenix
    Registriert seit
    20.02.2010
    Beiträge
    91
    So, meine Befehle sind jetzt soweit fertig. Ich stell sie hier einfach mal rein, für den Fall, das nochmal jemand sowas machen will.

    Eine kleine Frage hätte ich zwar noch, aber die Stell ich am besten erst ganz unten.
    Hier der Code, den ich geschrieben habe:

    Code:
    \usepackage[]{xifthen}
    \usepackage{amsmath}
    \usepackage{forloop}
    
    \makeatletter
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%	       Counter Initilization         %%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    \newcounter{Num}
    \newcounter{Row}			
    \newcounter{Col}
    \newcounter{Rows}
    \newcounter{Help}
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%	          List Management            %%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    %\makelist[stepwidth]{from}{to}
    \newcommand{\makelist}[3][1]{\forLoop[#1]{#2}{#3}{Num}{\theNum, }}
    
    %\getfromlist[index, default=1]{list}
    \newcommand*{\@listitem}{}
    \newcommand*{\getfromlist}[2][1]{%
    	\setcounter{Num}{0}	%
    	\@for\@listitem:=#2\do{%
    		\stepcounter{Num}%
    		\ifthenelse{\equal{\theNum}{#1}}{\@listitem}{}%
    	}%
    }
    
    %\sizeoflist[optional counter]{list}
    \newcommand{\sizeoflist}{\@ifstar\@sizeoflistStar\@sizeoflistNoStar}
    
    \newcommand*{\@sizeoflistNoStar}[2][Num]{%
    	\setcounter{Num}{0}%
    	\@for\@listitem:=#2\do{\stepcounter{Num}}%
    	\theNum\setcounter{#1}{\value{Num}}%
    }
    
    \newcommand*{\@sizeoflistStar}[2][Num]{%
    	\setcounter{Num}{0}%
    	\@for\@listitem:=#2\do{\stepcounter{Num}}%
    	\setcounter{#1}{\value{Num}}%
    }
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%	          Identity Matrix            %%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    %\ones(*)[background]{size}
    \newcommand{\ones}{\@ifstar\@onesStar\@onesNoStar}
    
    % Command without Star
    \newcommand*{\@onesNoStar}[2][0]{%		
    \setcounter{Row}{0}%			
    \setcounter{Col}{0}%	
    \setcounter{Rows}{#2}%
    \stepcounter{Rows}%
    %
    \ensuremath{%
    \begin{matrix}%
    	\forloop{Row}{1}{\theRow < \theRows}{%
    	\forloop{Col}{1}{\theCol < \theRows}{%
    		\ifthenelse{\equal{\theRow}{\theCol}}{1}{#1}%
    		\ifthenelse{\equal{\theCol}{\theRows}}{}{&}%
    		}\\}%
    \end{matrix}}%
    }
    
    % Command with Star
    \newcommand*{\@onesStar}[2][0]{%		
    \setcounter{Row}{0}%			
    \setcounter{Col}{0}%	
    \setcounter{Rows}{#2}%
    \setcounter{Help}{\theRows}%
    \stepcounter{Rows}%
    %
    \ensuremath{%
    \begin{matrix}%
    	\forloop[-1]{Row}{\theHelp}{\theRow > 0}{%
    	\forloop{Col}{1}{\theCol < \theRows}{%
    		\ifthenelse{\equal{\theRow}{\theCol}}{1}{#1}%
    		\ifthenelse{\equal{\theCol}{\theRows}}{}{&}%
    		}\\}%
    \end{matrix}}%
    }
    
    
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%	     Arbitrary Diagonal Matrix       %%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    
    %\diag(*)[matrix background]{list}
    \newcommand{\diag}{\@ifstar\@diagStar\@diagNoStar}
    
    \newcommand*{\@diagNoStar}[2][0]{%
    \setcounter{Row}{0}%			
    \setcounter{Col}{0}%
    \sizeoflist*[Rows]{#2}%
    \stepcounter{Rows}%
    %
    \ensuremath{%
    \begin{matrix}
    	\forloop{Row}{1}{\theRow < \theRows}{%
    	\forloop{Col}{1}{\theCol < \theRows}{%
    		\ifthenelse{\equal{\theRow}{\theCol}}{\getfromlist[\theRow]{#2}}{#1}%
    		\ifthenelse{\equal{\theCol}{\theRows}}{}{&}%
    		}\\}%
    \end{matrix}}%
    }
    
    \newcommand*{\@diagStar}[2][0]{%
    \setcounter{Row}{0}%			
    \setcounter{Col}{0}%
    \sizeoflist*[Rows]{#2}%
    \setcounter{Help}{\theRows}%
    \stepcounter{Rows}%
    %
    \ensuremath{%
    \begin{matrix}%
    	\forloop[-1]{Row}{\theHelp}{\theRow > 0}{%
    	\forloop{Col}{1}{\theCol < \theRows}{%
    		\ifthenelse{\equal{\theRow}{\theCol}}{\getfromlist[\theRow]{#2}}{#1}%
    		\ifthenelse{\equal{\theCol}{\theRows}}{}{&}%
    		}\\}%
    \end{matrix}}%
    }
    
    \makeatother
    Im Anhang befindet sich eine Beispieldatei, die zeigt, was damit so alles möglich ist.


    Jetzt noch schnell zu meiner Frage. Im Code gibt es den Befehl \makelist (auch in der pdf zu sehen). Der Befehl setzt zwar am Ende noch ein Komma, das sollte aber nicht das Problem sein. Ich habe mit dem Befehl nun folgendes versucht:

    Code:
    \getfromlist[3]{\makelist[1]{1}{10}}
    Das klappt nicht. Ich vermute, das TeX wieder den Ausgabestring von \makelist nicht für eine liste hält, wie ich sie ihm eingeben würde. Lässt sich da was machen? Damit käme man um die längliche Defintion des \ones Befehl rundrum, weil man ihn auf \diag zurückführen könnte.

    Nochmal Danke!
    Grüße

  7. #7
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.862
    Moin moin,
    Zitat Zitat von AureusPhoenix Beitrag anzeigen
    Im Code gibt es den Befehl \makelist (auch in der pdf zu sehen). Der Befehl setzt zwar am Ende noch ein Komma, das sollte aber nicht das Problem sein. Ich habe mit dem Befehl nun folgendes versucht:

    Code:
    \getfromlist[3]{\makelist[1]{1}{10}}
    Das klappt nicht. Ich vermute, das TeX wieder den Ausgabestring von \makelist nicht für eine liste hält, wie ich sie ihm eingeben würde.
    der in Deinem \makelist verwendete \forLoop nutzt intern \ifthenelse aus dem ifthen-Paket, da gibt es afair Probleme, wenn man an das expandierte Ergebnis kommen will (vllt irre ich mich auch).
    Mit einem kleinen Umweg geht's:
    Code:
    \newcommand*\meineliste{}%
    \newcommand*\Makelist[3][1]{%
      \forLoop[#1]{#2}{#3}{Num}{\edef\meineliste{\meineliste\ifnum\value{Num}>1,\fi\theNum}}%
    }
    und dann im Text
    Code:
    \Makelist[2]{1}{10}%
    (\meineliste)
    \getfromlist[3]{\meineliste}
    MfG
    Rainer
    There's nothing a good whack with a hammer won't fix!

  8. #8
    Registrierter Benutzer Avatar von AureusPhoenix
    Registriert seit
    20.02.2010
    Beiträge
    91
    Danke!
    Die Sache mit den expandierten Befehlen usw. ist mir allerdings schon lange ein Rätsel. Du kennst nicht zufällig ein Buch oder eine Webseite wo der ganze Kram (insbesondere dieses \expandafter usw.) gut beschrieben steht?

    Grüße

  9. #9
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.862
    Nunja, gerade bei Expansion hat auch meiner einer noch diverse Lücken
    Ich find das TeXbyTopic recht gut -- und ist immer griffbereit (texdoc TeXbyTopic).
    Du kannst ja mal stöbern, was bei Dir alles unter doc/plain bzw. doc/generic schlummert;-)

    MfG
    Rainer
    There's nothing a good whack with a hammer won't fix!

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •