Structuring Code for Global Parameters in Octave

Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
7 replies · 4K views
Dr.D
Messages
2,411
Reaction score
723
TL;DR
How do I define system constants once at the beginning of a script, and then have them available inside the function that calculates the derivatives for an ODE solution and also after solving the ODE?
I'm trying to do a fairly complete system analysis script in Octave that involves these steps:
1) Assign values to all fixed system parameters
2) Make various preliminary calculations based on system parameters
3) Solve a system of differential equations
4) Make various post-ODE solution calculations
5) Make various plots
I'd like to have all the results of the first two steps available for use in the last three steps. It would seem like a global declaration would be the way to do this, but the documentation on that is unclear.

How do I structure the code to accomplish these objectives? I really do not want to have to bury all the system parameters and related constants inside the function that defines the derivative. Surely there is a better way?
 
Last edited:
Physics news on Phys.org
Here's what Octave docs have to say on it:

https://octave.org/doc/v4.2.1/Global-Variables.html
There are dangers to using global variables so programmers usually avoid them. A better strategy is to follow a functional programming style where each function has inputs and outputs but no external variables like globals. It makes programs harder to write but easier to debug.

The two common issues are:
  • defining a local with the same name and essentially hiding the global from consideration.
  • some routine changes the global variable and that effect now ripples through your processing stream causing unanticipated consequences later on.
EDIT added "no external..."
 
Last edited:
jedishrfu said:
A better strategy is to follow a functional programming style where each function has inputs and outputs but external variables like globals.
@jedishrfu I don't understand this sentence. Would you explain, please? It seems like the second clause is missing something -- "but external variables like globals ... what?"

For those old enough to remember Fortran, what I'd really like is a COMMON block. This certainly always raised the danger of the second point jedishfru raised above, but is was extremely useful. I still don't see any neat way around it without have to repeat the definition of all my constants in each subroutine and then evaluate them everytime the routine is called.

PS: I did read the Octave documentation first, and that's what seems particularly unclear and I might say, pointless. I fail to see why anyone would have any use for that.
 
One aspect of Functional programming means writing functions which have no side effects ie given the same inputs you will get the same outputs. A consequence of that style of programming is no global variables are used to provide information to the function or extract info from the function once run.

It’s harder to write an application using that restriction but it results in better code that is easier to test and debug in the long run.
 
@jedishrfu : OK, but this bring me back to my original question. How do you get all of the problem constants into a derivative function for ODE solution without embedding them? If they are embedded in the function, they will have to be evaluated over and over again, many times in a numerical solution of an ODE. That is horribly inefficient! If they have to be both embedded and also stated outside the routine for use outside, then if the problem parameters change , it it necessary to change them everywhere they are embedded, not just once. Is that really the best that can be done in Octave?
 
Variables in Octave that are declared global have to be re-declared global inside functions in order to be passed properly. So if you have a main program that looks like:
Code:
## Calculate E=mc^2 from m.
global c;
c = 3e+8;
mass = input("Enter mass");
function E = energy (m)
  E = m*c^2;
endfunction
printf("Energy = %g", energy(mass));
it will flag an error because the global variable isn't declared inside the function. Instead, this works:
Code:
## Calculate E=mc^2 from m.
global c;
c = 3e+8;
mass = input("Enter mass");
function E = energy (m)
  global c;
  E = m*c^2;
endfunction
printf("Energy = %g", energy(mass));
Notice you only have to redeclare that c is a global variable (line 6); you don't have to declare the value of c. Octave will take that from the main program.
 
Thank you, @TeethWhitener What you describe is just about what I have come to on my own. In many respects, this is much like the Fortran COMMON block usage, which is what I had in mind. Thanks for the help.