I'm trying to insert tensors of different dimensions into a lua table. But the insertion is writing the last tensor to all the previous elements in the table.
MWE:
require 'nn';
char = nn.LookupTable(100,10,0,1)
charRep = nn.Sequential():add(char):add(nn.Squeeze())
c = {}
c[1] = torch.IntTensor(5):random(1,100)
c[2] = torch.IntTensor(2):random(1,100)
c[3] = torch.IntTensor(3):random(1,100)
--This works fine
print(c)
charFeatures = {}
for i=1,3 do
charFeatures[i] = charRep:forward(c[i])
--table.insert(charFeatures, charRep:forward(c[i]))
-- No difference when table.insert is used
end
--This fails
print(charFeatures)
Maybe i haven't understood how tables work in Lua. But this code copies the last tensor to all previous charFeatures elements.
The issue is not related with tables, but is very common in Torch though. When you call the forward method on a neural net, its state value output is changed. Now when you save this value into charFeatures[i] you actually create a reference from charFeatures[i] to charRep.output. Then in the next iteration of the loop charRep.output is modified and consequently all the elements of charFeatures are modified too, since they point to the same value which is charRep.output.
Note that this behavior is the same as when you do
a = torch.Tensor(5):zero()
b = a
a[1] = 0
-- then b is also modified
Finally to solve your problem you should clone the output of the network:
charFeatures[i] = charRep:forward(c[i]):clone()
And all will work as expected!
Related
When creating an element in the table, I need to use another element that I created before in the same table. please help me with this.
local table = {
distance = 30.0,
last_distance = table.distance-10.0
}
I want to do the above operation but I can't, I think I need to use self or setmetatable but I don't know how to do it. and please don't give me answers like first create a value outside and then use it in the table, I don't want to do that.
Basic life advice
First of all: Don't call your table table. That will shadow the global table library. Call it t, tab, tabl, Table, table_, or actually give it a useful name, but don't call it table, or there'll be a big surprise when you try to access any table.* methods. Ideally, your linter should warn you about this.
Implementing it using hacks
Table constructors are equivalent to creating a table on the stack - there is no named local variable self or the like. It is likely possible that there is a hidden local variable accessible using debug.getlocal however:
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> function getlocals()
>> local i = 1; repeat local k, v = debug.getlocal(2, i); i = i + 1; print(k, v) until not k
>> t = {a = getlocals(), b = ()}
stdin:3: unexpected symbol near ')'
> function getlocals()
local i = 1; repeat local k, v = debug.getlocal(2, i); i = i + 1; print(k, v) until not k end
> t = {a = getlocals(), b = 2}
(temporary) table: 0x55e9181302d0
nil nil
> t
table: 0x55e9181302d0
Indeed, from basic testing it appears that this is even the first local inside the table constructor! However, it isn't quite as easy:
> local a = 1; local b = a; t = {a = getlocals(), b = 2}; print(b)
a 1
b 1
(temporary) table: 0x55e918130160
nil nil
1
Using extensive hacks, you might be able to write something that returns the currently constructed table most of the time (probably relying on the fact that it will usually be the last local). The following works:
function lastlocal()
local i = 0
local last
::next:: -- you could (and perhaps should) use a loop instead
i = i + 1
local k, v = debug.getlocal(2, i)
if v then
last = v
goto next
end
return last
end
from my basic testing, this works fine to obtain the table currently being constructed:
> function lastlocal()
local i = 0
local last
::next:: -- you could (and perhaps should) use a loop instead
i = i + 1
local k, v = debug.getlocal(2, i)
if v then
last = v
goto next
end
return last
end
> t = {a = 1, b = lastlocal().a}
> t.a
1
> t.b
1
Why you should not implement this using hacks
With all of this in mind: Don't ever do this. The purpose of this merely is to lead this ad absurdum. There are multiple reasons why this is horribly unreliable:
The order of execution of table constructor assignments is undefined. An optimizing interpreter like LuaJIT (and the PUC Lua implementation just as well) is free to reorder {a = 1, b = 2} to {b = 2, a = 1}.
Likewise, how table constructors are implemented internally is entirely undefined. There is no guarantee that the local variable actually exists and is the last one.
It is horribly inefficient and relies on the debug library for something other than debugging.
What's a metatable?
Metatables serve an entirely different purpose; you could dynamically generate derived fields like last_distance using them, but you can't use them to reference a table using a table constructor. Here's a basic example:
local t = {distance = 30}
setmetatable(t, {__index = function(self, k)
if k ~= "last_distance" then return nil end
return t.distance - 10 -- calculate `last_distance` & return it
end})
print(t.last_distance) -- 20
t.distance = 10
print(t.last_distance) -- 0
Back to the question
When creating an element in the table, I need to use another element that I created before in the same table.
The proper way to do this is to either (1) create a value outside of the table
local distance = 30
local last_distance = distance - 10
local tab = {distance = distance, last_distance = last_distance}
Perfectly readable, perfectly fine.
Or (2) first create a table with some properties, then add derived properties:
local tab = {distance = 30}
tab.last_distance = tab.distance - 10
as readable, as fine.
Both will be highly efficient; only micro-optimizations would be debatable (could (1) choose a better layout for the hashes by choosing the right insertion order? does it pre-allocate the right size (likely yes)? does (2) incur a penalty since it indexes tab to obtain tab.distance?), but none of this will likely ever matter.
I want to do the above operation but I can't, I think I need to use self or setmetatable but I don't know how to do it.
I have shown you:
How you can do it using egregious hacks and why you shouldn't.
How you can do something similar (derived attributes) using a metamethod.
and please don't give me answers like first create a value outside and then use it in the table, I don't want to do that.
This is the correct, idiomatic way to do this in Lua though. Your restriction seems arbitrary.
I have the following code which Roblox Developer and the Lua.org manual both say should work to remove an instance from the table so I can store as a local, but the local is only holding a nil value.
The table is there. It shows up on the print function. It just will not store to be useful in the app.
I have tried multiple versions of this code including going with just the pairs function, just the table.remove function, and going with and without the position for the table remove, and it all generates nil variable.
response = HttpService:GetAsync(mining)
data = HttpService:JSONDecode(response, Enum.HttpContentType.ApplicationJson)
local function tprint(t)
for k,v in pairs(t) do print(k,v) end
end
tprint(data)
local a = table.remove(data, 4)
local b = table.remove(data, 3)
local c = table.remove(data, 2)
local d = table.remove(data, 1)
The solution ended up being so simple, and yet so profound. I can now use this to link crypto, bank accounts, credit cards, and anything else I want directly into Roblox or any other lua based program.
a = (data["result"]["amount"])
Before I dig into the error you're seeing, first some background information.
Lua tables have two methods of indexing values: numerically, and by keys. Often times you will see these two different methods be used to describe the kind of data structure that uses it.
Arrays and lists are tables that use numeric keys to index information.
local arr = {}
arr[1] = "abc"
arr[2] = 123
arr[3] = true
-- print the length of the array
print(#arr) -- 3
-- print the contents of the array
for i, v in ipairs(arr) do
print(i, v)
-- 1 abc
-- 2 123
-- 3 true
end
On the other side of things, dictionaries and hash maps and associative arrays use keys to store information :
local dict = {}
dict["foo"] = "abc"
dict["bar"] = 123
dict["blah"] = true
dict["katz"] = { 1, 2, 3 }
-- print the number of numerical keys in the dictionary
print(#dict) -- 0
-- print the contents of the dictionary
for k, v in pairs(dict) do
print(k, v)
-- foo abc
-- bar 123
-- blah true
-- katz table
end
While lua allows a table to use both of these indexing methods simultaneously, it's important never to mix the two, as behaviors can get real funky when you do. When a table has keys, treat it like a dictionary. When a table has numerical indices, treat it like an array.
When you use HttpService to decode a JSON string into a table, it generates a dictionary that reflects the heirarchical structure of the original data.
The table library, which you call with table.insert() and table.remove() expects that the table you're working with is an array.
When your data is arranged like this :
local data = {}
data["Success"] = true
data["StatusCode"] = 200
data["StatusMessage"] = "Success"
data["Headers"] = {} -- a dictionary of headers
data["Body"] = {
result = {
amount = 1,
depositAddress = "blah",
},
} -- after HttpService:JSONDecode() is called...
And you tell it to remove a numbered index with table.remove(data, 4), it won't work because there's no data stored at index number 4. data is a dictionary, not an array.
Often, it is annoying to try to print out the contents of a table with multiple layers of data, especially JSON tables, as the pairs function will only index one level at a time. Thankfully, Roblox's print function and Output widget are smart enough to do this for you. You can simply print(data) and it will show you the full table in the output and allow you to inspect each level.
Then once you know how your data is structured you can step through it value by value.
local amount = data["Body"]["result"]["amount"]
-- or
local amount = data.Body.result.amount
I have a problem where I need to do a linear interpolation on some data as it is acquired from a sensor (it's technically position data, but the nature of the data doesn't really matter). I'm doing this now in matlab, but since I will eventually migrate this code to other languages, I want to keep the code as simple as possible and not use any complicated matlab-specific/built-in functions.
My implementation initially seems OK, but when checking my work against matlab's built-in interp1 function, it seems my implementation isn't perfect, and I have no idea why. Below is the code I'm using on a dataset already fully collected, but as I loop through the data, I act as if I only have the current sample and the previous sample, which mirrors the problem I will eventually face.
%make some dummy data
np = 109; %number of data points for x and y
x_data = linspace(3,98,np) + (normrnd(0.4,0.2,[1,np]));
y_data = normrnd(2.5, 1.5, [1,np]);
%define the query points the data will be interpolated over
qp = [1:100];
kk=2; %indexes through the data
cc = 1; %indexes through the query points
qpi = qp(cc); %qpi is the current query point in the loop
y_interp = qp*nan; %this will hold our solution
while kk<=length(x_data)
kk = kk+1; %update the data counter
%perform online interpolation
if cc<length(qp)-1
if qpi>=y_data(kk-1) %the query point, of course, has to be in-between the current value and the next value of x_data
y_interp(cc) = myInterp(x_data(kk-1), x_data(kk), y_data(kk-1), y_data(kk), qpi);
end
if qpi>x_data(kk), %if the current query point is already larger than the current sample, update the sample
kk = kk+1;
else %otherwise, update the query point to ensure its in between the samples for the next iteration
cc = cc + 1;
qpi = qp(cc);
%It is possible that if the change in x_data is greater than the resolution of the query
%points, an update like the above wont work. In this case, we must lag the data
if qpi<x_data(kk),
kk=kk-1;
end
end
end
end
%get the correct interpolation
y_interp_correct = interp1(x_data, y_data, qp);
%plot both solutions to show the difference
figure;
plot(y_interp,'displayname','manual-solution'); hold on;
plot(y_interp_correct,'k--','displayname','matlab solution');
leg1 = legend('show');
set(leg1,'Location','Best');
ylabel('interpolated points');
xlabel('query points');
Note that the "myInterp" function is as follows:
function yi = myInterp(x1, x2, y1, y2, qp)
%linearly interpolate the function value y(x) over the query point qp
yi = y1 + (qp-x1) * ( (y2-y1)/(x2-x1) );
end
And here is the plot showing that my implementation isn't correct :-(
Can anyone help me find where the mistake is? And why? I suspect it has something to do with ensuring that the query point is in-between the previous and current x-samples, but I'm not sure.
The problem in your code is that you at times call myInterp with a value of qpi that is outside of the bounds x_data(kk-1) and x_data(kk). This leads to invalid extrapolation results.
Your logic of looping over kk rather than cc is very confusing to me. I would write a simple for loop over cc, which are the points at which you want to interpolate. For each of these points, advance kk, if necessary, such that qp(cc) is in between x_data(kk) and x_data(kk+1) (you can use kk-1 and kk instead if you prefer, just initialize kk=2 to ensure that kk-1 exists, I just find starting at kk=1 more intuitive).
To simplify the logic here, I'm limiting the values in qp to be inside the limits of x_data, so that we don't need to test to ensure that x_data(kk+1) exists, nor that x_data(1)<pq(cc). You can add those tests in if you wish.
Here's my code:
qp = [ceil(x_data(1)+0.1):floor(x_data(end)-0.1)];
y_interp = qp*nan; % this will hold our solution
kk=1; % indexes through the data
for cc=1:numel(qp)
% advance kk to where we can interpolate
% (this loop is guaranteed to not index out of bounds because x_data(end)>qp(end),
% but needs to be adjusted if this is not ensured prior to the loop)
while x_data(kk+1) < qp(cc)
kk = kk + 1;
end
% perform online interpolation
y_interp(cc) = myInterp(x_data(kk), x_data(kk+1), y_data(kk), y_data(kk+1), qp(cc));
end
As you can see, the logic is a lot simpler this way. The result is identical to y_interp_correct. The inner while x_data... loop serves the same purpose as your outer while loop, and would be the place where you read your data from wherever it's coming from.
I'm trying to work with some matrix in lua for my dungeon generator. Basically I'll have matrix [x][y] and a structure inside there will store the info of each "room". But since it is a generator, I don't know how many rooms I'll have, and the only way I know is to make something like this:
mat = {}
for i = 0, 10 do
mat[i] = {}
for j = 0, 10 do
mat[i][j] = 1
end
end
So the question is, is there a way to create a matrix that dynamic increases the size as I add data to it? because there will be blank spaces since the dungeon is going to be like a tree branch.
From Programming in Lua:
Moreover, tables have no fixed size; you can add as many elements as
you want to a table dynamically.
To handle access to non-existent table members and so avoid error messages for indexing nil values you can use a metatable implementing the __index metamethod.
In the following example Lua will insert an empty table into your table whenever it is not there yet.
Please refer to https://www.lua.org/manual/5.3/manual.html#2.4 for details
local mt_2D = {
__index =
function(t, k)
local inner = {}
rawset(t, k, inner)
return inner
end
}
local array2D = setmetatable({}, mt_2D)
array2D[2][5] = 'it works'
print(array2D[2][5]) --> it works
I am working on programming a Markov chain in Lua, and one element of this requires me to uniformly generate random numbers. Here is a simplified example to illustrate my question:
example = function(x)
local r = math.random(1,10)
print(r)
return x[r]
end
exampleArray = {"a","b","c","d","e","f","g","h","i","j"}
print(example(exampleArray))
My issue is that when I re-run this program multiple times (mash F5) the exact same random number is generated resulting in the example function selecting the exact same array element. However, if I include many calls to the example function within the single program by repeating the print line at the end many times I get suitable random results.
This is not my intention as a proper Markov pseudo-random text generator should be able to run the same program with the same inputs multiple times and output different pseudo-random text every time. I have tried resetting the seed using math.randomseed(os.time()) and this makes it so the random number distribution is no longer uniform. My goal is to be able to re-run the above program and receive a randomly selected number every time.
You need to run math.randomseed() once before using math.random(), like this:
math.randomseed(os.time())
From your comment that you saw the first number is still the same. This is caused by the implementation of random generator in some platforms.
The solution is to pop some random numbers before using them for real:
math.randomseed(os.time())
math.random(); math.random(); math.random()
Note that the standard C library random() is usually not so uniformly random, a better solution is to use a better random generator if your platform provides one.
Reference: Lua Math Library
Standard C random numbers generator used in Lua isn't guananteed to be good for simulation. The words "Markov chain" suggest that you may need a better one. Here's a generator widely used for Monte-Carlo calculations:
local A1, A2 = 727595, 798405 -- 5^17=D20*A1+A2
local D20, D40 = 1048576, 1099511627776 -- 2^20, 2^40
local X1, X2 = 0, 1
function rand()
local U = X2*A2
local V = (X1*A2 + X2*A1) % D20
V = (V*D20 + U) % D40
X1 = math.floor(V/D20)
X2 = V - X1*D20
return V/D40
end
It generates a number between 0 and 1, so r = math.floor(rand()*10) + 1 would go into your example.
(That's multiplicative random number generator with period 2^38, multiplier 5^17 and modulo 2^40, original Pascal code by http://osmf.sscc.ru/~smp/)
math.randomseed(os.clock()*100000000000)
for i=1,3 do
math.random(10000, 65000)
end
Always results in new random numbers. Changing the seed value will ensure randomness. Don't follow os.time() because it is the epoch time and changes after one second but os.clock() won't have the same value at any close instance.
There's the Luaossl library solution: (https://github.com/wahern/luaossl)
local rand = require "openssl.rand"
local randominteger
if rand.ready() then -- rand has been properly seeded
-- Returns a cryptographically strong uniform random integer in the interval [0, n−1].
randominteger = rand.uniform(99) + 1 -- randomizes an integer from range 1 to 100
end
http://25thandclement.com/~william/projects/luaossl.pdf