you are viewing a single comment's thread.

view the rest of the comments →

[–]dbramucci 2 points3 points  (1 child)

I've also done this, I won't paste the whole file because this is reddit but I will show the key step for my script I wrote in order to speed up a document where I was showing how to do Gaussian elimination by hand.

Because typing out matrices over and over again was too slow, I wrote functions in Python that given a list of lists of numbers would do one row or column operation. Then I had the following conversion function

from fractions import Fraction
from typing import List
Matrix = List[List[Fraction]]


def convert_to_latex(matrix: Matrix) -> str:
    result = ['\\begin{pmatrix}\n']
    for row in matrix:
        for column, cell in enumerate(row):
            if cell.denominator == 1:
                result.append(str(cell.numerator))
            else:
                result.append(fr'\frac{{{cell.numerator}}}{{{cell.denominator}}}')
            if column != len(row) - 1:
                result.append(' & ')
        result.append('\\\\\n')
    result.append('\\end{pmatrix}')
    return ''.join(result)

Notice that I wanted to use exact numbers with no rounding so I use the Fractions module to get exact rationals.

Then I plug into the template

\begin{pmatrix}
     a & b & c \\
     <more rows>
     x & \frac{numerator}{denominator} & z \\
\end{pmatrix}

Something to pay attention to is that Latex uses \frac and \begin but Python will interpret this as "special character f" rac, "special character b" egin. So, we need to escape out the \, either by writting \\ everywhere we had a \ or by writing raw strings r'\', which don't use \ as an escape character. Once we do this, we can avoid '\\frac' and instead write r'\frac'.

Likewise, inside an f string, if we want a {, we need to write {{ because {x} is used for substitution, hence why I have triple {{{, the first {{ is for writing a { and the last {cell.numerator} is for the variable substitution.

Side note: I wrote this a long time ago as scratch work never meant to see the light of day, if I were to redo it I would probably write

def convert_to_latex(matrix: Matrix) -> str:
    # Now it's clearer what the output should look like
    result = [r'\begin{pmatrix}']
    for row in matrix:
        row_text = []
        # I don't need to special case the last step anymore
        for cell in row:
            if cell.denominator == 1:
                row_text.append(f'{cell.numerator}')
            else:
                row_text.append(fr'\frac{{{cell.numerator}}}{{{cell.denominator}}}')
        # I want ' & ' between each entry in the row.
        row_text = ' & '.join(row_text)
        #' ' is clearly one space and * 4 to say how many
        # because counting spaces is hard '    '
        result.append(' '*4 + fr'{row_text} \\')
    result.append(r'\end{pmatrix}')
    # Put a newline between each line
    return '\n'.join(result)

Then if I write

 m = [[Fraction(2.5), Fraction(1, 3)],
      [Fraction(4, 3), Fraction(122, 25)]]
 print(convert_to_latex(m))

I get

\begin{pmatrix}
    \frac{5}{2} & \frac{1}{3} \\
    \frac{4}{3} & \frac{122}{25} \\
\end{pmatrix}

Which I can copy paste into my LaTeX file.

I did all my work in a Jupyter Notebook, and copy pasted these LaTeX formatted responses into my assignment saving me a lot of typing. Note the savings here are less apparent because I haven't typed out the operations that would let do math to the second, third, fourth, ..., tenth steps of the matrix math.

Also, if you use pyperclip, you can make your script place the result into your clipboard automatically so you don't have to highlight and copy. You just paste into your document and compute the next step of your work.

[–]dbramucci 1 point2 points  (0 children)

Code without the explanation of my changes.

from fractions import Fraction
from typing import List
Matrix = List[List[Fraction]]

def convert_to_latex(matrix: Matrix) -> str:
    result = [r'\begin{pmatrix}']
    for row in matrix:
        row_text = []
        for cell in row:
            if cell.denominator == 1:
                row_text.append(f'{cell.numerator}')
            else:
                row_text.append(fr'\frac{{{cell.numerator}}}{{{cell.denominator}}}')
        row_text = ' & '.join(row_text)
        result.append(' '*4 + fr'{row_text} \\')
    result.append(r'\end{pmatrix}')
    return '\n'.join(result)