Variable name to include value of another variable - variables

Lets say I have pre-defined 3 variables, x1, x2, and x3, each of which is a different co-ordinate on the screen. I have a whole chunk of code to decide whether another variable, a will equal 1, 2, or 3. Now, I want to include the value of a in a variable name, allowing me to 'dynamically' change between x1, x2, and x3.
E.g. a is set to 2. Now I want to move the mouse to xa, so if a=2, xa is x2, which is a predefined variable.
Its probably clear I am very new to Lua, I have tried googling the issue, but I'm not really sure what I am looking for, terminology wise and such.
Anyhow, is anyone able to help me out?

If you can change the code where x1, x2 and x3 are defined, a cleaner approach is to use arrays (i.e. array-like tables). This is the general approach when you need a sequence of variables indexed by a number.
Therefore, instead of x1, x2 and x3 you could define:
local x = {}
x[1] = 10 -- instead of x1
x[2] = 20 -- instead of x2
x[3] = 30 -- instead of x3
Now instead of using xa you simply use x[a].

If xa are global variables, you can use the table _G like this:
x1 = 42
x2 = 43
x3 = 44
local a = 2
print(_G['x' .. a])
Output:
43

Related

Dataframe grouping and distribution test/choose

I have a Dataframe with 16 variables (x1, x2,...x16). The variables from 1 to 15 are parameters chosed to perform an experiment. The 16th variable is the measured paramater which describe the result of the experiment.
The experiment is repeated a certein number of times, let´s say n, with constant value of the parameters (x1 to x15), i.e. with costant boundary conditions. In this way I have one serie of experiments. If the boundary conditions change, then I have a new serie of experiments where the experiment is repeated m-times.
First, I would like to find out all the series of experiments in the dataframe. I think this could be done with the R-function "group_by".
Then, I would like to find out the probability distribution of the 16th variable, i.e. the results of the experiment for each serie (i.e. group found with "group_by"). For this I was thinking to use the comand "distChoose". Otherweise I was thinking to fit the data with "fitdist" for two/three distributions and get the AIC. I Wold like to create a table where the AIC is saved for every tested distribution for each group.
I tried something like this:
grouping = group_by(Dataframe, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)
grouplist <- group_split(grouping)
AIC <- integer(763)
for (i in 1:763){
if (length(grouplist[[i]][["x16"]]) > 2){
normal = fitdist(grouplist[[i]][["x16"]], "norm")
AIC[i] = normal$aic
}
Is there a better way to do it, or maybe a command in R that already exist? I am new to R and I am trying to learn it.
Thank you all.

In an ILP problem, is it possible to constrain/penalize the number of decision variables used?

I'm trying to setup minimization problems with restrictions on the number of decision variables used.
Is it possible to do this within a linear programming framework? Or am I forced to use a more sophisticated optimization framework?
Suppose all x's are non-negative integers:
x1, x2, x3, x4, x5 >= 0
1) Constraint: Is it possible to set up the problem so that no more than 3 of the x's can be non-zero? e.g. if
x1 = 1, x2 = 2, x3 = 3 then x4 = 0 and x5 = 0
2) Penalty: Suppose there are 3 possible solutions to the problem:
a) x1 = 1, x2 = 2, x3 = 3, x4 = 0, x5 = 0
b) x1 = 2, x2 = 3, x3 = 0, x4 = 0, x5 = 0
c) x1 = 3, x2 = 0, x3 = 0, x4 = 0, x5 = 0
Due to simplicity, solution (c) is preferred over solution (b) which is preferred over solution (a) i.e. 'using' less decision variables is preferable.
In both questions I've simplified the problem down to 5 x's, but in reality I have 100's of x's to optimise over.
I can see how I might do this in a general optimisation framework using indicator/delta variables, but can't figure out how to do it in linear programming. Any help would be appreciated!
You can build your own indicators (and without restrictions to some very specific problem you also need to).
Assuming there is an upper-bound ub_i for all of your integer-variables x0, x1, ..., xn, introduce binary-variables u0, u1, ... un and post new constraints like:
u1 * ub_1 >= x1
u2 * ub_2 >= x2
...
(the ub_x constants are often called big-M constants; but we keep them as small as possible for better relaxations)
Then your cardinality-constraint is simply:
sum(u) <= 3
Of course you can also use those u-variables in whatever penalty-design you might want to use.

