Anschlussfrage zu richtige-ausgabe-der-argumente-bei-pgffor-if-bedingung


Wie kann ich die if-Bedingung von @Henri in einem newcolumntype anwenden? Ich habe da leider gar keine Idee, daher auch kein eigener Ansatz.

Hinweis: Die Hintergrundidee ist, dass aus einer einfachen Eingabematrix, also etwa

1, 1, 2, -1, 0 0, 1, 1, 3, 0

ein notationsrichtiges LGS entsteht.

alt text

Öffne in Overleaf
\documentclass{article}
\usepackage[ngerman]{babel}

\usepackage[fleqn]{amsmath} % fleqn = noindent bei alignat*
\usepackage{amsfonts, amssymb}
\usepackage{array}
\usepackage{pgffor}

\setlength{\parindent}{0pt}
\begin{document}

% Koeffizienten von x festlegen
\pgfmathsetmacro{\a}{-1}

% Konstanten zum Vergleichen
\pgfmathsetmacro{\zero}{0}
\pgfmathsetmacro{\one}{1}
\pgfmathsetmacro{\mone}{-1}

$a x$ wird ausgegeben als:
\ifx\a\zero {}            % Leer
\else
  \ifx\a\one {$x$}%       % Nur x
  \else
    \ifx\a\mone {$-x$}%   % Nur -x
      \else {$\a x$}%
    \fi
  \fi
\fi

\bigskip

SOLL nach: \\
$
\newcolumntype{C}{>{{}}c<{{}}}
\newcolumntype{R}[1]{r<{x_{#1}}}
\left\{\setlength\arraycolsep{0pt}
\begin{array}{ R{1} C R{2}  C R{3}  C  R{4}  @{{}={}}c}
+1 & & +1 & & +2  & & -1  & 0 \\
0 & & +1 & & +1  & & +3  & 0
\end{array}\right.
$ \bigskip

Um das Resultat \\
$
\newcolumntype{C}{>{{}}c<{{}}}
\left\{\setlength\arraycolsep{0pt}
\begin{array}{ r C r  C r  C  r  @{{}={}} c}
x_1 & + & x_2 & + & 2 x_3 & - &   x_4 & 0 \\
    &   & x_2 & - &   x_3 & + & 3 x_4 & 0
\end{array}\right.
$\\
zu erzeugen. 
\end{document}

gefragt 27 Dez '17, 10:36

cis's gravatar image

cis
9.5k75452491
Akzeptiert-Rate: 29%

Ich verstehe nicht ganz, was Du vor hast, vermute aber, dass die Spalte Informationen aus dem Inhalt der Spalte auswerten soll. Das geht nicht mit einem einfachen Spaltentyp. Zwar kann ein Spaltentyp ein Argument besitzen, dieses wird aber zum Zeitpunkt des Einlesens der Spaltentypen ausgewertet und nicht erst bei Anwendung des Spaltentyps. Soll stattdessen der Inhalt einer Spalte als Argument verwendet werden, dann gibt es zwar Tricks dafür, die haben aber meist irgendwelche Beschränkungen.

(29 Dez '17, 20:01) saputello

Es wäre viel einfacher das Rad nicht neu zu erfinden und das systeme-Paket zu verwenden.

Öffne in Overleaf
\documentclass{article}

\usepackage{systeme}

\begin{document}

\systeme{
  x_1 + x_2 + 2 x_3 - x_4 = 0,
  x_2 - x_3 + 3 x_4 = 0
}

\end{document}

alt text

Ansonsten würde ich Lua für sowas benutzen.

Öffne in Overleaf
\documentclass{article}

\usepackage{amsmath}
\usepackage{luacode}

\begin{luacode*}
lgs = lgs or {}
lgs.saved = lgs.saved or {}

local sprint = tex.sprint

local function define(name, array)
   if lgs.saved[name] then
      print("Redefining LGS `" .. name .. "'")
   end
   lgs.saved[name] = array

   local len = #array[1]
   for i, row in ipairs(array) do
      assert(#row == len, "LGS `" .. name .. "' is not square!")
   end
end

lgs.define = define

local function explicit(name)
   local array = assert(lgs.saved[name], "LGS `" .. name .. "' undefined!")
   local len = #array[1]

   sprint("\\begin{array}{@{}*{" .. len .. "}{c@{}r@{}}}")
   for i, row in ipairs(array) do
      local isfirst = true
      for j, col in ipairs(row) do
         local sign = ""
         local entry = "x_{" .. j .. "}"
         if (col == -1) then
              sign = "-"
         elseif (col == 0) then
              entry = ""
         elseif (col == 1) then
              sign = "+"
         else
              sign = col < 0 and "+" or "-"
              entry = math.abs(col) .. entry
         end

         if (isfirst and sign == "+") then
            sprint("& " .. entry .. " &")
         elseif (j < len) then
            sprint("{}" .. sign .. "{} & " .. entry .. " &")
         else
            sprint("{}=" .. col .. " \\\\")
         end

         if (col ~= 0) then
            isfirst = false
         end
      end
   end
   sprint("\\end{array}")
end

lgs.explicit = explicit

local function matrix(name)
   local array = assert(lgs.saved[name], "LGS `" .. name .. "' undefined!")
   local len = #array[1]

   sprint("\\begin{pmatrix}")
   for i, row in ipairs(array) do
      for j, col in ipairs(row) do
         if (j < len) then
            sprint(col .. " &")
         else
            sprint(col .. " \\\\")
         end
      end
   end
   sprint("\\end{pmatrix}")
end

lgs.matrix = matrix
\end{luacode*}

\newcommand\definelgs[2]{\directlua{lgs.define([[#1]],{#2})}}
\newcommand\lgsexplicit[1]{\directlua{lgs.explicit([[#1]])}}
\newcommand\lgsmatrix[1]{\directlua{lgs.matrix([[#1]])}}

\begin{document}

\definelgs{first}{
  { 1, 1, 2, -1, 0 },
  { 0, 1, 1,  3, 0 }
}

\[\lgsexplicit{first}\]

\[\lgsmatrix{first}\]

\definelgs{second}{
  { 1,   -2, 1 },
  { 1, 3.14, 0 },
}

\[\lgsexplicit{second}\]

\[\lgsmatrix{second}\]

\end{document}
Permanenter link

beantwortet 28 Dez '17, 00:06

Henri's gravatar image

Henri
15.7k133943
Akzeptiert-Rate: 46%

bearbeitet 30 Dez '17, 06:12

Ja, danke. Puh... scheint elementar, also mit reinen tex-Mitteln, nicht mehr zu lösen zu sein.

(31 Dez '17, 10:05) cis
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×58
×9
×9
×5

gestellte Frage: 27 Dez '17, 10:36

Frage wurde gesehen: 4,988 Mal

zuletzt geändert: 31 Dez '17, 10:05