-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGEP_Regression_parfeval.m
More file actions
233 lines (199 loc) · 7.23 KB
/
GEP_Regression_parfeval.m
File metadata and controls
233 lines (199 loc) · 7.23 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
clc;clear;
close all;
% for i = 1:10
% f(i) = parfeval(@rand, 1, 1);
% end
%
% afterEach(f,@disp,0);
%
% return
% --fetchOutputs
% MATLAB returns the Future object F before the function fcn finishes running.
% You can use fetchOutputs to retrieve the results [Y1,...,Yn] from the future.
% --cancel
% To stop running the function fcn, use the cancel function.
% --wait
% Unfortunately, the MATLAB debugger can't stop in code running on the
% workers - only code running at the client.
% In this case, you should try looking at the diary output of the
% future f, like this:
% f = parfeval(..);
% wait(f); % wait for the worker to complete
% disp(f.Diary); % display the output
% --afterEach
% Run function after each function finishes running in the background.
% If you don't wish to block the client, you could use afterEach to
% invoke the call to disp, like this:
% f = parfeval(..);
% afterEach(f, @(f) disp(f.Diary), 0, 'PassFuture', true);
% compare to 'wait' function, it will saving time cost.
% If the Future array has M elements, the MATLAB client runs
% the callback function M times.
% MATLAB runs fcn(X1,...,Xm) using the outputs X1,...,Xm from each Future
% element in A as the elements finish.
% --afterAll
% ...
% --disp
% Each future has a unique ID property for the lifetime of the client.
% Check the ID property of each of the futures in f: disp(f)
% --waitbar
% You can use the State property to obtain the status of futures.
% Create a logical array where the State property of the futures in f
% is "finished". Use mean to calculate the fraction of finished futures.
% Then, create an anonymous function updateWaitbar. The function changes
% the fractional wait bar length of h to the fraction of finished futures.
% e.g. updateWaitbar = @(~) waitbar(mean({f.State} == "finished"),h);
% target = @(a,b)2*a - b;
target = @(a,b)2*a - b^2;
% target = @(a,b)(a+b)^2 + 3*a - b;
% target = @(a)a^2/2 + 3*a;
% target = @(x)5*x^4 + 4*x^3 + 3*x^2 + 2*x + 1;
% target = @(x)sin(x) + cos(x);
sample_num = 10;
var_num = 2;
environment = zeros(sample_num, var_num + 1); % a&b is 2, target is 3
for i = 1 : sample_num
for j = 1 : var_num
environment(i,j) = randn;
end
environment(i,end) = target(environment(i,1), environment(i,2));
end
tol = 0.01;
selection_range = 1000;
T = "ab";
F = "+-*/"; % 'sin', 'cos'
link_function = '+';
head_length = 15;
gene_num = 3;
individual_num = 10;
chromosome_num = 1;
max_generation = 20;
mutation_rate = 0.1; % 0.044
inversion_rate = 0.1;
transIS_rate = 0.1;
transRIS_rate = 0.1;
transGene_rate = 0.1;
rec1P_rate = 0.4;
rec2P_rate = 0.2;
recGene_rate = 0.1;
% initial multi populations
pn = 3;
populations = [];
for i = 1 : pn
population = PopulationClass( ...
individual_num, chromosome_num, max_generation, ...
mutation_rate, inversion_rate, ...
transIS_rate, transRIS_rate, transGene_rate, ...
rec1P_rate,rec2P_rate, recGene_rate, ...
gene_num,F,T,head_length,link_function);
populations = [populations, population];
end
% For efficiency, preallocate an array of future objects before.
futures(1 : pn) = parallel.FevalFuture;
stop = false; % for while(1) to stop
% tips:
% because you can't forbid "fetch" the data in every while iterations,
% so afterEach or afterAll fcn won't help improving efficiency here, merely
% adding more complicate parameter processing in your fcn. but, we can do
% sth before fetching all futures by using fetchNext !
while(1)
tic
ticBytes(gcp);
% 1. parallel call evaluating functions
for idx = 1 : pn
% --parfeval
% F = parfeval(fcn,numout,X1,...,Xm) schedules the function fcn to be run.
% MATLAB evaluates the function fcn asynchronously as
% [Y1,...,Yn] = fcn(X1,...,Xm), with m inputs and n outputs.
% parfeval does not block MATLAB, so you can continue working while
% computations take place.
futures(idx) = parfeval(@evaluating, 1, populations(idx), environment, selection_range);
end
% 2. check the best fitness and decide whether to finish the cycle
for idx = 1 : pn
% --fetchNext
% retrieve next unread outputs from Future array, it's a BLOCK FUN !
% every time it will block until get one.
[j, populations(j)] = fetchNext(futures);
% check the convergency or age limite, finished == true means
% success or failed
isfinished = checking(populations(j), j, selection_range, tol);
% this is for ploting fitness curve
age = populations(j).age;
best_fitness_array(j, age) = populations(j).best_fitness;
% once it has true, stop.
if isfinished == true
stop = true;
end
end
% after all futures have been fetched then stop!
if stop == true
for i = 1 : pn
plot(best_fitness_array(i, 1:age), '--*');
hold on;
end
break; % break the circle
end
% 4. if not satisfy finishing conditions, migrating populations
% ...
% 5. excute population's evolution paralleling.
for idx = 1 : pn
populations(idx).reproduction();
end
tocBytes(gcp);
toc
end
%**************************
% help functions
%**************************
function population = evaluating(population, environment, selection_range)
sample_num = size(environment,1);
out = zeros(sample_num, 1);
% express all the chromosome one by one
fitness_array = zeros(1, population.individual_num);
for i = 1 : population.individual_num
for j = 1 : sample_num
out(j) = population.getExpression(i, 1, environment(j, 1:end-1));
end
% all element must be normal.
if GeneBasicClass.anyNanOrInf(out) == false
fitness = population.psr(selection_range, out, environment(:,end));
else
fitness = 0;
end
% eliminate nagative value
if fitness >= 0
fitness_array(i) = fitness;
else
fitness_array(i) = 0;
end
end
% set back the fitness and reflash internal parameters
population.setFitness(fitness_array);
end
function isfinished = checking(population, idx, selection_range, tol)
if population.isRunning() == true
isfinished = false;
end
if (selection_range - population.best_fitness) <= tol
isfinished = true;
fprintf([' \n--------population %d success!--------\n' ...
'population: %d\n' ...
'chrom code: %s\n' ...
'chrom expression: %s \n'], ...
idx, ...
population.age, ...
population.best_code, ...
population.best_expression);
elseif population.isRunning() == false
isfinished = true;
fprintf(2, ['\npopulation %d solving failed: upto limitation...\n' ... % 2=red
'best fitness: %d\n' ...
'best chromosome: %s\n' ...
'best expression: %s\n'], ...
idx, ...
population.best_fitness, ...
population.best_code, ...
population.best_expression);
end
end