I have been learning Lua and I was wondering if it is allowed to reference two local variables of the same name.
For example, in the following code segment, is the syntax legal (without undefined behavior)?
I ask because it does run, but I cannot seem to figure out what is happening behind the scenes. Is this simply referencing the same x local? Or are there now two local x variables that mess things up behind the scenes. I'd like to know what exactly is happening here and why it is the case.
local x = 5 + 3; -- = 8
local x = 3 - 2; -- = 1
print("x = " .. x); -- x = 1
There are two variables. The second shadows (but does not remove or overwrite) the first.
Sometimes you can still access the earlier definition via a closure.
local x = 5 + 3
local function getX1()
return x
end
local x = 3 - 2
local function getX2()
return x
end
print("x = " .. x); -- x = 1
print("x = " .. getX1()); -- x = 8
print("x = " .. getX2()); -- x = 1
All your local variables have been remembered by Lua :-)
local x = 5 + 3; -- = 8
local x = 3 - 2; -- = 1
local i = 0
repeat
i = i + 1
local name, value = debug.getlocal(1, i)
if name == 'x' then
print(name..' = '..value)
end
until not name
Yes, it is legal. Lua handles local-variable declarations as statements.
Here's an interesting example from the Lua Reference Manual:
Notice that each execution of a local statement defines new local variables. Consider the following example:
a = {}
local x = 20
for i=1,10 do
local y = 0
a[i] = function () y=y+1; return x+y end
end
The loop creates ten closures (that is, ten instances of the anonymous function). Each of these closures uses a different y variable, while all of them share the same x.
In this example, if ignore the returning closure part, there are 10 local variables named y in the same for block.
Related
I would like to see if the distribution of my species is affected by specific environmental parameters. When I try to do the analysis with the function "capscale ()" the graph showed only the first 5 variables of the 20 total. Please, can someone help me? Thanks.
This is the code I used.
species <- read.table('db-RDA.txt', sep ='\t', h = T, strip.white = T)
species = species[,2:ncol(species)]
species001= (species + 0.001)
fix(species001)
env <- read.table('Env Db-RDA.txt', sep ='\t', h = T, strip.white = T)
env = env[,-1]
env001= (env + 0.001)
fix(env001)
#I have not put all variables but only appeared the first 5 explanatory variables
dbRDA = capscale(species001 ~ Rock + Sand + Rubble + pH + NOx + NH4 + Temp + SIOH + DIC, data=env001, dist = "bray", scale=TRUE)
plot(dbRDA)
I guess that the function told you that some of your variables were aliased. Aliasing means that these variables are linear combinations of some other variables in the model, and there is no independent information to estimate those. See what the output says when you just call the short description of your result. You can get this by typing the name of the result as dbRDA.
This question already has an answer here:
Haskell: What is immutable data?
(1 answer)
Closed 4 years ago.
I heard that Haskell variables are immutable but i am able to reassign and update variable values
First, note that GHCi syntax is not quite the same as Haskell source-file syntax. In particular, x = 3 actually used to be illegal as such:
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> x = 3
<interactive>:2:3: parse error on input ‘=’
Newer versions have made this possible by simply rewriting any such expression to let x = 3, which has always been ok:
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> let x = 3
Prelude> x
3
By contrast, in a Haskell source file, let x = 3 has never been legal by itself. This only works in a particular environment, namely a monadic do block.
main :: IO ()
main = do
let x = 3
print x
3
And the GHCi prompt by design actually works like the lines in a do block, so let's in the following discuss that. Note that I can also write
main = do
let x = 1
let x = 3
print x
3
And that's basically what's also going on in your GHCi session. However, as the others have remarked, this is not mutation but shadowing. To understand how this works, note that the above is essentially a shorthand way of writing
main =
let x = 1
in let x = 3
in print x
So, you have two nested scopes. When you look up a variable in some expression, Haskell always picks the “nearest one”, i.e. in the inner scope:
main =
let x = 1
┌──
in│let x = 3
│in print x
└─
The outer x isn't touched at all, it's basically unrelated to anything going on in the inner scope. The compiler will actually warn you about this, if asked if there's anything fishy in your file:
$ ghc -Wall wtmpf-file16485.hs
[1 of 1] Compiling Main ( wtmpf-file16485.hs, wtmpf-file16485.o )
wtmpf-file16485.hs:3:8: warning: [-Wunused-local-binds]
Defined but not used: ‘x’
|
3 | let x = 1
| ^
wtmpf-file16485.hs:3:12: warning: [-Wtype-defaults]
• Defaulting the following constraint to type ‘Integer’
Num p0 arising from the literal ‘3’
• In the expression: 3
In an equation for ‘x’: x = 3
In the expression:
do let x = 1
let x = 3
print x
|
3 | let x = 1
| ^
wtmpf-file16485.hs:4:8: warning: [-Wname-shadowing]
This binding for ‘x’ shadows the existing binding
bound at wtmpf-file16485.hs:3:8
|
4 | let x = 3
| ^
There: the second definition simply introduces a new, more local variable which also happens to be called x, but is unrelated to the outer variable. I.e. we might as well rename them:
main = do
let xOuter = 1
let xInner = 3
print xInner
A consequence of all this is that a variable that's “mutated” in this way has no influence on other functions which use the original variable. Example:
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/sagemuej/.ghci
Loaded GHCi configuration from /home/sagemuej/.ghc/ghci.conf
Prelude> let x = 1
Prelude> let info = putStrLn ("x is ="++show x++" right now")
Prelude> x = 3
Prelude> info
x is =1 right now
Another consequence is that “updates” which try to use the old value behave in a funny way:
Prelude> let s = "World"
Prelude> s = "Hello"++s
Prelude> s
"HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHell^C
Here, the new binding does not just prepend "Hello" to the old s="World". Instead, it prepends "Hello" to its own result value, which is in turn defined by "Hello" prepended to... and so on, recursively.
You're shadowing, not mutating.
I am trying to follow the tutorial of using the optimization tool box in MATLAB. Specifically, I have a function
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1)+b
subject to the constraint:
(x(1))^2+x(2)-1=0,
-x(1)*x(2)-10<=0.
and I want to minimize this function for a range of b=[0,20]. (That is, I want to minimize this function for b=0, b=1,b=2 ... and so on).
Below is the steps taken from the MATLAB's tutorial webpage(http://www.mathworks.com/help/optim/ug/nonlinear-equality-and-inequality-constraints.html), how should I change the code so that, the optimization will run for 20 times, and save the optimal values for each b?
Step 1: Write a file objfun.m.
function f = objfun(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1)+b;
Step 2: Write a file confuneq.m for the nonlinear constraints.
function [c, ceq] = confuneq(x)
% Nonlinear inequality constraints
c = -x(1)*x(2) - 10;
% Nonlinear equality constraints
ceq = x(1)^2 + x(2) - 1;
Step 3: Invoke constrained optimization routine.
x0 = [-1,1]; % Make a starting guess at the solution
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#objfun,x0,[],[],[],[],[],[],...
#confuneq,options);
After 21 function evaluations, the solution produced is
x, fval
x =
-0.7529 0.4332
fval =
1.5093
Update:
I tried your answer, but I am encountering problem with your step 2. Bascially, I just fill the my step 2 to your step 2 (below the comment "optimization just like before").
%initialize list of targets
b = 0:1:20;
%preallocate/initialize result vectors using zeros (increases speed)
opt_x = zeros(length(b));
opt_fval = zeros(length(b));
>> for idx = 1, length(b)
objfun = #(x)objfun_builder(x,b)
%optimization just like before
x0 = [-1,1]; % Make a starting guess at the solution
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#objfun,x0,[],[],[],[],[],[],...
#confuneq,options);
%end the stuff I fill in
opt_x(idx) = x
opt_fval(idx) = fval
end
However, it gave me the output is:
Error: "objfun" was previously used as a variable, conflicting
with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB
documentation for details.
There are two things you need to change about your code:
Creation of the objective function.
Multiple optimizations using a loop.
1st Step
For more flexibility with regard to b, you need to set up another function that returns a handle to the desired objective function, e.g.
function h = objfun_builder(x, b)
h = #(x)(objfun(x));
function f = objfun(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1) + b;
end
end
A more elegant and shorter approach are anonymous functions, e.g.
objfun_builder = #(x,b)(exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1) + b);
After all, this works out to be the same as above. It might be less intuitive for a Matlab-beginner, though.
2nd Step
Instead of placing an .m-file objfun.m in your path, you will need to call
objfun = #(x)(objfun_builder(x,myB));
to create an objective function in your workspace. In order to loop over the interval b=[0,20], use the following loop
%initialize list of targets
b = 0:1:20;
%preallocate/initialize result vectors using zeros (increases speed)
opt_x = zeros(length(b))
opt_fval = zeros(length(b))
%start optimization of list of targets (`b`s)
for idx = 1, length(b)
objfun = #(x)objfun_builder(x,b)
%optimization just like before
opt_x(idx) = x
opt_fval(idx) = fval
end
In AMPL I have a set of variables x[e], for some calculations I need a binary variable w[e] which equals 1 when x[e] > 0 and 0 if x[e] = 0. I tried a lot of stuff to make this constraint, but I failed to come up with something. Is this possible?
I have solved your problem the following way:
var u binary;
this is our binary variable that will be 0 or 1.
Then we put following constraint:
subject to U_constraint :
x <= 999999 * u;
Now when x = 0 then AMPL will make u = 0 and when x != 0 obviously u = 1.
When evaluation order is specified as "left to right" and language is a (pseudo) C-like, which are the sequence points in the following examples?
int x = 1;
int z = x-- + x; // z = 1 + 0 or z = 1 + 1?
my_func(x++); // x incremented before or after my_func execution?
my_func(x++ + --x); // combining those above
A sequence point is what the language standard defines to be a sequence point. The answers I'm about to give apply to C, but another "C-like" language might very well define different sequence points and thus have different answers to those questions.
int z = x-- + x; // z = 1 + 0 or z = 1 + 1?
Since + is not a sequence point in C, the result of the above statement is undefined.
my_func(x++); // x incremented before or after my_func execution?
x is incremented before my_func runs, but my_func is called with the old value of x as an argument.
my_func(x++ + --x); // combining those above
Undefined for the same reason as the first one.