Variable declaration from the value of a different variable - theory

This isn't really specific to one language, it's just something I'm very confused about. I was wondering if you can declare a variable using the value from a different variable.
ex:
int a = 2;
int ba = 3;
//except instead of ba its b with the value of a so it would be b2=3;
I feel like I've done this before, but I can't for the life of me remember how it was done, or if I had ever done it in the first place.
I apologize if this isn't in the correct category, I can't make my own, and I don't really know what would be a better place for it.

In python, exec() accepts and executes strings that contain valid Python expressions. You should try this
>>> a = 2
>>> exec('b' + str(a) + ' = ' + str(3))
>>> b2
The output will be 3
3

Related

Understanding a key concept in Minizinc - declaring set of variable, then using it to declare an array of values

I'm working through the Introduction to Minizink course on Coursera and have come to an example which I really would like to have a better intuitive understanding of.
The model in this vieo https://www.coursera.org/learn/basic-modeling/lecture/PZO1B/1-1-7-global-constraints declares the following parameters
set of int: DIGIT = 1..9;
array[DIGIT] of int: rods = [1,2,3,4,5,2,3,4,5];
with these constraints after
constraint rods[M1] + rods[M2] + rods[M3] +
rods[M4] + rods[M5] = 12;
constraint 2303 + M1 * 10 + 980 + M2 * 1000 + M3
= 301 + M4 * 1000 + M5 * 10;
I'm struggling to visualise what's going on here. To check, a set called DIGIT is declared consisting of numbers 1 to 9, which could also be viewed as {1,...,9}, then it's 'also' being 'instantiated/declared as/associated with' an array that looks like as it is written above inside the [], matched up by the corresponding index. In contrast, declaring var 1..9: DIGIT would create a range of values that DIGIT could take, which isn't an array or set.
In fact, as I write this, I actually remembered how I understood earlier examples in the course, but I'll finish this pose to perhaps get further perspectives and clarity on it, or see if I'm still missing something.
Say for example you have an enumerated set FRUIT = {apple,orange,banana} with which you could associate an array of integers using for example array[FRUIT] of int: whatever = [4,9834,-42]. Then, use either the enumareted possibilities by declaring var FRUIT: Opt1;, so Opt1 can take the value of either apple, orange or banana, depending on the type of constraint used, while using whatever[Opt1] inside a constraint would take on the value of either 4, 9834 or -42, depending on the fruit currently being 'tested' as Opt1?
So as is often the case, explaining something to someone actually helps you to understand it better yourself, so I think I get it, but I wonder if there is anything off or missing about how I interpret the way this aspect of Minizinc works?

R apply-like function for updating 2 arrays simultaneously?

I am new to R, and looking for an apply type function to work with 2 arrays at once (simultaneous update).
For example, let's say I have some variables X and P:
X = array(rep(0, 10), dim=c(10, 1))
P = array(rep(1, 10), dim=c(10, 1))
which are governed by the system of equations:
X[k,] = 2*X[k-1]
P[k,] = 3*X[k] + X[k-1] + 3
Obviously, this can easily be accomplished with a for-loop, however, I have read/confirmed myself that for loops work horrendously for large inputs, and I wanted to start getting into good R coding practice, so I am wondering, what is the best way to do this in an apply-type logic? I am looking for something like,
sapply(2:dim(X)[1], function(k) {
X[k,] = 2*X[k-1]
P[k,] = 3*X[k] + X[k-1] + 3
})
But this obviously won't work, as it doesn't actually update X and P internally. Any tips/tricks for how to make my for-loops faster, and get in better R coding practice? Thanks in advance!
You could do the following below. The <<- operator will set X and P outside of the function
sapply(2:dim(X)[1], function(k) {
X[k,] <<- 2*X[k-1]
P[k,] <<- 3*X[k] + X[k-1] + 3
})
As pointed out by thelatemail in the comments, using <<- can be problematic because of the side effects it can have. See the links below, the one comparing for loops (and other loops) to the apply family of functions.
Here is a link to documentation on assignment operators in R.
Here is a StackOverflow link on for loop vs. apply functions that talks about performance.

Fortran select a vector by indicating its name

In a program coded in F90, I have a set of 11 vectors, each of a size (7), with names going from "S1" to "S11".
I need to be able to read a number of elements from one vector, by giving the name of this latter.
Although this problem seems an elementary one, with my beginner level, I am unable to find a way to code it...
any help ?
When a Fortran program executes it doesn't really have the information available to identify a variable based on the value of a string containing the name of a variable. You could write a sequence of if statements such as
if (mystr=='S1') x = s1
if (mystr=='S2') x = s2
...
You could pretty this up a bit with a select case construction
select case (mystr)
case ('S1')
x = s1
case ('S2')
x = s2
...
but that may not appeal much more.
A better approach by far would be to declare your vectors as elements of a rank-2 array:
real, dimension(11,7) :: s
and you can then do all sorts of computations, at run-time, to select the vector you want
myrow = an_expression_returning_an_integer_between_1_and_11_inclusive
x = s(myrow,:)

