필터 지우기
필터 지우기

How to use global variable in nested function

조회 수: 11 (최근 30일)
Atinesh Singh
Atinesh Singh 2017년 2월 15일
편집: Jan 2017년 2월 16일
I need to use global variable in nested functions.
On running the below code, I'm getting an error
The GLOBAL or PERSISTENT declaration of "initial_flag" appears in a nested function, but should be in the outermost function where it is used.
Here is the logic of the below code:
There is a global variable named initial_flag which is defined in "demoEA.m" and "benchmark_func.m" and also in the nested function within "benchmark_func.m". The purpose of this variable is to avoid running code
if (func_num == 1) fhd = @f1;
elseif (func_num == 2) fhd = @f2;
end
multiple times in "benchmark_func.m" and avoid loading "datafiles/f01.mat" multiple times which contains the definition of (xopt, lb, ub) used in the nested functions.
Here is the Code.
"demoEA.m"
clear; clc; close all;
% Search Range
lb = -100;
ub = 100;
% Dimension
D = 1000;
NP = 100; % population size
runs = 2; % number of independent runs for each function, should be set to 25
Max_FEs = 1000; % maximal number of FEs, should be set to 3e+06
global initial_flag; % the global flag used in test suite
format short e;
for func_num = 1:2
for run = 1:runs
initial_flag = 0; % should set the flag to 0 for each run, each function
pop = lb + (ub-lb)*rand(D, NP); % Random Population
val = benchmark_func(pop, func_num); % fitness evaluation
FEs = NP;
while (FEs <= Max_FEs-NP)
% random search, you should add your own method
newpop = lb + (ub-lb)*rand(D, NP);
newval = benchmark_func(newpop, func_num); %returns a vector 1*100
FEs = FEs + NP;
index = (newval < val);
val(index) = newval(index);
pop(:, index) = newpop(:, index);
% demo output, you should save your results to some files
fprintf(1, 'func_num = %d, run = %d, FEs = %d\n', func_num, run, FEs);
fprintf(1, 'min(val) = %e\n\n', min(val));
end
end
end
"benchmark_func.m"
function fit = benchmark_func(x, func_num)
global initial_flag
persistent fhd
if (initial_flag == 0)
if (func_num == 1) fhd = @f1;
elseif (func_num == 2) fhd = @f2;
end
end
fit = fhd(x);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%BASE FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%------------------------------------------------------------------------------
% Elliptic Function
%------------------------------------------------------------------------------
function fit = elliptic(x)
[D ps] = size(x);
condition = 1e+6;
coefficients = condition .^ linspace(0, 1, D);
fit = coefficients * T_irreg(x).^2;
end
%------------------------------------------------------------------------------
% Rosenbrock's Function
%------------------------------------------------------------------------------
function fit = rosenbrock(x)
[D ps] = size(x);
fit = sum(100.*(x(1:D-1,:).^2-x(2:D, :)).^2+(x(1:D-1, :)-1).^2);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%BENCHMARK FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%------------------------------------------------------------------------------
% f1: Shifted Elliptic Function
% D = 1000
%------------------------------------------------------------------------------
function fit = f1(x)
global initial_flag
persistent xopt lb ub
[D ps] = size(x);
if (initial_flag == 0)
load 'datafiles/f01.mat';
initial_flag = 1;
end
idx = checkBounds(x, lb, ub);
x = x - repmat(xopt, 1, ps);
fit = elliptic(x);
fit(idx) = NaN;
end
%------------------------------------------------------------------------------
% f2: Shifted Rosenbrock’s Function
% D = 1000
%------------------------------------------------------------------------------
function fit = f2(x)
global initial_flag
persistent xopt lb ub
[D ps] = size(x);
if (initial_flag == 0)
load 'datafiles/f02.mat';
initial_flag = 1;
end
idx = checkBounds(x, lb, ub);
x = x - repmat(xopt, 1, ps);
fit = rosenbrock(x);
fit(idx) = NaN;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%HELPER FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%------------------------------------------------------------------------------
% This transformation is used to create smooth local irregularities.
%------------------------------------------------------------------------------
function g = T_irreg(f)
a = 0.1;
g = f;
idx = (f > 0);
g(idx) = log(f(idx))/a;
g(idx) = exp(g(idx) + 0.49*(sin(g(idx)) + sin(0.79*g(idx)))).^a;
idx = (f < 0);
g(idx) = log(-f(idx))/a;
g(idx) = -exp(g(idx) + 0.49*(sin(0.55*g(idx)) + sin(0.31*g(idx)))).^a;
end
%------------------------------------------------------------------------------
% This function tests a given decision vector against the boundaries of a function.
%------------------------------------------------------------------------------
function indices = checkBounds(x, lb, ub)
indices = find(sum(x > ub | x < lb) > 0);
end
end
Please help me to solve this issue. For complete code please refer attachments.
  댓글 수: 3
Atinesh Singh
Atinesh Singh 2017년 2월 16일
편집: Atinesh Singh 2017년 2월 16일
Actually, I didn't coded it by myself. I downloaded it from here
Rik
Rik 2017년 2월 16일
Still, the answer stands that variables are by definition shared between the main function and the nested function. Remove the global and you should be fine. You could also just load the data in the main function, because now you will have to reload the data. the .mat is loaded in a nested function, so after the call, all variables that were not shared by the main function are removed.
Passing of variables is a way better solution in almost any imaginable case. You can also take a look at varargin, varargout, nargin and nargout.

댓글을 달려면 로그인하십시오.

채택된 답변

Jan
Jan 2017년 2월 16일
편집: Jan 2017년 2월 16일
As mentioned in the comments already:
Using globals leads to the same problems every time: The distribution is buggy and it is hard to control, which part of the code is responsible for the last change of the value. Therefore globals impede the programming and the debugging. This does not matter Matlab only, but all programming languages. Therefore it is a good programming practice, to avoid globals, or in your case to modify the code to work without them.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Functions에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by