Git Product home page Git Product logo

latexify_py's Introduction

latexify

Python PyPI Latest Release License Downloads Code style: black Imports: isort

latexify is a Python package to compile a fragment of Python source code to a corresponding $\LaTeX$ expression:

Example of latexify usage

latexify provides the following functionalities:

  • Libraries to compile Python source code or AST to $\LaTeX$.
  • IPython classes to pretty-print compiled functions.

FAQs

  1. Which Python versions are supported?

    Syntaxes on Pythons 3.7 to 3.11 are officially supported, or will be supported.

  2. Which technique is used?

    latexify is implemented as a rule-based system on the official ast package.

  3. Are "AI" techniques adopted?

    latexify is based on traditional parsing techniques. If the "AI" meant some techniques around machine learning, the answer is no.

Getting started

See the example notebook, which provides several use-cases of this library.

You can also try the above notebook on Google Colaboratory.

See also the official documentation for more details.

How to Contribute

To contribute to this project, please refer CONTRIBUTING.md.

Disclaimer

This software is currently hosted on https://github.com/google, but not officially supported by Google.

If you have any issues and/or questions about this software, please visit the issue tracker or contact the main maintainer.

License

This software adopts the Apache License 2.0.

latexify_py's People

Contributors

0xflotus avatar 1mlightyears avatar afrozchakure avatar aritrakar avatar casper-guo avatar cclauss avatar chunibyo-wly avatar cool-rr avatar ctarnold avatar erica-w-fu avatar j-douglas avatar jasonlmfong avatar jianan1104 avatar jonbarron avatar kshxtij avatar lakeblair avatar leewalter avatar liyishuai avatar marvinvanaalst avatar odashi avatar raphael-cv avatar ryosuketc avatar ryxcommar avatar shigekikarita avatar specbug avatar wiljav avatar ziadamerr avatar zibingzhang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

latexify_py's Issues

n+1-1 in sum/prod

Currently the analyzer of sum and prod does not recognize the reducable addition and subtraction in the stop parameter of range:

It would be good if we could get $n$ rather than $n+1-1$ in most cases. This reduction would be safe because the operands of range must be integers, whose objects must be always associative and commutative in terms of operations $+$ and $-$.

underscores in variable names not displaying correctly

@latexify.function
def solve(a_a, b, c):
return (-b + math.sqrt(b**2 - 4a_ac)) / (2*a_a)

solve # Display the MathJax.

Will produce the variable a, with the next a as a subscript, instead of displaying the underscore.

I'm back now

Hi, I haven't been working in this repository for a long time, but according to the situation that the repository is getting more audience, I guessed I need to take certain time for this repository. I will work for remaining issues/PRs in this/next week.

Can't install using command `pip install latexify-py`

C:\Users\Vanja\Desktop>python --version
Python 3.10.5