Dynamically creating and naming an array

Consider the following code snippet
for i = 1:100
Yi= x(i:i + 3); % i in Yi is not an index but subscript,
% x is some array having sufficient values
i = i + 3
end
Basically I want that each time the for loop runs the subscript changes from 1 to 2, 3, ..., 100. SO in effect after 100 iterations I will be having 100 arrays, starting with Y1 to Y100.
What could be the simplest way to implement this in MATLAB?
UPDATE
This is to be run 15 times
Y1 = 64;
fft_x = 2 * abs(Y1(5));
For simplicity I have taken constant inputs.
Now I am trying to use cell based on Marc's answer:
Y1 = cell(15,1);
fft_x = cell(15,1);
for i = 1:15
Y1{i,1} = 64;
fft_x{i,1} = 2 * abs(Y1(5));
end
I think I need to do some changes in abs(). Please suggest.
It is impossible to make variably-named variables in matlab. The common solution is to use a cell array for Y:
Y=cell(100,1);
for i =1:100
Y{i,1}= x(i:i+3);
i=i+3;
end
Note that the line i=i+3 inside the for-loop has no effect. You can just remove it.
Y=cell(100,1);
for i =1:100
Y{i,1}= x(i:i+3);
end
It is possible to make variably-named variables in matlab. If you really want this do something like this:
for i = 1:4:100
eval(['Y', num2str((i+3)/4), '=x(i:i+3);']);
end
How you organize your indexing depends on what you plan to do with x of course...
Yes, you can dynamically name variables. However, it's almost never a good idea and there are much better/safer/faster alternatives, e.g. cell arrays as demonstrated by #Marc Claesen.
Look at the assignin function (and the related eval). You could do what asked for with:
for i = 1:100
assignin('caller',['Y' int2str(i)],rand(1,i))
end
Another related function is genvarname. Don't use these unless you really need them.

MATLAB Cell array to individual variables

I currently have a function which I am batch running. It outputs its results to a cell array. I would like to export each of the outputs from the cell array to their own variable.
As such I have a variable id which records the ID of each layer. This process is possible manually as follows:
>> output =
[300x300x2 double] [300x300x2 double] [300x300x2 double]
>> [a1,a2,a3]=deal(output{:});
Where the number after a represents the ID. Is it possible to automate this command, so that the prefix (in this case: a) can be set by the user and the id filled in automatically? As in, I could have variables set as below, and use these in the deal command to name my new variables?
>> id =
1 2 3
>> prefix =
a
Any ideas?
Thanks.
You can construct your own custom expression as a string and then evaluate it with eval() (or evalin() if it's in a function and you want to return the output to your workspace).
function deal_output(output, id, prefix)
id = id(:);
vars = strcat(prefix, cellstr(num2str(id)))';
myexpr = ['[', sprintf('%s,', vars{1:end-1}), vars{end}, '] = deal(output{:})'];
evalin('caller', myexpr)
>> output = num2cell(1:3);
>> id = 1:3;
>> prefix = 'a';
>> deal_output(output, id, prefix)
a1 =
4
a2 =
5
a3 =
6
Also check out the join.m file on FileExchange for avoiding the ugly sprintf.
Perhaps something like:
function dealinto(prefix, cellarray)
% DEALINTO
% USAGE
% dealinto('a', {'one', 'two', 'three'})
% Causes these variables to be set in the base workspace:
% a1: 'one'
% a2: 'two'
% a3: 'three'
for i=1:numel(cellarray)
assignin('base', [prefix num2str(i)], cellarray{i});
end
If you replace 'base' with 'caller' in the above, the variables will be written into the calling function's workspace. I don't recommend doing this, though, for the same reason that I would not recommend calling LOAD with no output arguments inside a function: arbitrarily writing into a running function's workspace isn't very safe.
If you need something like this for use inside of functions but don't want it just writing variables willy nilly, you could do the same thing that LOAD does, which is to give you a structure whose fields are the variables you would otherwise produce.
Do you really have to output them as completely separate variables? It would be much more efficient to use dynamic field names in a structure as this would avoid the use of the eval() statement. See the MATLAB blogs for avoiding eval()
In this case
m = length(output);
[a(1:m).data] = deal(output{:});
This will return a structure array, the length calculation is added so it'll work for different sizes of the output cell array.
Each array can be accessed individually with an id number.
a(1).data
a(2).data
a(3).data
I can't seem to add a comment so I'm adding an answer in the form of a question ^_^
Is it not better to pre-create the list of names and check them in the caller workspace using genvarname ?
Names = cell(1,numel(data))
for idx = 1:numel(data)
Names{idx} = [Prefix, num2str(idx)]
end
Names = genvarname(Names,who)
dealinto(Names, data)
would prevent any invalid names from being create in the existing work space, then dealto would need to be modified as
function dealinto(Names, Values)
for idx = 1:length(Names)
assignin('caller', Names(idx), Values(idx))
end

Resources