Skip to content

Commit c1daf13

Browse files
committed
Merge branch 'fix_in_div_and_log_operations'
2 parents a5618af + 77d8a5e commit c1daf13

File tree

32 files changed

+2367
-4832
lines changed

32 files changed

+2367
-4832
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,12 @@ tests/.coverage
99
# Ctags folders
1010
.tags
1111
.tags_sorted_by_file
12+
13+
# Ignore files generated by precision_bug scripts
14+
bugs/precision_bug/*.txt
15+
16+
# Ignore files generated by MATLAB test file generators
17+
scripts/*.txt
18+
19+
# Ignore SQLite DBs
20+
*.db

MLC/Application.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ def go(self, to_generation, fig, from_generation=None):
9898
self.evaluate_population(self._simulation.get_last_generation(),
9999
self._simulation.number_of_generations())
100100

101-
self.show_best(self._simulation.get_last_generation())
101+
if fig:
102+
self.show_best(self._simulation.get_last_generation())
102103
MLCTable.get_instance().commit_changes()
103104

104105
for i in range(from_generation + 1, self._simulation.number_of_generations() + 1):

MLC/Common/Lisp_Tree_Expr/Operation_Nodes.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import math
21
import importlib
32

43
import MLC.Log.log as lg
@@ -98,6 +97,7 @@ def op_compute(self, arg_list):
9897

9998
class Division_Node(Internal_Node):
10099
PROTECTION = 0.001
100+
SIMPLIFY_PROTECTION = 0.01
101101

102102
def __init__(self):
103103
Internal_Node.__init__(self, "/", 1)
@@ -107,12 +107,11 @@ def formal(self):
107107

108108
def _process_division(self, dividend, divisor):
109109
if type(divisor) == np.ndarray:
110-
# Check if at least one element is below the protection value
111-
if [x for x in divisor if abs(x) < Division_Node.PROTECTION] != []:
112-
return np.sign(divisor) * dividend / np.repeat(Division_Node.PROTECTION, len(divisor))
110+
new_divisor = [Division_Node.PROTECTION if np.abs(x) < Division_Node.PROTECTION else np.abs(x) for x in divisor]
111+
return np.sign(divisor) * dividend / np.asarray(new_divisor)
113112
else:
114113
if abs(divisor) < Division_Node.PROTECTION:
115-
return dividend / Division_Node.PROTECTION
114+
return np.sign(divisor) * dividend / Division_Node.PROTECTION
116115

117116
return dividend / divisor
118117

@@ -127,7 +126,7 @@ def op_simplify(self):
127126

128127
if not self._nodes[0].is_sensor() and not self._nodes[1].is_sensor():
129128
# FIXME: Harcoded number. Change it
130-
if abs(float(self._nodes[1].to_string())) < 0.01:
129+
if abs(float(self._nodes[1].to_string())) < Division_Node.SIMPLIFY_PROTECTION:
131130
return Leaf_Node(process_float(0))
132131
else:
133132
arg = float(self._nodes[0].to_string()) / float(self._nodes[1].to_string())
@@ -149,7 +148,7 @@ def formal(self):
149148

150149
def op_simplify(self):
151150
if not self._nodes[0].is_sensor():
152-
arg = math.sin(float(self._nodes[0].to_string()))
151+
arg = np.sin(float(self._nodes[0].to_string()))
153152
return Leaf_Node(process_float(arg))
154153
else:
155154
return self
@@ -168,7 +167,7 @@ def formal(self):
168167

169168
def op_simplify(self):
170169
if not self._nodes[0].is_sensor():
171-
arg = math.cos(float(self._nodes[0].to_string()))
170+
arg = np.cos(float(self._nodes[0].to_string()))
172171
return Leaf_Node(process_float(arg))
173172
else:
174173
return self
@@ -179,6 +178,7 @@ def op_compute(self, arg_list):
179178

180179
class Logarithm_Node(Internal_Node):
181180
PROTECTION = 0.00001
181+
SIMPLIFY_PROTECTION = 0.01
182182

183183
def __init__(self):
184184
Internal_Node.__init__(self, "log", 5)
@@ -188,9 +188,7 @@ def formal(self):
188188

189189
def _process_arg(self, arg):
190190
if type(arg) == np.ndarray:
191-
# Check if at least one element is below the protection value
192-
if [x for x in arg if abs(x) < Logarithm_Node.PROTECTION] != []:
193-
return np.repeat(Logarithm_Node.PROTECTION, len(arg))
191+
return [Logarithm_Node.PROTECTION if np.abs(x) < Logarithm_Node.PROTECTION else np.abs(x) for x in arg]
194192
else:
195193
if abs(arg) < Logarithm_Node.PROTECTION:
196194
return Logarithm_Node.PROTECTION
@@ -199,10 +197,10 @@ def _process_arg(self, arg):
199197

200198
def op_simplify(self):
201199
if not self._nodes[0].is_sensor():
202-
if float(self._nodes[0].to_string()) < 0.01:
203-
arg = math.log(0.01)
200+
if float(self._nodes[0].to_string()) < Logarithm_Node.SIMPLIFY_PROTECTION:
201+
arg = np.log(Logarithm_Node.SIMPLIFY_PROTECTION)
204202
else:
205-
arg = math.log(float(self._nodes[0].to_string()))
203+
arg = np.log(float(self._nodes[0].to_string()))
206204

207205
return Leaf_Node(process_float(arg))
208206
else:
@@ -224,9 +222,9 @@ def op_simplify(self):
224222
if not self._nodes[0].is_sensor():
225223
lg.logger_.debug("[EXP NODE] Value: " + self._nodes[0].to_string())
226224
try:
227-
arg = math.exp(float(self._nodes[0].to_string()))
225+
arg = np.exp(float(self._nodes[0].to_string()))
228226
except OverflowError:
229-
# FIXME: See what to do with this expression, because there are problems with
227+
# FIXME: See what to do with this expression, because there are problems when
230228
# an infinite value is the argumento of a sinusoidal function
231229
return Leaf_Node(process_float(float("inf")))
232230

@@ -248,7 +246,7 @@ def formal(self):
248246

249247
def op_simplify(self):
250248
if not self._nodes[0].is_sensor():
251-
arg = math.tanh(float(self._nodes[0].to_string()))
249+
arg = np.tanh(float(self._nodes[0].to_string()))
252250
return Leaf_Node(process_float(arg))
253251
else:
254252
return self

MLC/Scripts/Evaluation/toy_problem.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88

99

1010
def individual_data(indiv):
11-
x = np.arange(-10, 10 + 0.1, 0.1)
12-
# FIXME: Numpy precision it's driving me up the wall. It doesn't put a zero
13-
# in the middle element of the array (put a extremely small number instead).
14-
# That generates problems with the division operation
15-
x[len(x) / 2] = 0
11+
x = np.linspace(-10.0, 10.0, num=201)
1612
y = np.tanh(x**3 - x**2 - 1)
1713

1814
eng = MatlabEngine.engine()

MLC/Scripts/Evaluation/toy_problem_python_ev.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77

88

99
def individual_data(indiv):
10-
x = np.arange(-10, 10 + 0.1, 0.1)
11-
# FIXME: Numpy precision it's driving me up the wall. It doesn't put a zero
12-
# in the middle element of the array (put a extremely small number instead).
13-
# That generates problems with the division operation
14-
x[len(x) / 2] = 0
10+
x = np.linspace(-10.0, 10.0, num=201)
1511
y = np.tanh(x**3 - x**2 - 1)
1612

1713
config = Config.get_instance()

MLC/individual/Individual.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,6 @@ def __change_const_tree(self, tree_expression, leaf_value_generator):
461461

462462
def __str__(self):
463463
return "value: %s\n" % self.get_value() + \
464-
"type: %s\n" % self.get_type() + \
465464
"cost_history: %s\n" % self.get_cost_history() + \
466465
"evaluation_time: %s\n" % self.get_evaluation_time() + \
467466
"appearences: %s\n" % self.get_appearences() + \

bugs/precision_bug/README

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Run MATLAB scripts with the following command:
2+
3+
/path/to/MATLAB/dir/bin/matlab -nodisplay -nosplash -nodesktop -r script
4+
5+
Note: Take a look to the lack of extension in the script. The script MUST be a .m file,
6+
yet the argument of the command receives it without extension

bugs/precision_bug/expr_test.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import sys
2+
sys.path.append("../..")
3+
import binascii
4+
import numpy as np
5+
import struct
6+
import MLC.Log.log as lg
7+
8+
from MLC.Common.Lisp_Tree_Expr.Lisp_Tree_Expr import Lisp_Tree_Expr
9+
from MLC.Log.log import set_logger
10+
from MLC.mlc_parameters.mlc_parameters import Config
11+
12+
13+
def initialize_config():
14+
config = Config.get_instance()
15+
config.read('../../conf/configuration.ini')
16+
return config
17+
18+
# Set printable resolution (don't alter numpy interval resolution)
19+
np.set_printoptions(precision=9)
20+
# Show full arrays, no matter what size do they have
21+
np.set_printoptions(threshold=np.inf)
22+
# Don't show scientific notation
23+
np.set_printoptions(suppress=True)
24+
25+
initialize_config()
26+
set_logger('console')
27+
28+
# Full expression
29+
expr6 = "(root (cos (exp (- -6.3726 (* -7.1746 S0)))))"
30+
expr61 = "(root (exp (- -6.3726 (* -7.1746 S0))))"
31+
expr612 = "(root (- -6.3726 (* -7.1746 S0)))"
32+
33+
tree = Lisp_Tree_Expr(expr6)
34+
x = np.linspace(-10.0, 10.0, num=201)
35+
mlc_y = tree.calculate_expression([x])
36+
37+
# Calculate the Mean squared error
38+
y = np.tanh(x**3 - x**2 - 1)
39+
evaluation = float(np.sum((mlc_y - y)**2))
40+
41+
# print mlc_y
42+
with open("./costs_python.txt", "w") as f:
43+
for elem in mlc_y:
44+
f.write("%50.50f\n" % elem)
45+
46+
print evaluation
47+
print np.sum(mlc_y)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
close all;
2+
clear all;
3+
4+
%--------------------- %
5+
6+
x = -10:0.1:10;
7+
m = 'cos(exp(((-6.3726) - ((-7.1746) .* S0))))';
8+
% m = '((-6.3726) - ((-7.1746) .* S0))';
9+
y = tanh(x.^3-x.^2-1);
10+
m = strrep(m, 'S0', 'x'); y2=eval(m); J=sum((y2-y).^2); fprintf('%.10f\n', J);
11+
12+
filename = './costs_matlab.txt';
13+
file = fopen(filename, 'w');
14+
15+
for i=1:length(x)
16+
fprintf(file, '%50.50f\n', y2(i));
17+
end
18+
19+
fclose(file);

main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def main():
2222

2323
eng = MatlabEngine.engine()
2424
config = initialize_config()
25-
# MatlabEngine.load_random_values("./tests/integration_tests/matlab_randoms.txt")
25+
MatlabEngine.load_random_values("./tests/integration_tests/matlab_randoms.txt")
2626

2727
# Create the MLC2 object and store it in the workspace. With this
2828
# feature we will be able to call every function of the MATLAB code

0 commit comments

Comments
 (0)