Advantages and workarounds for using a main function for a project?

13 Ansichten (letzte 30 Tage)
This is a broader version of my question loading parameters from a text file. Someone commented that it sounds like the XY problem and so I am trying to write a better question here with more background.
I have a project which has 1 main script. I'd like to eventually distribute this project so I want to be careful about collisions with my function names, hence I put them in a 'private' folder. Now my main script doesn't have access so I wrapped a function around the script.
This function has many many parameters (used to be just written at the top of the script). But to be organized I'd like to instead pass in a file name to the main function which will read a file and load the parameters. I've solved this problem by loading them from a .mat file, but this seems like such a waste. For example
parameters.m
a = ones(10000,10000)
is 1 line of text while its a large matrix in the .mat file. In my previous question someone suggested that I try
run('parameters.m')
inside the main function, but this leads to other namespace problems. For instance one of my variables is named 'gamma' and when I try to use gamma later (loaded from running paramters.m) it thinks I am trying to use the MATLAB function gamma.
Do I need better project structure. Do I keep the project structure but need to settle for loading from a .mat file? Is there a workaround?

Akzeptierte Antwort

Stephen23
Stephen23 am 2 Sep. 2016
Bearbeitet: Stephen23 am 2 Sep. 2016
In general code and data should be thought of as two different things. While for small tasks, or where the values really are constant (e.g. conversion factors) it can be convenient to include a few parameters and numeric values in the code, these are the exception rather then the rule. For a larger project, a mat file is perfect: it is designed for efficiently storing data, after all, including very good compression...
Lets consider your example:
a = ones(10000,10000)
how to store this? That depends on what values it can have, and how you specify that data. If this matrix has different values for every test case, then a .mat file is perfect. If these values are always ones, then why not simply store the size in the mat file:
size_a = [1e4,1e4]
and then your code can generate the matrix when it runs. If the matrix is always the same size, but the values differ then just store the value:
val_a = 1;
etc. There is no universal best solution because what data you start with, what assumptions you apply to your data, and other factors will tell you what information needs to be stored.
Just try not to mix up the code and the data!

Weitere Antworten (2)

Kelly Kearney
Kelly Kearney am 2 Sep. 2016
My preference is to keep large sets of parameters like this in a structure, which can be returned from a function. For example:
function S = parameters()
S.a = ones(10000,10000);
S.gamma = 0;
Then, in your main program, rather than
run('parameters.m')
you can call
S = parameters();
You'll have to go through your main code and replace all references to a with S.a, gamma with S.gamma, etc. It may be a little tedious if your code is already quite complex, but the one-time tedium will pay off in the long run, since it allows you to ignore any potential variable name conflicts, and also to keep a clear record of which parameters came from that particular parameter setup function. You can even keep multiple sets:
function S = parameters(name)
switch name
case 'one'
S.a = ones(10000);
S.gamma = 0;
case 'two'
S.a = ones(1000);
S.gamma = 1;
otherwise
error('Unrecognized parameter set name');
end
  2 Kommentare
Michael Vaiana
Michael Vaiana am 2 Sep. 2016
I like this idea alot but the problem is that I wanted to be able to run the main function with many (~hundred) different combinations of different parameters. Each one will be store in a text or .mat file which can be called by name and run. But I am going with the struct concept by doing S = load('parameters') where parameters is a .mat file. This avoids the problem of having variables with the same name as the function and also allows me to load parameters from files. I might use this idea in the future though!
Stephen23
Stephen23 am 2 Sep. 2016
Loading into a structure
S = load('parameters')
is an excellent practice, and is highly recommended over loading the variables directly into the workspace.

Melden Sie sich an, um zu kommentieren.


Thorsten
Thorsten am 2 Sep. 2016
Bearbeitet: Thorsten am 2 Sep. 2016
You're right: If use use build-in commands or Matlab function as your variable name, such as 'gamma', something strange happens: when you call the script from the workspace, you can use gamma as a variable, as expected. However, when you run the script from a function,
which gamma
tells you that gamma is now a variable, but
gamma
does not display the variable, but results in
Error using gamma
Not enough input arguments.
So I would change your variables such that they are not similar to predefined function in Matlab. This is anyway the recommended practice.
A hack that works is to define gamma with an arbitrary value before running the script:
gamma = 0;
run('parameters.m')
  2 Kommentare
Michael Vaiana
Michael Vaiana am 2 Sep. 2016
Yeah, it is strange behavior, I'm curious, like you asked, if its a bug or a feature. I'll rename the variable if it is preferred practice, thanks for the tip
per isakson
per isakson am 2 Sep. 2016
Bearbeitet: per isakson am 2 Sep. 2016
The preferred practice is NOT to use function names as variable names, i.e. not to shadow (make unreachable) functions.
A problem with Matlab is that you cannot distinguish a function from a variable in a line like.
a = my_name( 4, 5 );
"if its a bug or a feature" &nbsp I think of it as an unfortunate feature, which dates thirty years or more back in time.

Melden Sie sich an, um zu kommentieren.

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by