Заменить оператор точечного произведения в математической формуле - PullRequest
0 голосов
/ 21 февраля 2020

Как заменить вместо внутреннего знака питона точечного произведения (@) на numpy numpy .dot? Например, формула m.a@x + m.b@y должна быть преобразована в np.dot(m.a, x) + np.dot(m.b, y).

Моей первоначальной мыслью было использование регулярных выражений, чтобы найти текст до и после @ (m.a и m.b в приведенном выше примере), а затем поместить их в функцию точки. Вот как я представляю себе это с помощью регулярных выражений:

# m.a, m.b, x and y are vectors of some equal size
formula = "m.a@x + m.b@y"
before_dots, after_dots = some_regex_function(formula)
result = eval(f"np.dot({before_dot[0]},{after_dot[0]}) + np.dot({before_dot[1]},{after_dot[1]})")

Ответы [ 2 ]

0 голосов
/ 22 февраля 2020

То, что вы ищете, действительно решаемо с помощью регулярных выражений, но имеет смысл, только если вы пытаетесь сделать это в нескольких файлах одновременно.
Кроме того, в этих файлах не должно быть электронных писем, так как электронные письма являются очень большой частью этого множества. шаблон регулярного выражения и почти всегда совпадает.

Здесь - это написанное мной регулярное выражение, которое, надеюсь, охватывает все возможные случаи.

Чтобы сделать это для нескольких файлов, я бы предложил использовать его с perl, так как

perl -i -pe 's/(?<=[^_a-zA-Z])([_a-zA-Z][\w\._]*)@([_a-zA-Z][\w\._]*)(\1|(?=\s))/np.dot(\1, \2)/g'

-i изменяет файл на месте

0 голосов
/ 21 февраля 2020

Используя модули ast и astor, вы можете проанализировать код и заменить все узлы двоичных операций, где оператором является умножение матриц, на вызов np.dot.

import ast
import astor


class ReplaceNpDot(astor.TreeWalk):
    def post_BinOp(self):
        node = self.cur_node
        if isinstance(node.op, ast.MatMult):
            np = ast.Name(id="np", ctx=ast.Load())
            np_dot = ast.Attribute(np, 'dot', ctx=ast.Load())
            self.replace(ast.Call(
                np_dot,
                args=[node.left, node.right],
                keywords=[],
                startargs=[]
            ))
        else:
            return node


# define m so it works...
# ...

# replace @ with np.dot
tree = ast.parse("m.a@x + m.b@y", mode='eval')
walker = ReplaceNpDot()
walker.walk(tree)

# print source code
print(astor.to_source(tree))

# run code
code = compile(ast.fix_missing_locations(tree), '<string>', 'eval')
exec(code)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...