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

14 次查看(过去 30 天)
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?

采纳的回答

Stephen23
Stephen23 2016-9-2
编辑:Stephen23 2016-9-2
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!

更多回答(2 个)

Kelly Kearney
Kelly Kearney 2016-9-2
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 个评论
Michael Vaiana
Michael Vaiana 2016-9-2
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 2016-9-2
Loading into a structure
S = load('parameters')
is an excellent practice, and is highly recommended over loading the variables directly into the workspace.

请先登录,再进行评论。


Thorsten
Thorsten 2016-9-2
编辑:Thorsten 2016-9-2
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 个评论
Michael Vaiana
Michael Vaiana 2016-9-2
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 2016-9-2
编辑:per isakson 2016-9-2
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.

请先登录,再进行评论。

产品

Community Treasure Hunt

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

Start Hunting!

Translated by