How do I build a constructor in Julia with fewer inputs than values? I have an Int64 array of numbers where each number represents 24 boolean values. The best situation would be that I could send in the array and get back a composite type with arrays of each component. Here is the code I've tried.
type Status
Valve1::Array{Bool}
Valve2::Array{Bool}
Valve3::Array{Bool}
Valve4::Array{Bool}
Valve5::Array{Bool}
Valve6::Array{Bool}
Valve7::Array{Bool}
Valve8::Array{Bool}
# Constructor for Status type
function Status(vals::Array{Int64})
l = int64(length(vals))
Valve1 = Array(Bool,l)
Valve2 = Array(Bool,l)
Valve3 = Array(Bool,l)
Valve4 = Array(Bool,l)
Valve5 = Array(Bool,l)
Valve6 = Array(Bool,l)
Valve7 = Array(Bool,l)
Valve8 = Array(Bool,l)
# Parse Inputs
for i=1:l
# Byte 1
Valve1[i] = vals[i] & 2^(1-1) > 0
Valve2[i] = vals[i] & 2^(2-1) > 0
Valve3[i] = vals[i] & 2^(3-1) > 0
Valve4[i] = vals[i] & 2^(4-1) > 0
Valve5[i] = vals[i] & 2^(5-1) > 0
Valve6[i] = vals[i] & 2^(6-1) > 0
Valve7[i] = vals[i] & 2^(7-1) > 0
Valve8[i] = vals[i] & 2^(8-1) > 0
end # End of conversion
new(Valve1,Valve2,Valve3,Valve4,Valve5,Valve6,Valve7,Valve8)
end # End of constructor
end # End of type
This results in a no method convert(Type{Bool},Array{Bool,1}) error. I tried to instantiate it with statuses = Status(StatusW) where StatusW is an Int64 array of values.
Useful references: Types and Constructors section of the Julia documentation
The declarations needs to be as follows.
Valve1::Vector{Bool}
Another factor contributing to my confusion was that new(Valve1,...) should be the last thing in the constructor. I had added debugging println()lines after the new(Valve1,...) causing the type to return Nothing.
Tim Holy on the Julia Google Groups forum provided the solution.
The full example should look like this.
type Status
Valve1::VectorBool}
Valve2::Vector{Bool}
Valve3::Vector{Bool}
Valve4::Vector{Bool}
Valve5::Vector{Bool}
Valve6::Vector{Bool}
Valve7::Vector{Bool}
Valve8::Vector{Bool}
# Constructor for Status type
function Status(vals::Array{Int64})
l = int64(length(vals))
Valve1 = Array(Bool,l)
Valve2 = Array(Bool,l)
Valve3 = Array(Bool,l)
Valve4 = Array(Bool,l)
Valve5 = Array(Bool,l)
Valve6 = Array(Bool,l)
Valve7 = Array(Bool,l)
Valve8 = Array(Bool,l)
# Parse Inputs
for i=1:l
# Byte 1
Valve1[i] = vals[i] & 2^(1-1) > 0
Valve2[i] = vals[i] & 2^(2-1) > 0
Valve3[i] = vals[i] & 2^(3-1) > 0
Valve4[i] = vals[i] & 2^(4-1) > 0
Valve5[i] = vals[i] & 2^(5-1) > 0
Valve6[i] = vals[i] & 2^(6-1) > 0
Valve7[i] = vals[i] & 2^(7-1) > 0
Valve8[i] = vals[i] & 2^(8-1) > 0
end # End of conversion
new(Valve1,Valve2,Valve3,Valve4,Valve5,Valve6,Valve7,Valve8)
end # End of constructor
end # End of type
The error message is correct, but unfortunately it is quite hard to understand the generic error messages in Julia.
The problem is that you declare your fields as the partially initialized Array{Bool, N}, and that does not seem to work when you try to call the constructor with Array{Bool, 1}.
The right solution is to declare the type to contain a fully initialized type Array{Bool,1} or use the alias Vector{Bool}.
What version of Julia are you using? The code you posted works for me on the latest Julia master, and I think this might have been fixed when https://github.com/JuliaLang/julia/issues/4026 solved.
Related
I am building a metaheuristic in Julia for study purpose.
The purpose is to find the best order of boxes.
1) I start with an initial order (random order) defined as. Order = InitOrder before my while loop.
2) For each iteration in the while loop I set CurrentOrder = Order
3) When the CurrentOrder is changed, Order changes too. Why does Order change value without being assigned? And how do I avoid it?
Version:
JuliaPro 1.0.2.1
Editor: Atom
while ( (time_ns()-timestart)/1.0e9 < RunLength && done == false ) #Stopping Criteria
done = true #Starting point
IterationCount = IterationCount + 1
BestCurrentValue = sum(H) #Worst case solutio
CurrentOrder = Order #(From,To)
for n1=1:N
for n2=1:N
if n1 != n2
(CurrentOrder,CopyTo) = SwapBox(CurrentOrder,n1,n2) #Swap boxes
(CurrentLayout,L) = DeltaCopy(CurrentLayout,CopyTo,CurrentOrder) #Delta Copy to minimise calculations
(TempLayout,L) = BLV(BinW,CurrentLayout,CopyTo,CurrentOrder,W,H,L) #Evalueate by BLV
if L < BestCurrentValue #check if TempLayout is better than Best Current
BestCurrentValue = L
BestCurrentOrder = CurrentOrder
BestCurrentLayout = CurrentLayout
end #if L<...
end #if n1 != n2
##############################################################################
CurrentOrder = Order
##############################################################################
end #n2 in N
end #n1 in N
if BestCurrentValue < BestValue
done = false #Look further
BestValue = BestCurrentValue
BestOrder = BestCurrentOrder
BestLayout = BestCurrentLayout
Order = BestOrder
end #if BestCurrentValue...
end #while
Your assignment NewOrder=Order does not copy any information in memory, it just says that the variable NewOrder should point to the same memory location as Order. Changing one of these variables will thus also change the other. If you want to copy a variable you could use NewOrder=deepcopy(Order)
I'm trying to parse http POST requests in Lua. My implementation works, but eats a hell lot of CPU load. This is critical, hence it is on an embedded platform.
I've looked on other implementations, but they can't fit, because my image is hardly fit in the memory, so I wouldn't use another library. I rolled my own parser, but it uses too much of system resource. Question is how could I optimize this to have lower CPU load.
This is an OpenWRT based system, so I only have Lua 5.1. This is the core function that looks for the boundary (in str variable). It reads the input block by block, and seeks for it.
The other solution would be to use LUCI libraries to do the heavy lifting, but I don't want my code to be integrated in LUCI.
--look for a pattern (str) and copy input until it is found to the output.
local function writeuntil(in_fp, str, out_fp)
local buff = ""
local ret = false
local bs = 4096 --Block size. The amount of data to read at once
local c = in_fp:read(bs)
local strStartPos = 1
while c do
local blockLen = string.len(c) --Not sure that a whole block is read, so get the size of the actual block.
local found = string.find(c, str, 1, true) --Try to locate str, so we don't have much work.
if (found ~= nil) then
if found > 2 then
out_fp:write(string.sub(c, 1, found - 1))
end
ret = true
break --we are done
else --Try to mach str till the end of the block
local strPos = string.find(c, string.sub(str, strStartPos, strStartPos), 1, true) --try to locate the first character
if strPos then --There is a starting character in the block
if (strPos > 1) then
out_fp:write(string.sub(c, 1, strPos - 1))
end
for i = strPos, blockLen do --iterate through the block
local ch = string.sub(c, i, i)
if ch == string.sub(str, strStartPos, strStartPos) then
buff = buff .. ch
if string.len(buff) == string.len(str) then
ret = true
break --We're done
end
strStartPos = strStartPos + 1
else --Lost track. Output.
if string.len(buff) > 0 then
out_fp:write(buff)
buff = ""
end
out_fp:write(ch)
strStartPos = 1
end
end
else
out_fp:write(c)
end
end
if ret then
break
end
c = in_fp:read(bs) --read next block
end
return ret
end
Egor, you were right, but I ended up this solution. It is now uses much less CPU. This not perfect hence scp is faster (although that is implemented in C).
--look for a pattern (str) and copy input until it is found to the output.
local function writeuntil(in_fp, str, out_fp)
local buff = ""
local ret = false
local bs = 4096 --Block size. The amount of data to read at once
local c = in_fp:read(bs)
local strStartPos = 1
local lastStrPos = 1
local needData = true
while c do
local blockLen = string.len(c) --Not sure that a whole block is read, so get the size of the actual block.
local found = string.find(c, str, 1, true) --Try to locate str, so we don't have much work.
if (found ~= nil) then
if found > 1 then
if #buff > 0 then
out_fp:write(buff)
end
out_fp:write(string.sub(c, 1, found - 1))
end
ret = true
break --we are done
else --Try to mach str till the end of the block
local strPos = string.find(c, string.sub(str, strStartPos, strStartPos), lastStrPos, true) --try to locate the first character
if strPos then --There is a starting character in the block
out_fp:write(string.sub(c, lastStrPos, strPos - 1))
for i = strPos, blockLen do --iterate through the block
local ch = string.sub(c, i, i)
if ch == string.sub(str, strStartPos, strStartPos) then
buff = buff .. ch
if string.len(buff) == string.len(str) then
ret = true
break --We're done
end
strStartPos = strStartPos + 1
lastStrPos = i + 1
else --Lost track. Output.
if string.len(buff) > 0 then
out_fp:write(buff)
buff = ""
end
out_fp:write(ch)
strStartPos = 1
if i == blockLen then
needData = true
else
lastStrPos = i + 1
needData = false
end
break
end
end
else
if ret == false then
if string.len(buff) > 0 then
out_fp:write(buff)
buff = ""
end
out_fp:write(string.sub(c, lastStrPos))
lastStrPos = 1
needData = true
else
break
end
end
end
if ret then
break
end
if needData then
c = in_fp:read(bs) --read next block
lastStrPos = 1
end
end
return ret
end
I'm trying to understand how to work with this package for Julia.
Im using the following code (is an example from the package):
using HttpServer
function fibonacci(n)
if n == 1 return 1 end
if n == 2 return 1 end
prev = BigInt(1)
pprev = BigInt(1)
for i=3:n
curr = prev + pprev
pprev = prev
prev = curr
end
return prev
end
http = HttpHandler() do req::Request, res::Response
m = match(r"^/fibo/(\d+)/?$",req.resource)
if m == nothing
return Response(404)
end
number = BigInt(m.captures[1])
if number < 1 || number > 100_000
return Response(500)
end
return Response(string(fibonacci(number)))
end
http.events["error"] = (client, err) -> println(err)
http.events["listen"] = (port) -> println("Listening on $port...")
server = Server(http)
run(server, 8031)
And trying to access to the server with this link:
http://localhost:8031/fibo/100
But i get the next error:
MethodError(convert,(BigInt,"100"))
ERROR: MethodError: Cannotconvert an object of type
SubString{String} to an object of type BigInt
What im doing wrong?
I have problems to figure out what r"^/fibo/(\d+)/? does, maybe there is my problem...
You get this error because method BigInt(s::AbstractString) is deprecated and was remove in julia 0.5. Use number = parse(BigInt,m.captures[1]) instead.
I am having trouble figuring out how to get the length of a matrix within a matrix within a matrix (nested depth of 3). So what the code is doing in short is... looks to see if the publisher is already in the array, then it either adds a new column in the array with a new publisher and the corresponding system, or adds the new system to the existing array publisher
output[k][1] is the publisher array
output[k][2][l] is the system
where the first [] is the amount of different publishers
and the second [] is the amount of different systems within the same publisher
So how would I find out what the length of the third deep array is?
function reviewPubCount()
local output = {}
local k = 0
for i = 1, #keys do
if string.find(tostring(keys[i]), '_') then
key = Split(tostring(keys[i]), '_')
for j = 1, #reviewer_code do
if key[1] == reviewer_code[j] and key[1] ~= '' then
k = k + 1
output[k] = {}
-- output[k] = reviewer_code[j]
for l = 1, k do
if output[l][1] == reviewer_code[j] then
ltable = output[l][2]
temp = table.getn(ltable)
output[l][2][temp+1] = key[2]
else
output[k][1] = reviewer_code[j]
output[k][2][1] = key[2]
end
end
end
end
end
end
return output
end
The code has been fixed here for future reference: http://codepad.org/3di3BOD2#output
You should be able to replace table.getn(t) with #t (it's deprecated in Lua 5.1 and removed in Lua 5.2); instead of this:
ltable = output[l][2]
temp = table.getn(ltable)
output[l][2][temp+1] = key[2]
try this:
output[l][2][#output[l][2]+1] = key[2]
or this:
table.insert(output[l][2], key[2])
I want to edit some legacy code written in classic-ASP.
Currently I've got a subroutine declared that uses a for-next loop to output some radio buttons:
For i = 1 to Cols
response.write "blah"
...
Next
i is simply a counter, Cols is a value passed to the sub-routine. I tried editing the for-loop to be a while loop instead:
i = Start
do while i <= Cols
response.write "blah"
...
i = i + 1
loop
But I get a Response Buffer Limit Exceeded error. If I replace Cols with the value it works fine. Is this a limitation in classic-ASP?
Reason I want to use a do while loop is because currently the sub-routine is limited to looping from 1 to Cols. It would be helpful to sometimes specify the loop counts backwards (i.e. step -1) but I can't write:
if Direction = Backwards then
For i = Cols to 1 step -1
else
For i = 1 to Cols
end if
How about:
If Direction = Backwards Then
cs = 10
ce = 1
s = -1
Else
cs = 1
ce = 10
s = 1
End If
For i = cs To ce Step s
''
Next