Mixed Integer Linear Programming for a Ranking Constraint

I am trying to write a mixed integer linear programming for a constraint related to the rank of a specific variable, as follows:
I have X1, X2, X3, X4 as decision variables.
There is a constraint asking to define i as a rank of X1 (For example, if X1 is the largest number amongst X1, X2, X3, X4, then i=1; if X1 is the second largest number then i=2, if X1 is the 3rd largest number then i=3, else i=4)
How could I write this constraint into a mixed integer linear programming?
Not so easy. Here is an attempt:
First introduce binary variables y(i) for i=2,3,4
Then we can write:
x(1) >= x(i) - (1-y(i))*M i=2,3,4
x(1) <= x(i) + y(i)*M i=2,3,4
rank = 4 - sum(i,y(i))
y(i) ∈ {0,1} i=2,3,4
Here M is a large enough constant (a good choice is the maximum range of the data). If your solver supports indicator constraints, you can simplify things a bit.
A small example illustrates it works:
---- 36 VARIABLE x.L
i1 6.302, i2 8.478, i3 3.077, i4 6.992
---- 36 VARIABLE y.L
i3 1.000
---- 36 VARIABLE rank.L = 3.000

Formatting a txt file of equations into the same format and then manipulating them for linear algebra calculations in Python

I'm looking for an universal way of transforming equations in Python 3.2. I've only recently begun playing around with it and stumbled upon some of my old MATLAB homework. I'm able to calculate this in MATLAB but pylab is still a bit of a mystery to me.
So, I have a text file of equations that I'm trying to convert into the the same form of A x = b and then solve some linear algebra problems associated with them in PYLAB.
The text file, "equations.txt",contains collections of linear equations in the following format:
-38 y1  +  35 y2  +  31 y3  = -3047
11 y1  + -13 y2  + -34 y3  = 784
34 y1  + -21 y2  +  19 y3  = 2949
etc.
The file contains the equations for four sets of equations, each set with a different number of variables. Each set of equations is of the exact form shown (3 examples above) with one empty line between each set.
I want to write a program to read all the sets of equations in the files, convert sets of equations into a matrix equation A x = b, and solve the set of equations for the vector x.
My approach has been very "MATLABy", which is a problem because I want to be able to write a program that will solve for all of the variables.
I've tried reading a single equation as a text line, stripped of the carriage return at the end, and splitting line at the = sign because as we know the 2nd element in the split is the right hand side of the equation, that goes into the vector b.
The first element in the split is the part you have to get the coefficients that go in the A matrix.  If you split this at white space ' ', you will get a list like
['-38', 'y1', '+', '35', 'y2', '+', '31', 'y3']
Note now that you can pull every 3rd element and get the coefficients that go into the matrix A.
Partial answers would be:
y1 = 90; c2 = 28; x4 = 41; z100 = 59
I'm trying to manipulate them to give me the sum of the entries of the solutions y1, ..., y3 for the first block of equations, the sum of the entries of the solutions c1, ..., c6 for the second block of equations, the sum of the entries of the solutions x1, ..., x13 for the third block of equations, and the sum of the entries of the solutions z1, ..., z100 for the fourth block of equations.
Like, I said - I'm able to do this in MATLAB but not in Python so I'm probably approaching this from the wrong way but this is what I have so far:
import pylab
f = open('equations.txt', 'r')
L=f.readlines()
list_final = []
for line in L:
line_l = line.rstrip()
list_l = line_l.split(";")
list_l = filter(None, list_l)
for expression in list_l:
and ending it with
f.close()
This was just my go at trying to format the equations to all look the same. I realise it's not a lot but I was really hoping someone could get my started because even though I know some python I normally don't use it for math because I have MATLAB for that.
I think this could be useful for many of us who have prior MATLAB experience but not pylab.
How would you go around this? Thank you!
For your example format, it's very easy to process it by numpy.loadtxt():
import numpy as np
data = np.loadtxt("equations.txt", dtype=str)[:, ::3].astype(np.float)
a = data[:, :-1]
b = data[:, -1]
x = np.linalg.solve(a, b)
The steps are:
An alternative approach that is possibly more robust to unstructured input is to use a combination of the Python symbolic math package (sympy), and a few parsing tricks. This scales to the variables in the equations being written in an arbitrary order.
Although sympy has some tools for parsing, (your input is very close in appearance to Mathematica), it appears that the sympy.parsing.mathematica module can't deal with some of the input (particularly leading minus signs).
import sympy
from sympy.parsing.sympy_parser import parse_expr
import re
def text_to_equations(text):
lines = text.split('\n')
lines = [line.split('=') for line in lines]
eqns = []
for lhs, rhs in lines:
# clobber all the spaces
lhs = lhs.replace(' ','')
# *assume* that a number followed by a letter is an
# implicit multiplication
lhs = re.sub(r'(\d)([a-z])', r'\g<1>*\g<2>', lhs)
eqns.append( (parse_expr(lhs), parse_expr(rhs)) )
return eqns
def get_all_symbols(eqns):
symbs = set()
for lhs, rhs in eqns:
for sym in lhs.atoms(sympy.Symbol):
symbs.add(sym)
return symbs
def text_to_eqn_matrix(text):
eqns = text_to_equations(text)
symbs = get_all_symbols(eqns)
n = len(eqns)
m = len(symbs)
A = numpy.zeros((m, n))
b = numpy.zeros((m, 1))
for i, (lhs, rhs) in enumerate(eqns):
d = lhs.as_coefficients_dict()
b[i] = int(rhs)
for j, s in enumerate(symbs):
A[i, j] = d[s]
x = sympy.Matrix([list(symbs)]).T
return sympy.Matrix(A), x, sympy.Matrix(b)
s = '''-38 y1 + 35 y2 + 31 y3 = -3047
11 y1 + -13 y2 + -34 y3 = 784
34 y1 + -21 y2 + 19 y3 = 2949'''
A, x, b = text_to_eqn_matrix(s)
print A
print x
print b

