google / latexify_py Goto Github PK
View Code? Open in Web Editor NEWA library to generate LaTeX expression from Python code.
License: Apache License 2.0
A library to generate LaTeX expression from Python code.
License: Apache License 2.0
Hi,
Very nice tool. Thanks a lot. I was just wondering if there will be any support for libraries like NumPy, PyTorch or TensorFlow?
I am using Windows 11 and I have python 3.9.11 installed on my laptop. I for this error when I used the code pip install latexify-py
Please help.
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+).
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?
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
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
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?
exec("""
def solve(a, b, c):
return (-b + math.sqrt(b**2 - 4ac)) / (2*a)
""")
lat = latexify.get_latex(solve)
Will result in: OSError: could not extract source code
The current implementation converts a * b
into
abc * def
--> x * -y
--> These cases require explicit multiply operator (
I think the Mult(left, right)
subtree should be converted to
This requires fine-graind name processing, and may be applied after #82.
it looks this lib isn't supported on pypi so how can i install it ?
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.
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.
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
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
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
It is worth to provide some mechanism to specify particular behaviors by users, such as:
=
, :=
, \equiv
, \triangleq
, {\rm def}
over =
, or \leftarrow
).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.
Sometimes users want to support NDArrays in this library, e.g., np.array([[a, b], [c, d]])
to
This is definitely useful, but often it is not possible to compile:
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:
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
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
->
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)
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:)
Ref: #78
We can also support showing some special array functions as a fixed, well-known form. For example, ndarray.zeros((2, 3))
-->
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.
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.
It would be great if we support the match
statement added in Python 3.10, but the entire syntax is somewhat complex.
Ref: #86
Currently we hard-coded function prefixes to be trimmed as follows:
latexify_py/src/latexify/constants.py
Line 5 in 86e6129
It would be good if the users can set it manually.
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 [
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).
@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.
Is it harder to generate Python functions from LaTeX math description? This function will be great for read ML papers.
Something like this would be a good idea:
I have an implementation here, but I am not sure if it is good, or if it will do unexpected things:
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\)\}
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
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
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>
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
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 range
must be integers, whose objects must be always associative and commutative in terms of operations
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)
-> atan2(y, x)
-> expit(x)
-> 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:
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.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.
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?
It would be interesting to implement some matrix operations such as:
Lb = np.array(Lb) - ((numerand/pivot)* np.array(La))
Prefixes of well-known packages are trimmed by the following code block in function_codegen.py
latexify_py/src/latexify/codegen/function_codegen.py
Lines 127 to 132 in 071a12d
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.
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)}}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.