File size: 2,183 Bytes
7145fd6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import sympy as sp
import random

from .parser import parse_prefix_to_sympy

isconst = lambda e: not any(c.is_symbol for c in e.atoms())
def constfold(expr):
    q = [expr]
    cidx = 0
    subsmap = {}
    constmap = {}

    while len(q) > 0:
        curr_expr = q.pop(0)
        if isinstance(curr_expr, sp.Number) or isconst(e):
            const_expr = curr_expr.evalf()
            rep = sp.nsimplify(const_expr, [sp.E, sp.pi])
            if isinstance(rep, sp.Integer) or \
                    (isinstance(rep, sp.Rational) and rep.q <= 16):
                subsmap[curr_expr] = rep
            else:
                subsmap[curr_expr] = sp.Symbol(f"k{cidx}")
                constmap[f"k{cidx}"] = float(const_expr)
                cidx += 1
        else:
            for child in curr_expr.args:
                q.append(child)

    return expr.subs(subsmap), constmap

def replace_const(expr):
    cidx = 0
    subsmap = {}
    constmap = {}

    for c in sp.preorder_traversal(expr):
        if isinstance(c, sp.Float):
            rep = sp.nsimplify(c)
            if isinstance(rep, sp.Integer) or \
                    (isinstance(rep, sp.Rational) and rep.q <= 16):
                subsmap[c] = rep
            else:
                subsmap[c] = sp.Symbol(f"c{cidx}")
                constmap[f"c{cidx}"] = float(c)
                cidx += 1
    return expr.subs(subsmap), constmap


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser("Random experiments")
    parser.add_argument("-f", required=True)
    parser.add_argument("-p", type=float, default=0.1)
    parser.add_argument("-n", type=int, default=20)
    args = parser.parse_args()

    random.seed(1225)
    
    count = 0
    with open(args.f, "r") as f:
        for line in f:
            if random.random() > args.p:
                continue

            prefl = line.strip().split(" ")

            orig = parse_prefix_to_sympy(prefl)
            # simp = sp.simplify(expr)
            expr = constfold(orig)
            expr, consts = replace_const(expr)
            print(orig, expr, consts)

            count += 1
            if count == args.n:
                break