I have a numerical scheme which I would like to optimize as well as make more readable by organizing it as follows. I have two numerical schemes, "numeric_method_1" and "numeric_method_2" which both calculate the next step of an interation and run many, many times. They are called by the function "do_single_step" which runs fewer times and in turn is called by "run_scheme" which runs the entire scheme and is only called once. I would like to have an initializer function/wrapper called "initialize_and_run" which, given a parameter, would declare a function "chosen_numeric_method" that refers to one of "numeric_method_1" or "numeric_method_2" and is used in all functions and subscopes that follow.
In code, what I would like to have is the following:
numeric_method_1 = function(x)
return x*x #arbitrary
end
numeric_method_2 = function(x)
return x*x*x #arbitrary
end
do_single_step = function(x)
return chosen_numeric_method(x)
end
run_scheme = function(x)
return do_single_step(x)
end
initialize_and_run = function(x,which)
if which
chosen_numeric_method = numeric_method_1
else
chosen_numeric_method = numeric_method_2
end
##
return run_scheme(x)
end
As you can see, the "initialize_and_run" function takes a boolean parameter "which", that lets you choose which numeric method will be used deeper within the scheme. However, this does not run as one obtains the following error:
UndefVarError: chosen_numeric_method not defined
I understand, from looking into this periodically, that it is to do with the fact that the function "do_single_step" has the outermost scope, and so it can only see functions which also have the outermost scope.
I also understand that there were other options. For one, I could have rewritten the above to pass the "chosen_numeric_method" down the scope to where I need it:
numeric_method_1 = function(x)
return x*x
end
numeric_method_2 = function(x)
return x*x*x
end
do_single_step = function(x,chosen_numeric_method)
return chosen_numeric_method(x)
end
run_scheme = function(x,chosen_numeric_method)
return do_single_step(x,chosen_numeric_method)
end
initialize_and_run = function(x,which)
if which
chosen_numeric_method = numeric_method_1
else
chosen_numeric_method = numeric_method_2
end
##
return run_scheme(x,chosen_numeric_method)
end
This runs, however, this will become problematic as I have more and more functions to pass down and as they need to be passed deeper and deeper. I could also do the if statement inside the innermost scope where I need it:
numeric_method_1 = function(x)
return x*x
end
numeric_method_2 = function(x)
return x*x*x
end
do_single_step = function(x,which)
if which
return numeric_method_1(x)
else
return numeric_method_2(x)
end
end
run_scheme = function(x,which)
return do_single_step(x,which)
end
initialize_and_run = function(x,which)
return run_scheme(x,which)
end
This also runs, however, the innermost function "do_single_step" is run many, many times and so I worry about this constant checking as it may make things slower. In addition, this is once again just not very pleasing style as I knew already at the initializer step which numeric function will be used for the entire run period.
Is there really no way to achieve my desired configuration (the first code block) and have it be performant by somehow telling the compiler in the initializer step Hey, I want the function "chosen_numeric_method" to be avaliable in all subscopes of this one ?