-
Notifications
You must be signed in to change notification settings - Fork 391
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added remaining Numpy NDArray single function expressions #183
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,8 +23,8 @@ def __init__( | |
"""Initializer. | ||
|
||
Args: | ||
use_math_symbols: Whether to convert identifiers with a math symbol surface | ||
(e.g., "alpha") to the LaTeX symbol (e.g., "\\alpha"). | ||
use_math_symbols: Whether to convert identifiers with a math symbol | ||
surface (e.g., "alpha") to the LaTeX symbol (e.g., "\\alpha"). | ||
use_set_symbols: Whether to use set symbols or not. | ||
""" | ||
self._identifier_converter = identifier_converter.IdentifierConverter( | ||
|
@@ -240,6 +240,129 @@ def _generate_transpose(self, node: ast.Call) -> str | None: | |
else: | ||
return None | ||
|
||
def _generate_determinant(self, node: ast.Call) -> str | None: | ||
"""Generates LaTeX for numpy.linalg.det. | ||
Args: | ||
node: ast.Call node containing the appropriate method invocation. | ||
Returns: | ||
Generated LaTeX, or None if the node has unsupported syntax. | ||
Raises: | ||
LatexifyError: Unsupported argument type given. | ||
""" | ||
name = ast_utils.extract_function_name_or_none(node) | ||
assert name == "det" | ||
|
||
if len(node.args) != 1: | ||
return None | ||
|
||
func_arg = node.args[0] | ||
if isinstance(func_arg, ast.Name): | ||
return rf"\det \left( \mathbf{{{func_arg.id}}} \right)" | ||
elif isinstance(func_arg, ast.List): | ||
return rf"\det \left( {self._generate_matrix(node)} \right)" | ||
|
||
return None | ||
|
||
def _generate_matrix_rank(self, node: ast.Call) -> str | None: | ||
"""Generates LaTeX for numpy.linalg.matrix_rank. | ||
Args: | ||
node: ast.Call node containing the appropriate method invocation. | ||
Returns: | ||
Generated LaTeX, or None if the node has unsupported syntax. | ||
Raises: | ||
LatexifyError: Unsupported argument type given. | ||
""" | ||
name = ast_utils.extract_function_name_or_none(node) | ||
assert name == "matrix_rank" | ||
|
||
if len(node.args) != 1: | ||
return None | ||
|
||
func_arg = node.args[0] | ||
if isinstance(func_arg, ast.Name): | ||
return rf"\mathrm{{rank}} \left( \mathbf{{{func_arg.id}}} \right)" | ||
elif isinstance(func_arg, ast.List): | ||
return rf"\mathrm{{rank}} \left( {self._generate_matrix(node)} \right)" | ||
|
||
return None | ||
|
||
def _generate_matrix_power(self, node: ast.Call) -> str | None: | ||
"""Generates LaTeX for numpy.linalg.matrix_power. | ||
Args: | ||
node: ast.Call node containing the appropriate method invocation. | ||
Returns: | ||
Generated LaTeX, or None if the node has unsupported syntax. | ||
Raises: | ||
LatexifyError: Unsupported argument type given. | ||
""" | ||
name = ast_utils.extract_function_name_or_none(node) | ||
assert name == "matrix_power" | ||
|
||
if len(node.args) != 2: | ||
return None | ||
|
||
func_arg = node.args[0] | ||
power_arg = node.args[1] | ||
if isinstance(power_arg, ast.Num): | ||
if isinstance(func_arg, ast.Name): | ||
return rf"\mathbf{{{func_arg.id}}}^{{{power_arg.n}}}" | ||
elif isinstance(func_arg, ast.List): | ||
matrix = self._generate_matrix(node) | ||
if matrix is not None: | ||
return rf"{matrix}^{{{power_arg.n}}}" | ||
return None | ||
|
||
def _generate_qr_and_svd(self, node: ast.Call) -> str | None: | ||
"""Generates LaTeX for numpy.linalg.qr and numpy.linalg.svd. | ||
Args: | ||
node: ast.Call node containing the appropriate method invocation. | ||
Returns: | ||
Generated LaTeX, or None if the node has unsupported syntax. | ||
Raises: | ||
LatexifyError: Unsupported argument type given. | ||
""" | ||
name = ast_utils.extract_function_name_or_none(node) | ||
assert name == "QR" or name == "SVD" | ||
|
||
if len(node.args) != 1: | ||
return None | ||
|
||
func_arg = node.args[0] | ||
if isinstance(func_arg, ast.Name): | ||
func_arg_str = rf"\mathbf{{{func_arg.id}}}" | ||
return rf"\mathrm{{{name.upper()}}} \left( {func_arg_str} \right)" | ||
|
||
elif isinstance(func_arg, ast.List): | ||
matrix_str = self._generate_matrix(node) | ||
return rf"\mathrm{{{name.upper()}}} \left( {matrix_str} \right)" | ||
return None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function can be removed. The current implementation converts |
||
|
||
def _generate_inverses(self, node: ast.Call) -> str | None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks there is no reason to combine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify, would you rather I separate them into two different functions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that would be reasonable I think. |
||
"""Generates LaTeX for numpy.linalg.inv. | ||
Args: | ||
node: ast.Call node containing the appropriate method invocation. | ||
Returns: | ||
Generated LaTeX, or None if the node has unsupported syntax. | ||
Raises: | ||
LatexifyError: Unsupported argument type given. | ||
""" | ||
name = ast_utils.extract_function_name_or_none(node) | ||
assert name == "inv" or name == "pinv" | ||
|
||
if len(node.args) != 1: | ||
return None | ||
|
||
func_arg = node.args[0] | ||
if isinstance(func_arg, ast.Name): | ||
if name == "inv": | ||
return rf"\mathbf{{{func_arg.id}}}^{{-1}}" | ||
return rf"\mathbf{{{func_arg.id}}}^{{+}}" | ||
elif isinstance(func_arg, ast.List): | ||
if name == "inv": | ||
return rf"{self._generate_matrix(node)}^{{-1}}" | ||
return rf"{self._generate_matrix(node)}^{{+}}" | ||
return None | ||
|
||
def visit_Call(self, node: ast.Call) -> str: | ||
"""Visit a Call node.""" | ||
func_name = ast_utils.extract_function_name_or_none(node) | ||
|
@@ -256,6 +379,16 @@ def visit_Call(self, node: ast.Call) -> str: | |
special_latex = self._generate_identity(node) | ||
elif func_name == "transpose": | ||
special_latex = self._generate_transpose(node) | ||
elif func_name == "det": | ||
special_latex = self._generate_determinant(node) | ||
elif func_name == "matrix_rank": | ||
special_latex = self._generate_matrix_rank(node) | ||
elif func_name == "matrix_power": | ||
special_latex = self._generate_matrix_power(node) | ||
elif func_name in ("QR", "SVD"): | ||
special_latex = self._generate_qr_and_svd(node) | ||
elif func_name in ("inv", "pinv"): | ||
special_latex = self._generate_inverses(node) | ||
else: | ||
special_latex = None | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks some generation rules don't follow the convention of the library:
\mathopen{}\left*
and\mathclose{}\right*