Add files via upload
This commit is contained in:
parent
5a301e2f48
commit
f0cc7dfcaa
19 changed files with 1210 additions and 182 deletions
122
Code/S_add_bf_on_numbers_on_pareto.py
Normal file
122
Code/S_add_bf_on_numbers_on_pareto.py
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
# Adds on the pareto all the snapped versions of a given expression (all paramters are snapped in the end)
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
import torch.optim as optim
|
||||
import torch.utils.data as utils
|
||||
from torch.autograd import Variable
|
||||
from sklearn.metrics import roc_curve, auc
|
||||
from sklearn.preprocessing import label_binarize
|
||||
from sklearn.manifold import TSNE
|
||||
import copy
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore")
|
||||
import sympy
|
||||
from S_snap import integerSnap
|
||||
from S_snap import zeroSnap
|
||||
from S_snap import rationalSnap
|
||||
from S_get_symbolic_expr_error import get_symbolic_expr_error
|
||||
from get_pareto import Point, ParetoSet
|
||||
from S_brute_force_number import brute_force_number
|
||||
|
||||
from sympy import preorder_traversal, count_ops
|
||||
from sympy.abc import x,y
|
||||
from sympy.parsing.sympy_parser import parse_expr
|
||||
from sympy import Symbol, lambdify, N, simplify, powsimp
|
||||
from RPN_to_eq import RPN_to_eq
|
||||
|
||||
from S_get_number_DL_snapped import get_number_DL_snapped
|
||||
|
||||
# parameters: path to data, math (not RPN) expression
|
||||
def add_bf_on_numbers_on_pareto(pathdir, filename, PA, math_expr):
|
||||
def unsnap_recur(expr, param_dict, unsnapped_param_dict):
|
||||
"""Recursively transform each numerical value into a learnable parameter."""
|
||||
import sympy
|
||||
from sympy import Symbol
|
||||
if isinstance(expr, sympy.numbers.Float) or isinstance(expr, sympy.numbers.Integer) or isinstance(expr, sympy.numbers.Rational) or isinstance(expr, sympy.numbers.Pi):
|
||||
used_param_names = list(param_dict.keys()) + list(unsnapped_param_dict)
|
||||
unsnapped_param_name = get_next_available_key(used_param_names, "p", is_underscore=False)
|
||||
unsnapped_param_dict[unsnapped_param_name] = float(expr)
|
||||
unsnapped_expr = Symbol(unsnapped_param_name)
|
||||
return unsnapped_expr
|
||||
elif isinstance(expr, sympy.symbol.Symbol):
|
||||
return expr
|
||||
else:
|
||||
unsnapped_sub_expr_list = []
|
||||
for sub_expr in expr.args:
|
||||
unsnapped_sub_expr = unsnap_recur(sub_expr, param_dict, unsnapped_param_dict)
|
||||
unsnapped_sub_expr_list.append(unsnapped_sub_expr)
|
||||
return expr.func(*unsnapped_sub_expr_list)
|
||||
|
||||
|
||||
def get_next_available_key(iterable, key, midfix="", suffix="", is_underscore=True):
|
||||
"""Get the next available key that does not collide with the keys in the dictionary."""
|
||||
if key + suffix not in iterable:
|
||||
return key + suffix
|
||||
else:
|
||||
i = 0
|
||||
underscore = "_" if is_underscore else ""
|
||||
while "{}{}{}{}{}".format(key, underscore, midfix, i, suffix) in iterable:
|
||||
i += 1
|
||||
new_key = "{}{}{}{}{}".format(key, underscore, midfix, i, suffix)
|
||||
return new_key
|
||||
|
||||
eq = parse_expr(str(math_expr))
|
||||
expr = eq
|
||||
# Get the numbers appearing in the expression
|
||||
is_atomic_number = lambda expr: expr.is_Atom and expr.is_number
|
||||
eq_numbers = [subexpression for subexpression in preorder_traversal(expr) if is_atomic_number(subexpression)]
|
||||
# Do bf on one parameter at a time
|
||||
bf_on_numbers_expr = []
|
||||
for w in range(len(eq_numbers)):
|
||||
param_dict = {}
|
||||
unsnapped_param_dict = {'p':1}
|
||||
eq_ = unsnap_recur(expr,param_dict,unsnapped_param_dict)
|
||||
eq = eq_
|
||||
|
||||
np.savetxt(pathdir+"number_for_bf_%s.txt" %w, [eq_numbers[w]])
|
||||
brute_force_number(pathdir,"number_for_bf_%s.txt" %w)
|
||||
# Load the predictions made by the bf code
|
||||
bf_numbers = np.loadtxt("results.dat",usecols=(1,),dtype="str")
|
||||
new_numbers = copy.deepcopy(eq_numbers)
|
||||
|
||||
# replace the number under consideration by all the proposed bf numbers
|
||||
for kk in range(len(bf_numbers)):
|
||||
eq = eq_
|
||||
new_numbers[w] = parse_expr(RPN_to_eq(bf_numbers[kk]))
|
||||
|
||||
jj = 0
|
||||
for parm in unsnapped_param_dict:
|
||||
if parm!="p":
|
||||
eq = eq.subs(parm, new_numbers[jj])
|
||||
jj = jj + 1
|
||||
|
||||
bf_on_numbers_expr = bf_on_numbers_expr + [eq]
|
||||
for i in range(len(bf_on_numbers_expr)):
|
||||
try:
|
||||
# Calculate the error of the new, snapped expression
|
||||
snapped_error = get_symbolic_expr_error(pathdir,filename,str(bf_on_numbers_expr[i]))
|
||||
# Calculate the complexity of the new, snapped expression
|
||||
expr = simplify(powsimp(bf_on_numbers_expr[i]))
|
||||
is_atomic_number = lambda expr: expr.is_Atom and expr.is_number
|
||||
numbers_expr = [subexpression for subexpression in preorder_traversal(expr) if is_atomic_number(subexpression)]
|
||||
|
||||
snapped_complexity = 0
|
||||
for j in numbers_expr:
|
||||
snapped_complexity = snapped_complexity + get_number_DL_snapped(float(j))
|
||||
# Add the complexity due to symbols
|
||||
n_variables = len(expr.free_symbols)
|
||||
n_operations = len(count_ops(expr,visual=True).free_symbols)
|
||||
if n_operations!=0 or n_variables!=0:
|
||||
snapped_complexity = snapped_complexity + (n_variables+n_operations)*np.log2((n_variables+n_operations))
|
||||
|
||||
PA.add(Point(x=snapped_complexity, y=snapped_error, data=str(expr)))
|
||||
except:
|
||||
continue
|
||||
|
||||
return(PA)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue