Could anyone help me with a way to randomly fill a table with N values, where the values are 1,...,M allowing no duplicates ?
Cheers.
local M, N, tNonFinal, tFinal = 500, 20, {}, {}
math.randomseed( os.time() )
for i = 1, N, 1 do
local iRandom = math.random(1, M)
while tNonFinal[iRandom] do
iRandom = math.random(1, M)
end
table.insert( tNonFinal, iRandom, true )
tFinal[i] = iRandom
end
Your required table will be tFinal. You can also add a condition where if M < N then N = M end
This may help you...
local myArray = {}
local valueArray = {1,2,3,4,5,6,7,8,9,10} -- let it be the array with values 1,2...M
local index = 0
local isFetched = {}
for i=1,#valueArray do
isFetched[i] = 0
end
local randomValue = 0
local function addTomyArray()
randomValue = math.random(#valueArray)
if(isFetched[randomValue]==0)then
index = index + 1
isFetched[randomValue] = 1
myArray[index] = valueArray[randomValue]
if(index==#valueArray)then
for i=1,#myArray do
print(myArray[i]) -- result : shuffled array
end
end
else
addTomyArray()
end
end
timer.performWithDelay(0,addTomyArray,#valueArray) -- #valueArray
Keep coding........ 😃
Related
I have a table t with many entries like t["name1"] = 42, t["name2"] = 123, ...
I would like to iterate over the table in descending order of the value numbers. How can this be accomplished? I have found methods to create iterator functions that go ordered over the keys of a table, but no way to go over the entries with ordered values.
function pairs_order_by_values_desc(tab)
local keys = {}
for k in pairs(tab) do
keys[#keys + 1] = k
end
table.sort(keys, function(a, b) return tab[a] > tab[b] end)
local j = 0
return
function()
j = j + 1
local k = keys[j]
if k ~= nil then
return k, tab[k]
end
end
end
local t = {}
t.name1 = 42
t.name2 = 123
t.name3 = 99
for k, v in pairs_order_by_values_desc(t) do
print(k, v)
end
I'm trying to implement Smith-Waterman alignment in parallel using Julia (see: Figure 1 of http://www.cs.virginia.edu/~rl6sf/paper_dump/2011:12:33:22.pdf), but the algorithm is running much slower in Julia than the serial version. I'm using shared arrays to do this and figure I am doing something silly that is making the code run slow. Could someone take a look and see if my code is optimized as possible? The parallel version should run faster than in serial….
The basic concept of it is to compute the anti-diagonal elements of a matrix in parallel from the upper left to lower right corner and to update them. I'm trying to use 32 cores on a shared array machine to do this. I have a SharedArray matrix that I am using to do this and am computing the elements of each anti-diagonal in parallel as shown below. The while loops in the spSW function submit tasks to workers in sync for each anti-diagonal using the helper function shared_get_score(). The main goal of this function is to fill in each element in the shared arrays "matrix" and "path".
function spSW(seq1,seq2,p)
indel = -1
match = 2
seq1 = "^$seq1"
seq2 = "^$seq2"
col = length(seq1)
row = length(seq2)
wl = workers()
matrix,path = shared_initialize_path(seq1,seq2)
for j = 2:col
jcol = j
irow = 2
#sync begin
count = 0
while jcol > 1 && irow < row + 1
#println(j," ",irow," ",jcol)
if seq1[jcol] == seq2[irow]
equal = true
else
equal = false
end
w = wl[(count % p) + 1]
#async remotecall_wait(w,shared_get_score!,matrix,path,equal,indel,match,irow,jcol)
jcol -= 1
irow += 1
count += 1
end
end
end
for i = 3:row
jcol = col
irow = i
#sync begin
count = 0
while irow < row+1 && jcol > 1
#println(j," ",irow," ",jcol)
if seq1[jcol] == seq2[irow]
equal = true
else
equal = false
end
w = wl[(count % p) + 1]
#async remotecall_wait(w,shared_get_score!,matrix,path,equal,indel,match,irow,jcol)
jcol -= 1
irow += 1
count += 1
end
end
end
return matrix,path
end
The other helper functions are:
function shared_initialize_path(seq1,seq2)
col = length(seq1)
row = length(seq2)
matrix = convert(SharedArray,fill(0,(row,col)))
path = convert(SharedArray,fill(0,(row,col)))
return matrix,path
end
#everywhere function shared_get_score!(matrix,path,equal,indel,match,i,j)
pathvalscode = ["-","|","M"]
pathvals = [1,2,3]
scores = []
push!(scores,matrix[i,j-1]+indel)
push!(scores,matrix[i-1,j]+indel)
if equal
push!(scores,matrix[i-1,j-1]+match)
else
push!(scores,matrix[i-1,j-1]+indel)
end
val,ind = findmax(scores)
if val < 0
matrix[i,j] = 0
else
matrix[i,j] = val
end
path[i,j] = pathvals[ind]
end
Does anyone see an obvious way to make this run faster? Right now it's about 10 times slower than the serial version.
I need to initialize a 3D tensor with an index-dependent function in torch7, i.e.
func = function(i,j,k) --i, j is the index of an element in the tensor
return i*j*k --do operations within func which're dependent of i, j
end
then I initialize a 3D tensor A like this:
for i=1,A:size(1) do
for j=1,A:size(2) do
for k=1,A:size(3) do
A[{i,j,k}] = func(i,j,k)
end
end
end
But this code runs very slow, and I found it takes up 92% of total running time. Are there any more efficient ways to initialize a 3D tensor in torch7?
See the documentation for the Tensor:apply
These functions apply a function to each element of the tensor on
which the method is called (self). These methods are much faster than
using a for loop in Lua.
The example in the docs initializes a 2D array based on its index i (in memory). Below is an extended example for 3 dimensions and below that one for N-D tensors. Using the apply method is much, much faster on my machine:
require 'torch'
A = torch.Tensor(100, 100, 1000)
B = torch.Tensor(100, 100, 1000)
function func(i,j,k)
return i*j*k
end
t = os.clock()
for i=1,A:size(1) do
for j=1,A:size(2) do
for k=1,A:size(3) do
A[{i, j, k}] = i * j * k
end
end
end
print("Original time:", os.difftime(os.clock(), t))
t = os.clock()
function forindices(A, func)
local i = 1
local j = 1
local k = 0
local d3 = A:size(3)
local d2 = A:size(2)
return function()
k = k + 1
if k > d3 then
k = 1
j = j + 1
if j > d2 then
j = 1
i = i + 1
end
end
return func(i, j, k)
end
end
B:apply(forindices(A, func))
print("Apply method:", os.difftime(os.clock(), t))
EDIT
This will work for any Tensor object:
function tabulate(A, f)
local idx = {}
local ndims = A:dim()
local dim = A:size()
idx[ndims] = 0
for i=1, (ndims - 1) do
idx[i] = 1
end
return A:apply(function()
for i=ndims, 0, -1 do
idx[i] = idx[i] + 1
if idx[i] <= dim[i] then
break
end
idx[i] = 1
end
return f(unpack(idx))
end)
end
-- usage for 3D case.
tabulate(A, function(i, j, k) return i * j * k end)
I am working on implementing "Goal-based vector field pathfinding" (demonstrated in the article at this link) It requires that I label every node in my world graph with a path distance from the goal node and recommends using a brushfire (wavefront) algorithm to do this. This is the area I am having issues in. When I get to the 8th iteration of my while loop and the 6th iteration of my nested for, I get a nil reference error on the marked line.
g is my graph, which has an 8-way adjacency list form.
q is an instance of this FIFO lua library.
rtx and rty are the x and y coords of the root node.
d is an iterator added to keep track of the path distance assigned to each node.
The structure of each node in the graph is not the same as the structure of a node being processed.
Node for processing:
n = {}
n[1] = x coord
n[2] = y coord
n[3] = adjacency list (eight entries)
n.vX = x componant of vector for vector field
n.vY = y componant of vector for vector field
Node stored in graph:
n = {}
n[1] = adjacency list
n.vX = x componant of vector for vector field
n.vY = y componant of vector for vector field
Beneath is my implementation so far. The t in the for loop is just a temporary node used to pass information along to the queue. BTW t is where the distance of all the nodes gets set.
local function brushFire( g, rtx, rty )
local q = q.new()
local s = {}
s[1] = rtx
s[2] = rty
s[3] = g[rtx][rty][3]
s.dist = 0
q:pushRight( s )
s = nil
local d = 0
while( table.getn( q.list[q.first] ) ~= 0 ) do
print( d )
local n = q:popLeft()
setDist( g, n )
print( #n[3] )
for i = 1, #n[3] do
print( ":"..i )
if( g[n[3][i][4]][n[3][i][2]].v ~= true ) then
g[n[3][i][5]][n[3][i][2]].v = true
local t = {}
t[1] = n[3][i][1]
t[2] = n[3][i][2]
t[3] = g[n[3][i][7]][n[3][i][2]][1] <------Error here
t.dist = d
q:pushRight( t )
t = nil
end
end
d = d + 1
end
end
Let me know if you need more information in order to answer my question.
I found the answer to my problem. If anyone wants to use the source, I am posting it below:
Queue module:
local q = {}
local q_mt = { __index = q }
function q.new()
local nq = { first = 0, last = -1, list = {} }
return setmetatable( nq, q_mt )
end
function q:pushLeft( value )
local first = self.first - 1
self.first = first
self.list[first] = value
end
function q:pushRight( value )
local last = self.last + 1
self.last = last
self.list[last] = value
end
function q:popLeft()
local first = self.first
if first > self.last then error( "list is empty" ) end
local value = self.list[first]
self.list[first] = nil
self.first = first + 1
return value
end
function q:popRight()
local last = self.last
if self.first > last then error( "list is empty" ) end
local value = self.list[last]
self.list[last] = nil
self.last = last - 1
return value
end
return q
The following module creates a vector field which points towards a goal when pathFind.findPath is called:
local q = require( "Queue" )
local pathFind = {}
local pathFind_mt = { __index = pathFind }
-- Private Functions
local function genDistMap( g, rtx, rty ) -<-<-<- genDistMap is the brushfire part
local q = q.new()
local g = g
g[rtx][rty].v = true
g[rtx][rty].dist = 0
local s = {}
s[1] = rtx
s[2] = rty
s[3] = g[rtx][rty][1]
s.dist = 0
q:pushRight( s )
s = nil
while( q.list[q.first] ~= nil ) do
local n = q:popLeft()
for i = 1, #n[3] do
local x, y = n[3][i][1], n[3][i][2]
if( g[x][y].v ~= true ) then
g[x][y].v = true
local t = {}
t[1] = x
t[2] = y
t[3] = g[x][y][1]
t.dist = n.dist + 1
g[x][y].dist = n.dist + 1
q:pushRight( t )
t = nil
end
end
end
return g
end
local function genVectorField( nodes )
local nodes = nodes
for i = 2, #nodes - 1 do
for j = 2, #nodes[i] - 1 do
local a = nodes[i - 1][j].dist - nodes[i + 1][j].dist
local b = nodes[i][j - 1].dist - nodes[i][j + 1].dist
local c = math.sqrt( a*a + b*b )
nodes[i][j].vX = a/c*5
nodes[i][j].vY = b/c*5
end
end
return nodes
end
-- Public Functions
function pathFind.new()
local newPathFind = {}
return setmetatable ( newPathFind, pathFind_mt )
end
function pathFind.findPath( nodeSet, rootX, rootY )
local nodes = nodeSet
nodes = genDistMap( nodes, rootX, rootY )
nodes = genVectorField( nodes )
return( nodes )
end
return pathFind
I am very new to Lua, so please be gentle.
I want a sorted results based on the "error" key. For this example, the output should be:
c 50 70
d 25 50
b 30 40
a 10 20
Here is my script:
records = {}
records["a"] = {["count"] = 10, ["error"] = 20}
records["b"] = {["count"] = 30, ["error"] = 40}
records["c"] = {["count"] = 50, ["error"] = 70}
records["d"] = {["count"] = 25, ["error"] = 50}
function spairs(t, order)
-- collect the keys
local keys = {}
for k in pairs(t) do keys[#keys+1] = k end
-- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys
if order then
table.sort(keys, function(a,b) return order(t, a, b) end)
else
table.sort(keys)
end
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
for k, v in pairs(records) do
for m, n in pairs(v) do
for x, y in spairs(v, function(t,a,b) return t[b] < t[a] end) do
line = string.format("%s %5s %-10d", k, n, y)
end
end
print(line)
end
I found this about sorting a table and tried to implement it. But it does not work, results are not sorted.
table.sort only works when the table elements are integrally indexed. In your case; when you try to call spairs, you are actually calling table.sort on the count and error indices.
First off; remove the ugly, irrelevant nested for..pairs loops. You only need the spairs for your task.
for x, y in spairs(records, function(t, a, b) return t[b].error < t[a].error end) do
print( x, y.count, y.error)
end
And that is all.