Global CONSTANTS. Any problem using them? - matlab

I've been programming for over 6 years now and i've always avoided using global variables because there is always another way around the problems.
Today, i work on a (big) project, we want to use a dictionnary of mathematical CONSTANTS what will never be modified anywhere. The only problem i seem to find with globals on internet is the fact that if someone overwrites one it could bug out the whole project. But as mine are constants this problem doesnt apply.
(as a second security to avoid people creating a variable with the same name as one of the constants i will probably pack them all in a single global struct)
Does anyone know of problems that still happend using global constants?
Thanks for your answers! :)

In MATLAB, your best bet for mathematical constants is to define a class with properties that have the Constant attribute. This is described in the doc here, and here's the leading example from that page:
classdef NamedConst
properties (Constant)
R = pi/180
D = 1/NamedConst.R
AccCode = '0145968740001110202NPQ'
RN = rand(5)
end
end
This way, the values cannot be overridden. (Note that there's something a little perhaps unexpected in this example - the value of the property RN changes each time the class is loaded! I personally wouldn't write code like that...)

The old-fashioned standard way to create a constant in MATLAB is to write a function. For example pi is a function. It could be written as:
function value = pi
value = 3.14159;
end
Of course we can overwrite the value of pi in MATLAB, but it is always a local change, it is not possible to affect another workspace.

Related

Modelica - Is it possible to set name of a submodel as the value of another variable?

I’m quite noob in Modelica language and I’d appreciate any help about this simple issue. I’d like to know if it’s possible to write variables name (that depends on a submodel) as a function of other variable in order to shorten the general code. Here there is an example about what I’d like to do.
I’m considering a top-level model that includes three identical submodels (OpenTank) of the Standard Modelica Library (tank1,tank2 and tank3). I’d like to know if it’s possible to call the variable (“level”) inside the submodels from the top-level model using a loop like this way (example code is attached) or something similar instead of repeating the code three times (I’m really interested in setting this operation in the top-level model)
What would you advise me to do? Thanks in advance!
model threeTanks
Modelica.Fluid.Vessels.OpenTank tank1;
Modelica.Fluid.Vessels.OpenTank tank2;
Modelica.Fluid.Vessels.OpenTank tank3;
equation
for i in 1:3 loop
tank(i).level= /* … */;
end for;
end threeTanks;
You would need a component iterator, which is proposed in Modelica Change Proposal MCP-0021 Component Iterators. But it is not available yet and nothing has changed since 2016 if I read it correct, so don't expect to get that soon.
With the current Modelica language version (specified in Modelica Language Specification 3.5), you must use literal names when you refer to components.
(In Modelica, there is nothing like eval which you might know from other languages.)
So either go for Rene Just Nielsens solution and use vectorized tanks.
This works, but in the graphical view you will have only one tank. The parameter window will then accept vectors and the tank connectors will be vectorized as well.
If you don't want that, you can also instantiate your tanks as you did and manually specify the component names over which you want to iterate:
for item in {tank1, tank2, tank3} loop
item.level= /* … */;
end for;
The question is also what you want to achieve. The tank already has equations to compute the level, so it's unlikely that you want to set it.
Maybe you want to gather all levels at top in one variable. You could do that by adding this line:
Modelica.Units.SI.Length levels[3] = {item.level for item in {tank1, tank2, tank3}};
Similar to the answer to the post (Modelica - Is it possible to set name of a variable as the value of another variable?) you can declare an array of components like this:
model threeTanks
Modelica.Fluid.Vessels.OpenTank[3] tank;
equation
for i in 1:3 loop
tank[i].level= /* … */;
end for;
end threeTanks;

Is it possible to create constants in Progress-4GL?