C:\Users\Vanja\Desktop>pip install latexify-py
WARNING: Ignoring invalid distribution -p (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -ip (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution - (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -p (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -ip (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution - (c:\python310\lib\site-packages)
ERROR: Ignored the following versions that require a different python version: 0.0.4 Requires-Python >=3.6, <3.9; 0.0.5 Requires-Python >=3.6, <3.9; 0.0.6 Requires-Python >=3.6, <3.9; 0.0.7 Requires-Python >=3.6, <3.9
ERROR: Could not find a version that satisfies the requirement latexify-py (from versions: none)
ERROR: No matching distribution found for latexify-py
WARNING: Ignoring invalid distribution -p (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -ip (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution - (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -p (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -ip (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution - (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -p (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution -ip (c:\python310\lib\site-packages)
WARNING: Ignoring invalid distribution - (c:\python310\lib\site-packages)

Write the latexify object directly to file

Hi,
I have a question. When printing the function with the latexify decorator, is there any way that I can use the format string to print the "function" string directly. As I have 10 functions name from "p1" to "p10". Is it possible to write a for loop to print all the functions?
Also, is it possible to directly convert the function to string and write it to a file? Thanks!
Thanks.

Support guard clauses

Running in the colab notebook, noticed guard clauses are not supported in the cell rendering. Thought they are common enough, to get support

# works 
@latexify.function
def foo(x): 
    if x > 0: 
        return x
    else: 
        return 0 

foo 


@latexify.function 
def foo(x): 
    if x > 0: 
         return x

    return 0

# raises LatexifyNotSupportedError
foo

version: 0.2.0b2

Showing some special arrays

Ref: #78

We can also support showing some special array functions as a fixed, well-known form. For example, ndarray.zeros((2, 3)) --> $\mathbf{0}$ or $\mathbf{0}^{2 \times 3}$

Support expanding some functions

Follows #63

It is good to provide a expand_functions boolean option to control whether some composite functions are expanded or not, e.g.:

  • hypot(x, y) -> $\sqrt{x^2 + y^2}$
  • atan2(y, x) -> $\arctan{\frac{y}{x}}$
  • expit(x) -> $\frac{1}{1+\exp{(-x)}}$

Support IfExp

Support the expression syntax a if x else b. Since we have already a codegen for if-statements, IfExp should generate the same LaTeX.

็„ก้กŒ

Breaking on function with docstring

I am getting the error below for the following function:

@latexify.function(use_math_symbols=True)
def model(t: float, y: list, params: dict) -> list:
        """
        SIR Model.
        :param t: time step
        :param y: state of the model at time t
        :param params: parameter dictionary
        :return:
        """
        S, I, R = y
        beta, gamma, N = params['beta'], params['gamma'], params['N']
        return [
            -beta * S * I / N,
            beta * S * I / N - gamma * I,
            gamma * I
        ]
LatexifyNotSupportedError: Codegen supports only Assign nodes in multiline functions, but got: Expr

If I remove the docstring, it works as expected

Automatically detecting imported libraries

Ref: #86

Sometimes users import libraries with custom names, and the current implementation of latexify does not recognize it without passing the custom config (this is not the current feature: tracked by #87)

We can anyway list up the all imported modules through globals(), and check if they contains some well known libraries. For example, if the user invoked import numpy as np, globals()["np"] should point to a module with __name__ == "numpy".

This is clever enough I think, but applying this involves environment-dependent behavior. I think this can be implemented as an additional NodeTransformer with a boolean switch which is turned off by default.

Add mathopen and mathclose to parentheses

Since \left( and \right) are not correctly treated as brackets, they accidentally insert additional whitespaces around the symbols. It would be better to replace all \left( to \mathopen{}\left( and \right) to \mathclose{}\right):

็„ก้กŒ

Ability to get latex without getting function name

import latexify
def solve(a):
	return 5 * a
print(latexify.get_latex(solve, no_function=True))

to be 5a, not \mathrm{solve}(a) \triangleq 5a

i think it's better to create another function not parameter or set by default

Multiple statements functions

Currently this tool analyses only the first statement of given functions, and passing multi-statement function results in generating garbages. Basically multiple statements are hard to interpret as a single equation and it is good not to support such things in the current with_latex and better to provide some other interfaces.

I am thinking of two things:

  1. latexify.array/latexify.eqnarray for functions without control flow ... these may only contain the sequence of assignments/augmentations and we can represent them as equation arrays.
  2. latexify.algorithm for general functions ... these are generally impossible to be written as simple equations, but we can output algorithmic form instead. Each statements can still be written by LaTeX formulas.

If we provide these functions, it is also good to rename latexify.with_latex to latexify.equation or some.

Config class

Follows #65

It may be good if we provide a config class integrating every setting, which are currently passed directly to with_latex:

import latexify

config = latexify.Config.defaults()
config.use_math_symbols()
config.expand_function("expit")

@latexify.with_latex(config)
def f(x):
    return expit(x)

# Will generate: \mathrm{f}(x) \triangleq \frac{1}{1+\exp{(-x)}}

Some basic questions about this awesome project

Hi, I accidentally found this project and it spends me quite a few time to basically figure out how this works and I'm still a little confused about it. Can I just simply summarize this Python package as a "decorator" which is used when we are writing a function in Python to generate an extra formula in Latex format?

Limits in Summations

Hello Team - thanks for this wonderful package, I was wondering how do we put a limit on summation.
image

Thanks in advance :)

Weird output for some functions

There are some cases where generated LaTeX contains some weird strings (probably artifacts of the ast library). Here's a minimal example:

@latexify.with_latex
def foo(a):
 c = foo(a-1)
 return c

>>> print(foo)
>>> \mathrm{foo}(a)\triangleq <_ast.Assign object at 0x000001E3DD084F88>

Lack of equals sign

I dont know if it is my techniques problem. When I run the sample code on Pycharm and use the converted latex code, there is no equals sign between left hand expression and right hand expression.

11b89272a66074b52982a8a284fa87f

FYI: waiting for org response

I am currently stopping to develop everything and waiting for approvals from my org. It will remain several days. I will process PRs and issues but won't push any changes by me for awhile. Thank you for understanding.

Do not comment here.

Support for methods

Description

I would like to be able to latexify class(instance) methods such as this simple example:

class Test:
    @latexify.function
    def fun(self,a,b):
        return a+b
T = Test()
T.fun

this simple example does not work on 0.2.0b2

tf-keras functions doesn't work

I was trying to generate latex quickly from my python code, but it didn't return the output as expected.

Code:

import latexify
import tensorflow.keras.backend as K

@latexify.with_latex
def dice_coef(y_true, y_pred, smooth = 1):
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    intersection = K.sum(y_true_f * y_pred_f)
    return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)



print(dice_coef)
dice_coef

latexify_py doesn't work with tensorflow or keras

Error using pip to install it.

ERROR: latexify_py is not a valid editable requirement. It should either be a
th to a local project or a VCS URL (beginning with svn+, git+, hg+, or bzr+).

Support for nested functions

As an example use case, I have a function that takes in a dataset and returns a closure based on that dataset.

def gen_normalizer(df):

    def normalize_row_based_on_dataset(row):
        return (row - df.mean()) / df.std()
    
    return normalize_row_based_on_dataset

I would love to be able to apply the decorator to the nested function so that later in my experiment I can display a set of different Normalizers in LaTeX. However, currently adding the decorator to the nested function results in the following error:

File <unknown>:1
    @latexify.with_latex
    ^
IndentationError: unexpected indent

Support substitutions of names

According to: #46 (comment)

Currently, latexify uses only the syntax information of the functions wrapped by with_latex and the decorator does not know any bound values outside the function. Some people want to substitute identifiers in the function into its actual value. For example:

# Values bound by literals
t = 42
@with_latex
def diff(y):
    return y - t

# Values bound by given variables
def wrapper(t):
    @with_latex
    def diff(y):
        return y - t

mydiff = wrapper(42)

In both cases the user may want to see [ $diff(y) \triangleq y - 42$ ], not [ $diff(y) \triangleq y - t$ ].

I think implementing additional parameter to with_latex to specify substitutions, for example:

@with_latex(substitutions={"t": t})
def diff(y):
    ...

is a handy solution at this moment, though users are required to write some additional stuff. To implement it, we need to define a substitution rule in the AST visitor that replaces matched identifiers to given strings (or any values that can be converted into a string).

NDArray support

Sometimes users want to support NDArrays in this library, e.g., np.array([[a, b], [c, d]]) to

$$\left( \begin{array}{cc}a&b \\ c&d\end{array} \right)$$

This is definitely useful, but often it is not possible to compile:

  • Large arrays.
  • Arrays with more than 2 dimensions.

I think we could start implementing it with reasonable restrictions (e.g., only NDArrays with <= 2 dimensions with small lengths), but it would be also good to keep discussion.

Refs:

support indicies

Add suppot for indicies

import math
import latexify

@latexify.with_latex
def solve(a):
	return a[0]

print(solve)

to be something like \mathrm{solve}(a) \triangleq a_0

Support for nested functions

Screenshot from 2022-10-05 11-18-55

In the image above, I have a function that I would like to represent using latexify.

I think the usage in code would be something as follows:

@latexify.with_latex
def pondera(a,b, func):
    return (a*abs(func(b)) + b*abs(func(a)))/ (abs(func(b)) + abs(func(a))) 

It doesn't work out of the box in latexify. How can it be accomplished?

Wrong behavior around multiplication

The current implementation converts a * b into $ab$. This only works if the variables have only 1 character and doesn't generate a correct syntax for other cases:

  • Long names: abc * def --> $abcdef$, which is hard to distinguish from other combination of variables.
  • Unary operators: x * -y --> $x - y$, which is definitely wrong.

These cases require explicit multiply operator ( $\cdot$ or $\times$ ) between the operands.

I think the Mult(left, right) subtree should be converted to $left \cdot right$ by default, and try to avoid the operator only in the following cases:

  • The left-hand side operand is a single character or a bracket (with or without unary operators and/or super/subscripts)
  • The right-hand side operand is a single character or a bracket (with or without super/subscripts, without unary operators)

This requires fine-graind name processing, and may be applied after #82.

Configs to control the behavior.

It is worth to provide some mechanism to specify particular behaviors by users, such as:

  • Specifying commands for particular operators (e.g., definition is usually represented as =, :=, \equiv, \triangleq, {\rm def} over =, or \leftarrow).
  • Auto-converting math symbols.
  • Appearances of control flow, or long equations.

Currently, with_latex decorator have an optional flag for math symbols, and I am suggesting to add similar ones for other options (#15). This way finally introduces a bunch of particular flags. So we need more sophisticated way to control these behavior.

Multiple Return Values

I'm submitting this issue, instead of directly working on it, because I'm not sure if multiple return values is practical or not.

Actually, I haven't seen any function in papers I read has more than one return value, but in some special occasions-say pseudo codes-I do see some functions "equal" a list of numbers, like pseudo_linspace(n)=1,2,...,n-1

Are we going to take these occasions in consideration, or abandon them, for they are literally rarely seen?

Fine-grained name processing

There are still some issues around name processing:

In the current implementation, only the function names are processed separately, but I think that that behavior is generally preferred for all identifiers, and it should be applied by default.

In some specific cases, it would be still good to process underscores (e.g., trailing numbers: x_123 -> $x_{123}$), but rather this feature should be the option than retaining underscores.

Package name trimming as a NodeTransformer

Prefixes of well-known packages are trimmed by the following code block in function_codegen.py

# Removes common prefixes: math.sqrt -> sqrt
# TODO(odashi): This process can be implemented as a NodeTransformer.
for prefix in constants.PREFIXES:
if func_str.startswith(f"{prefix}."):
func_str = func_str[len(prefix) + 1 :]
break

As I noted in the TODO, this can be implemented as a NodeTransformer preprocessor. This change would make the behavior more flexible.

For example, the AST of math.sqrt(x) is:

Call(
    func=Attribute(
        value=Name(id='math', ctx=Load()),
        attr='sqrt',
        ctx=Load()),
    args=[
        Name(id='x', ctx=Load())],
    keywords=[])

and we can implement NodeTransformer to modify the above to:

Call(
    func=Name(id='sqrt', ctx=Load()),
    args=[
        Name(id='x', ctx=Load())],
    keywords=[])

The modification may be applied on only the func subtree.

Setting one directory for all test scripts

I would like to suggest that you can make one directory outside the source code directory to hold all testing scripts this might be helpful even when the codebase grows. If this is acceptable I am open to helping restructure it.
Thanks:)

Generates algorithmic environment

I have worked recently to investigate if we could generate the LaTeX algorithm environment from the function.
Actually it can work like this:

FfJj0MyVEAAe01M

I think this feature is really useful for almost arbitrary functions.

Supporting Set operations and comprehensions

It would be nice to support some more set operations and comprehensions, since they're pretty easy to use in python. (I assume this is going to be fairly difficult though, since it requires a fair amount of information from the python ast)

For example, this code:

@latexify.with_latex
def solve():
    return {x ** 2 for x in range(1, 10)}

Returns this currently:

\displaystyle \mathrm{solve}() \triangleq <ast.SetComp object at 0x7f6920238160>

It would be nice to show something like this:

\displaystyle \mathrm{solve}() \triangleq \{x\mid x^2\in\Bbb \(1..10\)\}

$$ \displaystyle \mathrm{solve}() \triangleq {x\mid x^2\in\Bbb (1..10)} $$

And operations on sets:

@latexify.with_latex
def solve(x: set, y: set):
    return x | y
    

Returns this currently:

\displaystyle \mathrm{solve}(x, y) \triangleq \mathrm{unknown\_binop}(x, y)

It could be something like this:

\displaystyle \mathrm{solve}(x, y) \triangleq x \cup y

$$ \displaystyle \mathrm{solve}(x, y) \triangleq x \cup y $$

in and not in could also be supported, like x in A or x not in A like this:

x\in A, x\notin A

$$ \displaystyle \mathrm{solve}() \triangleq x\in A $$

$$ \displaystyle \mathrm{solve}() \triangleq x\notin A $$

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.