Julia IntervalTrees.jl Create IntervalMap that maps to Array - julia

I wanna create something like this, just as explained on here.
using IntervalTrees
# Create an interval tree mapping (Int, Int) intervals to Strings.
xs = IntervalMap{Int, ASCIIString}()
# Insert values
xs[(1,100)] = "Low"
xs[(101,1000)] = "Medium"
xs[(1001,10000)] = "High"
# Search for values
println(xs[(1001,10000)]) # prints "High"
# Get a value, returning a default value if not found
println(get(xs, (10001, 100000), "Not found")) # prints "Not found"
# Set a value if it's not already present
println(set(xs, (10001, 100000), "Not found"))
# Delete values
delete!(xs, (1,100))
However instead on mapping to String. I want to map to an Array. So I tried something like this.
intmap = IntervalMap{Int, Array{SubString{String},1}}
but this returns:
ERROR: LoadError: MethodError: no method matching setindex!(::Type{IntervalTrees.IntervalBTree{Int64,IntervalTrees.IntervalValue{Int64,Array{SubString{String},1}},64}}, ::Array{SubString{String},1}, ::Tuple{SubString{String},SubString{String}})
Is there even a way to achieve this?

Related

ERROR: type Nullable has no field name Julia

in array i have Object , created by two constructors
type Node
name::AbstractString
value::Int
left::Nullable{Node}
right::Nullable{Node}
Node(name::AbstractString, value::Int) = new(name, value, Nullable{Node}(), Nullable{Node}())
Node(name::AbstractString, value::Int, left::Node, right::Node) = new(name, value, left, right)
end
When I try to get to the nodes[1].right.name I get an error like in topic , but i'm sure is there an Object
nodes[1]
Node("New",15,Nullable(Node("bb",7,Nullable{Node}(),Nullable{Node}())),Nullable(Node("cc",8,Nullable{Node}(),Nullable{Node}())))
How can i fix it ?
Edit i type my whole code
A = [Node("aa", 11) , Node("bb", 7), Node("cc", 8), Node("d", 11)]
function HuffmanNodes(nodes::Vector{Node})
while(length(nodes) > 1)
left = minimal(nodes)
Left = nodes[left[1]]
deleteat!(nodes, left)
right = minimal(nodes)
Right = nodes[right[1]]
deleteat!(nodes, right)
top = Node("New",Left.value+Right.value, Left, Right)
println(top)
push!(nodes, top)
printNodes(top, " ")
end
end
And methods in HuffmanNodes function
function printNodes(node::Node, str::AbstractString)
if(node.name != "New")
string(node.name, str)
println(string)
end
printNodes(node.left.name , string(str , " 0")
printNodes(node.right.name , string(str, " 1")
end
function minimal(nodes::Vector{Node})
minnode = Nullable{Node}()
minnode = nodes[1]
minval = nodes[1].value
for f in nodes
println(f)
if f.value < minval
minval = f.value
minnode = f
end
end
return find(nodes .==minnode)
end
And i trying call HuffmanCode(A) and then i get error , i tried with get(node.right).name , but it is not wokring
Can you provide a minimum working example? From the code you posted I'm not able to create the Node you're trying to access, and I don't really understand what you're trying to do.
In any case, nodes[1].right is of type Nullable, it's not the node (which would have a name attribute). According to the docs, you should access the value of the Nullable object using get(), i.e. get(nodes[1].right)
You should use the REPL (i.e. the Julia terminal) to explore the objects you are creating. Here is a sample session after defining the Node type like you did, exactly as I wrote it in the terminal as I was exploring the Node objects.
In the future, please report exactly what you type and exactly the resulting error, just by copying and pasting as I did here, and make your example as simple as possible without extra detail that does not matter.
julia> type Node
name::AbstractString
value::Int
left::Nullable{Node}
right::Nullable{Node}
Node(name::AbstractString, value::Int) = new(name, value, Nullable{Node}(), Nullable{Node}())
Node(name::AbstractString, value::Int, left::Node, right::Node) = new(name, value, left, right)
end
julia> nodes = [Node("a", 1), Node("a", 2)]
2-element Array{Node,1}:
Node("a",1,Nullable{Node}(),Nullable{Node}())
Node("a",2,Nullable{Node}(),Nullable{Node}())
julia> nodes[1]
Node("a",1,Nullable{Node}(),Nullable{Node}())
julia> nodes[1].right
Nullable{Node}()
julia> get(nodes[1].right)
ERROR: NullException()
in get at nullable.jl:30
julia> nodes[1].right = Node("c", 3)
Nullable(Node("c",3,Nullable{Node}(),Nullable{Node}()))
julia> get(nodes[1])
ERROR: MethodError: `get` has no method matching get(::Node)
julia> get(nodes[1].right)
Node("c",3,Nullable{Node}(),Nullable{Node}())
julia> n = get(nodes[1].right)
Node("c",3,Nullable{Node}(),Nullable{Node}())
julia> n.name
"c"

GAE - When adding two floats whose sum is over 1000, the sum is changed to the thousands value

This was an administrative issue. It was claimed that it was our fault, and our code was broken, when the issue was elsewhere in different code that can update what ours imports. So, this is a non-problem.
We are adding to values together that are in a dictionary and storing them in a variable to then be added to the NDB datastore.
Essentially, we are importing a csv and parsing the data. If the sum of two of the values is greater than 1,000.00, the float is changed to the thousands value.
Examples:
1263.13 would change to 1
51367.42 would change to 51
218.12 would be unchanged (218.12)
We think it is an issue with storing the data, but we are having trouble reproducing the the issue, and have verified that with a small amount of data, there will be "false positives". IE: there not being an issue.
Reading csv from blob:
blob_reader = blobstore.BlobReader(blob_info.key())
raw_blob = blob_reader.read()
result = [row for row in csv.DictReader(StringIO.StringIO(raw_blob), delimiter=',')]
# loop through all rows in the data/csv
for v, row in enumerate(result):
if set_data_type(row, v) == False:
return False
else:
length = len(result) + 1
# check values for type
if check_values(row, v, length) == False:
return False
else:
# calculate numerical data for storage
calculate_vars(row, v)
if not error_log:
# if no errors, store the row in the datastore
store_data(row, v)
# if there are no errors, add to transaction log.
if not error_log:
added_records = len(result)
old_new = "Upload Success - " + str(added_records) + " records added."
transactions(module, 'Datastore', data[0], 'CSV Bulk Upload', old_new, old_new)
Calculating values:
def calculate_vars(row, v):
# calcuate values for storage based on
# data passed from the csv
try:
float_sum = float(row['float1']) + float(row['float2'])
except Exception, e:
catch_error(["Value calculation error in row ", v+1, " Error: ", e])
return False
else:
# global var
calculated_val = float_sum
Storing Value:
def store_data(row, v):
try:
entry = Datastore(
float_sum = calculated_val
)
except Exception, e:
catch_error(["StoreDataError in row ", v, e])
return False
else:
# add entry to datastore.
entry.put()
The Datastore column 'float_sum' is an ndb.FloatProperty()
What we're trying to figure out is: what could cause the floats to be truncated to the thousands digits and nothing else when the number is larger than 1,000. Obviously, we are aware that adding two floats together will not cause this normally, which is why we think it could be an issue with the datastore itself.

filling an array recursively in R language

I have a multidimensional array (B_matrix) that I need to fill up with some random values. Since the dimension depends on two parameters K and C that are user defined, I cannot use nested loop to fill the array, so I have decided to fill it up recursively.
The problem with the recursion function (fillUp) is that that even though the array is declared outside the function, the array is set to NULL after the function is run.
B_dim = rep(2,((K+1+C)*2))
B_matrix = array( dim = B_dim, dimnames = NULL)
string = c()
fillUp<-function(level, string ){
if (level>=1){
for(i in c(1,2)){
Recall(level-1, c(string, i))
}
}else{
B_matrix[string] = 1;
}
}
fillUp(length(B_dim), string)
> sum( B_matrix == 1)
[1] NA
I'm new to R, so I'm not sure if the "global" declaration allows fillUp to change the values of the matrix.
Edit:
Note that the line
B_matrix[string] = 1;
is just a test case, and the original idea is to assign some random value that depends of the position of the array element.
Edit2:
Based on what #Bridgeburners hinted, I'm almost there. Replacing B_matrix[string] = 1, by
assign('str', matrix(string,1), envir=.GlobalEnv)
assign('hl', B_half_length, envir=.GlobalEnv)
rul <-runif(1, 0, sum(str[1:hl]))
with( .GlobalEnv,B_matrix[str] <- rul)
I get the error (last line):
Error in eval(expr, envir, enclos) : object 'rul' not found
The problem, I guess, is that I'm working with variables from two different environments at the same time. I don't know how to proceed here.
This option doesn't work either
assign('str',matrix(string,1), envir=.GlobalEnv)
assign('hl', B_half_length, envir=.GlobalEnv)
assign('ru', runif(1, 0, sum(str[1:hl])), envir=.GlobalEnv)
with( .GlobalEnv,B_matrix[str] <- ru)
Note: no visible binding for global variable 'ru'
Edit3:
I've finally solved it:
assign('str',matrix(string,1), envir=.GlobalEnv)
with( .GlobalEnv, B_matrix[str] <- runif(1, 0, sum(str[1:B_half_length])-B_half_length+1) )
where B_half_length is a global variable
Whenever a process is working within a function, it's working in a different environment. The object "B_matrix" is defined in the global environment. Since you're nesting environments (2*(K+C+1) times) you're not impacting the original object. If you simply replace line
B_matrix[string] = 1;
with
assign('str', matrix(string,1), envir=.GlobalEnv)
with(.GlobalEnv,B_matrix[str] <- 1)
your code will work. You simply need to specify which environment your expression is working in. (In the first line you're passing the local value of "string" to a global object named "str".)
Note, also, that indexing an array with a vector doesn't work.
That is, "B_matrix[2,2,2,2,2,2]" is not the same as "B_matrix[c(2,2,2,2,2,2)]".
But it works with a matrix
What you want can be achieved with the following line code once you have initialised you B_matrix array:
B_matrix[] <- runif(length(B_matrix))

Partial matching confusion when arguments passed through dots ('...')

I've been working on an R package that is just a REST API wrapper for a graph database. I have a function createNode that returns an object with class node and entity:
# Connect to the db.
graph = startGraph("http://localhost:7474/db/data/")
# Create two nodes in the db.
alice = createNode(graph, name = "Alice")
bob = createNode(graph, name = "Bob")
> class(alice)
[1] "node" "entity"
> class(bob)
[1] "node" "entity"
I have another function, createRel, that creates a relationship between two nodes in the database. It is specified as follows:
createRel = function(fromNode, type, toNode, ...) {
UseMethod("createRel")
}
createRel.default = function(fromNode, ...) {
stop("Invalid object. Must supply node object.")
}
createRel.node = function(fromNode, type, toNode, ...) {
params = list(...)
# Check if toNode is a node.
stopifnot("node" %in% class(toNode))
# Making REST API calls through RCurl and stuff.
}
The ... allows the user to add an arbitrary amount of properties to the relationship in the form key = value. For example,
rel = createRel(alice, "KNOWS", bob, since = 2000, through = "Work")
This creates an (Alice)-[KNOWS]->(Bob) relationship in the db, with the properties since and through and their respective values. However, if a user specifies properties with keys from or to in the ... argument, R gets confused about the classes of fromNode and toNode.
Specifying a property with key from creates confusion about the class of fromNode. It is using createRel.default:
> createRel(alice, "KNOWS", bob, from = "Work")
Error in createRel.default(alice, "KNOWS", bob, from = "Work") :
Invalid object. Must supply node object.
3 stop("Invalid object. Must supply node object.")
2 createRel.default(alice, "KNOWS", bob, from = "Work")
1 createRel(alice, "KNOWS", bob, from = "Work")
Similarly, if a user specifies a property with key to, there is confusion about the class of toNode, and stops at the stopifnot():
Error: "node" %in% class(toNode) is not TRUE
4 stop(sprintf(ngettext(length(r), "%s is not TRUE", "%s are not all TRUE"),
ch), call. = FALSE, domain = NA)
3 stopifnot("node" %in% class(toNode))
2 createRel.node(alice, "KNOWS", bob, to = "Something")
1 createRel(alice, "KNOWS", bob, to = "Something")
I've found that explicitly setting the parameters in createRel works fine:
rel = createRel(fromNode = alice,
type = "KNOWS",
toNode = bob,
from = "Work",
to = "Something")
# OK
But I am wondering how I need to edit my createRel function so that the following syntax will work without error:
rel = createRel(alice, "KNOWS", bob, from = "Work", to = "Something")
# Errors galore.
The GitHub user who opened the issue mentioned it is most likely a conflict with setAs on dispatch, which has arguments called from and to. One solution is to get rid of ... and change createRel to the following:
createRel = function(fromNode, type, toNode, params = list()) {
UseMethod("createRel")
}
createRel.default = function(fromNode, ...) {
stop("Invalid object. Must supply node object.")
}
createRel.node = function(fromNode, type, toNode, params = list()) {
# Check if toNode is a node.
stopifnot("node" %in% class(toNode))
# Making REST API calls through RCurl and stuff.
}
But, I wanted to see if I had any other options before making this change.
Not really an answer, but...
The problem is that the user-provided argument 'from' is being (partially) matched to the formal argument 'fromNode'.
f = function(fromNode, ...) fromNode
f(1, from=2)
## [1] 2
The rules are outlined in section 4.3.2 of RShowDoc('R-lang'), where named arguments are exact matched, then partial matched, and then unnamed arguments are assigned by position.
It's hard to know how to enforce exact matching, other than using single-letter argument names! Actually, for a generic this might not be as trite as it sounds -- x is a pretty generic variable name. If 'from' and 'to' were common arguments to ... you could change the argument list to "fromNode, , ..., from, to", check for missing(from) in the body of the function, and act accordingly; I don't think this would be pleasant, and the user would invariable provide an argument 'fro'.
While enforcing exact matching (and errors, via warn=2) by setting global options() might be helpful in debugging (though by then you'd probably know what you were looking for!) it doesn't help the package author who is trying to write code to work for users in general.
It might be reasonable to ask on the R-devel mailing list whether it might be time for this behavior to be changed (on the 'several releases' time scale); partial matching probably dates as a 'convenience' from the days before tab completion.

How do you use matrices in Nimrod?

I found this project on GitHub; it was the only search term returned for "nimrod matrix". I took the bare bones of it and changed it a little bit so that it compiled without errors, and then I added the last two lines to build a simple matrix, and then output a value, but the "getter" function isn't working for some reason. I adapted the instructions for adding properties found here, but something isn't right.
Here is my code so far. I'd like to use the GNU Scientific Library from within Nimrod, and I figured that this was the first logical step.
type
TMatrix*[T] = object
transposed: bool
dataRows: int
dataCols: int
data: seq[T]
proc index[T](x: TMatrix[T], r,c: int): int {.inline.} =
if r<0 or r>(x.rows()-1):
raise newException(EInvalidIndex, "matrix index out of range")
if c<0 or c>(x.cols()-1):
raise newException(EInvalidIndex, "matrix index out of range")
result = if x.transposed: c*x.dataCols+r else: r*x.dataCols+c
proc rows*[T](x: TMatrix[T]): int {.inline.} =
## Returns the number of rows in the matrix `x`.
result = if x.transposed: x.dataCols else: x.dataRows
proc cols*[T](x: TMatrix[T]): int {.inline.} =
## Returns the number of columns in the matrix `x`.
result = if x.transposed: x.dataRows else: x.dataCols
proc matrix*[T](rows, cols: int, d: openarray[T]): TMatrix[T] =
## Constructor. Initializes the matrix by allocating memory
## for the data and setting the number of rows and columns
## and sets the data to the values specified in `d`.
result.dataRows = rows
result.dataCols = cols
newSeq(result.data, rows*cols)
if len(d)>0:
if len(d)<(rows*cols):
raise newException(EInvalidIndex, "insufficient data supplied in matrix constructor")
for i in countup(0,rows*cols-1):
result.data[i] = d[i]
proc `[][]`*[T](x: TMatrix[T], r,c: int): T =
## Element access. Returns the element at row `r` column `c`.
result = x.data[x.index(r,c)]
proc `[][]=`*[T](x: var TMatrix[T], r,c: int, a: T) =
## Sets the value of the element at row `r` column `c` to
## the value supplied in `a`.
x.data[x.index(r,c)] = a
var m = matrix( 2, 2, [1,2,3,4] )
echo( $m[0][0] )
This is the error I get:
c:\program files (x86)\nimrod\config\nimrod.cfg(36, 11) Hint: added path: 'C:\Users\H127\.babel\libs\' [Path]
Hint: used config file 'C:\Program Files (x86)\Nimrod\config\nimrod.cfg' [Conf]
Hint: system [Processing]
Hint: mat [Processing]
mat.nim(48, 9) Error: type mismatch: got (TMatrix[int], int literal(0))
but expected one of:
system.[](a: array[Idx, T], x: TSlice[Idx]): seq[T]
system.[](a: array[Idx, T], x: TSlice[int]): seq[T]
system.[](s: string, x: TSlice[int]): string
system.[](s: seq[T], x: TSlice[int]): seq[T]
Thanks you guys!
I'd like to first point out that the matrix library you refer to is three years old. For a programming language in development that's a lot of time due to changes, and it doesn't compile any more with the current Nimrod git version:
$ nimrod c matrix
...
private/tmp/n/matrix/matrix.nim(97, 8) Error: ']' expected
It fails on the double array accessor, which seems to have changed syntax. I guess your attempt to create a double [][] accessor is problematic, it could be ambiguous: are you accessing the double array accessor of the object or are you accessing the nested array returned by the first brackets? I had to change the proc to the following:
proc `[]`*[T](x: TMatrix[T], r,c: int): T =
After that change you also need to change the way to access the matrix. Here's what I got:
for x in 0 .. <2:
for y in 0 .. <2:
echo "x: ", x, " y: ", y, " = ", m[x,y]
Basically, instead of specifying two bracket accesses you pass all the parameters inside a single bracket. That code generates:
x: 0 y: 0 = 1
x: 0 y: 1 = 2
x: 1 y: 0 = 3
x: 1 y: 1 = 4
With regards to finding software for Nimrod, I would like to recommend you using Nimble, Nimrod's package manager. Once you have it installed you can search available and maintained packages. The command nimble search math shows two potential packages: linagl and extmath. Not sure if they are what you are looking for, but at least they seem more fresh.

Resources