Good afternoon,
Is it possible to create constants in Progress-4GL?
The same question has been asked here, but there the question is based on object oriented programming (which I'm not doing).
There is no constant keyword in ABL.
The simplest way to create constant values is using static properties. These are available in any code, even procedural.
class ConstantValues:
define static public PI as decimal initial 3.14159 get.
end class.
You could add a private setter and do the assignment in the static constructor, instead of the initial value.
If you can't or don't want to use this approach, you can use preprocessors. If you need these values shared then define the preprocessors in includes and use those in your programs (even classes).
But that's - to me - more work than it needs to be if you're creating new constant values.
Even if not a constant and also possibly quite old school you can define precompiler statements that can work as a constant.
There's a possibility for global (&GLOBAL-DEFINE) and not global (&SCOPED-DEFINE)
Its also possible to undefine, check defined and other basic things.
These are define on compilation time so they cannot be changed dynamically when the program is running.
&SCOPED-DEFINE const1 1
&GLOBAL-DEFINE const2 hello
DISPLAY {&const1} "{&const2}".

Exploit Matlab copy-on-write by ensuring function arguments are read-only?

Background
I'm planning to create a large number of Matlab table objects once, so that I can quickly refer to their contents repeatedly. My understanding is that each table variable/column is treated in copy-on-write manner. That is, if a table column is not modified by a function, then a new copy is not created.
From what I recall of C++ as of 1.5 decades ago, I could ensure that the code for a function does not modify its argument's data by using constant-correctness formalism.
The specific question
I am not using C++ in these days, but I would like to achieve a similar effect of ensuring that the code for my Matlab function doesn't change the data for selected arguments, either inadvertently or otherwise. Does anyone know of a nonburensome way to do this, or just as importantly, whether this is an unrealistic expectation?
I am using R2015b.
P.S. I've web searched and came across various relevant articles, e.g.:
http://www.mathworks.com/matlabcentral/answers/359410-is-it-possible-to-avoid-copy-on-write-behavior-in-functions-yet
http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data
(which I need clarification on to fully understand, but it isn't my priority just now)
However, I don't believe that I am prematurely optimizing. I know that I don't want to modify the tables. I just need a way to enforce that without having to go through contortions like creating a wrapper class.
I've posted this at:
* Stack Overflow
* Google groups
There is no way of making variables constants in MATLAB, except by creating a class with a constant (and static?) member variable. But even then you can do:
t = const_table_class.table;
t(1,1) = 0; % Created and modified a copy!
The reason that a function does not need to mark its inputs as const is because arguments are always passed by value. So a local modification does not modify data in the caller’s workspace. const is something that just doesn’t exist in the MATLAB language.
On the other hand, you can be certain that your data will not be modified by any of the functions you call. Thus, as long as the function that owns the tables does not modify them, they will remain constant. Any function you pass these tables to, if they attempt to modify them, they will create a local copy to be modified. This is only locally a problem. The memory used up by this copy will be freed upon function exit. It will be a bug in the function, but not affect code outside this function.
You can define a handle class that contains a table as it's preperty. Define a property set listener that triggers and generates error/warning when the value of the property changes.
classdef WarningTable < handle
properties (SetObservable)
t
end
methods
function obj = WarningTable(varargin)
obj.t = table(varargin);
addlistener(obj,'t','PreSet',...
#(a,b)warning('table changed!'));
end
end
end
This should generate warning:
mytable = WarningTable;
mytable.t(1,1) = 0;

Octave: How should I go about having global constants handy for any program?

I would like to have a list of constants readily available to use in any script or function I write. For example, I have been defining constants like hbar (Planck's constant) at the start of any script that will be using it.
Instead of that, should I:
make a list of constants in a script and load that script every time
I want to use it,
or save constants in a workspace and load that,
or is it possible for me to have global variables that will be there even when I close and reopen Octave,
or something else?
If you use GNU Octave I would suggest using the miscellaneous package and the function physical_constant which already has 335 constants. In your case:
[val, uncertainty, unit] = physical_constant ("Planck constant over 2 pi")
val = 1.0546e-34
uncertainty = 4.7000e-42
unit = J s
If you want don't want this, then use functions, not global vars.
As you indicated, there are a few ways to solve this problem. To address your third option, which seems to be closest to the spirit of what you want, you've got at least two ways of handling this.
1.) If the variables need to be mutable. Create a function or script that initializes the variables to what you want them to be. I'm going to reference the MATLAB documentation but it should basically be the same.
function initglobals()
global the_answer
the_answer = 42;
end
Then any time you want to use these globals in a script, you first indicate to Octave that you'll be using the variable as a global:
...
global the_answer
disp(the_answer) %prints 42
...
For this to be more useful, I'd recommend generating a startup script and putting in your .octaverc docs. This startup script can call this function to initialize your globals.
2.) Your other choice, if the globals ought to be immutable (for example, a physics constant) is to define a function that returns the value you want.
function [out] = the_answer()
out = 42;
end
Then you can simply just use the_answer to access your constant.
In both cases you'll want to add these functions to your path. Create your collections of functions and put them somewhere, then add that location to your path. docs

Matlab: How to return output from a function in a set()?

I am now using Matlab GUI and have problem during accessing return values from a function which is set by set().
Situation:
I set the windowMotionFcn as below:
set(gcf,'WindowButtonMotionFcn',#test);
Function 'test' can return 2 variables (named as var1 and var2).But I dont know how to store them...
I have searched in the Internet and could not find any way.
How should I write?
Thank you for your help and kind attention.
I think that what you want to do is to return a value from the callback function. And regarding returning a value from a callback I am not sure that is possible. I found an old article from matlab newsreader. I think your problem could be similar.
However, if you have a matlab GUIDE GUI, there is a way to return a value from a gui. It is described in a matlab tutorial in matlab central: advanced-getting-an-output-from-a-guide-gui. What you must do is to modify your CloseRequestFcn and your OutputFcn.
Another way, which should work is using global variables. A global varable exist in the global workspace. That means that it can be seen and accessed by every function in matlab. Global variables are in most cases not recommended, but if no other solution exists they may be necessary. Just make sure to document them, so that the next person to take over your code knows that they are there. Also make sure to select a good name for the globals, like gblMyVar so there can be no confusion that the variable is global.