Matlab- How does you name a new variable based on other variables' values? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
How to concatenate a number to a variable name in MATLAB?
MATLAB: How can I use a variables value in another variables name?
I want to name a variable using values of other variables given in a function.
So, if I have values for an x1,x2 I can make the new variable's name as:
x_(x1's value)_(x2's value) as a name.
I've checked out the eval, num2str, strcat functions, but as of yet I can't make it so that I have a variable with the name above which I can assign a value to.
Any help would be greatly appreciated.
Take a look at the following FAQ:
How can I create variables A1, A2,...,A10 in a loop?
It answers the "how" part of your question and recommends a better approach using arrays.
As Jonas suggests, if x1 and x2 are numbers this works:
x1 = 3;
x2 = 4;
newValue = 25;
eval(sprintf('x_%i_%i = newValue;',x1,x2));
If x1 and x2 are strings, this becomes:
x1 = 'foo';
x2 = 'bar';
newValue = 25;
eval(sprintf('x_%s_%s = newValue;',x1,x2));
or more simply (using concatenation instead of SPRINTF):
x1 = 'foo';
x2 = 'bar';
newValue = 25;
eval(['x_' x1 '_' x2 ' = newValue']);
I don't know what you're trying to accomplish, but this probably isn't the best way to go about it. EVAL should always be avoided. Creating variables in the using EVAL is (a.k.a. "poofing") is doubly bad.
If you're trying to associate parameters with values, structures are a much better solution:
x1 = 'foo';
x2 = 'bar';
newValue = 25;
x.([x1 '_' x2]) = newValue;
Assuming you have a really good reason why you'd want to do that (and assuming x1 and x2 have integer values), you can do this by combining EVAL and SPRINTF.
x1 = 3;
x2 = 4;
newValue = 25;
eval(sprintf('x_%i_%i = newValue;',x1,x2));
If x1 and x2 are floats, it'll be trickier since a variable name cannot have dots in it, though it would still be possible as long as you replace the dots with something else.
However, I really have to ask: Are you sure that you want to do that? Because at the moment I cannot imagine an application where would want to create variable names you don't know beforehand, which in turn makes it very hard to write an efficient program.
EDIT
There are many useful ways to store your data in arrays. If you really don't want that, you may be interested in accessing data via key/value pairs in a MAP, a feature which is available in more recent versions of Matlab. Thus, your key would become sprintf('%i_%i',x1,x2), and the corresponding value would be whatever it is you want to store.
You can also use dynamic field references. Loren at the Mathworks gives a writeup here:
Mathworks: use-dynamic-field-references