How to get tuples in gremlin? - titan

How can I get Gremlin return a tuple. I want to get 2 attributes from vertices at a time and then sort these tuples on one of the attributes. How can I do that.
Also how can analytics be applied to titan graphs....

For the first part of your question regarding tuples - just transform to a two (or more) item list of your properties:
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V.has('age').transform{[it.name,it.age]}
==>[marko, 29]
==>[vadas, 27]
==>[josh, 32]
==>[peter, 35]
then to sort, just use order step and pick the item in the tuple to order by...in this case "name":
gremlin> g.V.has('age').transform{[it.name,it.age]}.order{it.a[0]<=>it.b[0]}
==>[josh, 32]
==>[marko, 29]
==>[peter, 35]
==>[vadas, 27]
and in this case "age":
gremlin> g.V.has('age').transform{[it.name,it.age]}.order{it.a[1]<=>it.b[1]}
==>[vadas, 27]
==>[marko, 29]
==>[josh, 32]
==>[peter, 35]

Related

Get all vertices with a specific property, label and id along the path

I have following structure in a Janusgraph database:
gremlin> continent = g.addV("continent").property("name", "Europe").next()
gremlin> country = g.addV("country").property("name", "France").next()
gremlin> region = g.addV("region").property("name", "Ile-de-France").next()
gremlin> departement = g.addV("departement").property("name", "Hauts-de-Seine").next()
gremlin> city = g.addV("city").property("name", "Saint-Cloud").next()
gremlin> g.V(continent).addE('is_part_of').to(country).iterate()
gremlin> g.V(country).addE('is_part_of').to(region).iterate()
gremlin> g.V(region).addE('is_part_of').to(departement).iterate()
gremlin> g.V(departement).addE('is_part_of').to(city).iterate()
I did to get the property name from all vertices from city to continent from the following query:
gremlin> g.V(city).emit().repeat(inE("is_part_of").outV().simplePath()).path().unfold().dedup().values("name")
==>Saint-Cloud
==>Hauts-de-Seine
==>Ile-de-France
==>France
==>Europe
But I would like to get also the id and the label of every returned vertex.
I tried to use valueMap(true) instead of values("name") step to get all properties including id and label, but big part of vertices contain lot of properties which could be heavy in the level of performance.
Is it possible to get those values from each vertex?
You could just do valueMap(true, 'name')
gremlin> g.V(city).emit().repeat(inE("is_part_of").outV().simplePath()).
......1> path().
......2> unfold().
......3> dedup().
......4> valueMap(true,'name')
==>[id:8,label:city,name:[Saint-Cloud]]
==>[id:13,label:is_part_of]
==>[id:6,label:departement,name:[Hauts-de-Seine]]
==>[id:12,label:is_part_of]
==>[id:4,label:region,name:[Ile-de-France]]
==>[id:11,label:is_part_of]
==>[id:2,label:country,name:[France]]
==>[id:10,label:is_part_of]
==>[id:0,label:continent,name:[Europe]]

Count the number of times an object appears in an array in matlab

I have two classes, Good and Market. Every class has its properties. They are as follows
classdef market< handle
properties
name
goods=good.empty
budget=0
end
methods
function obj=market(val1)
obj.name=val1;
end
function buy(obj, item)
obj.goods(end+1)=item;
end
function sell(obj,item,quantity)
obj.goods=obj.goods(obj.goods~=item);
end
function list=l(obj)
list={obj.goods.name;obj.goods.price1;obj.goods.price2};
end
end
end
Good
classdef good
properties
name
price1
price2
quantity
end
methods
function obj=good(val1,val2,val3)
obj.name=val1;
obj.price1=val2;
obj.price2=val3;
end
end
end
Everytime I call the method buy, a new item is added to my goods in market. For example if I have 2 goods, good1 ang good2, after 9 times buying them, I have the following result
Columns 1 through 6
'Cheese' 'Eggs' 'Cheese' 'Cheese' 'Cheese' 'Cheese'
[ 10] [ 20] [ 10] [ 10] [ 10] [ 10]
[ 20] [ 30] [ 20] [ 20] [ 20] [ 20]
Columns 7 through 9
'Cheese' 'Eggs' 'Eggs'
[ 10] [ 20] [ 20]
[ 20] [ 30] [ 30]
Cheese correpsonds to good1. Eggs corresponds to good2.
How can I sum all the good1 and all the good2 that I have? the function numel(good1) returns ans=1 which is wrong.
I have a property quantity in my goods. After summing up the results how can I have another array of my goods with their corresponding quantities?
The result of accessing a field of an object array is a comma-separated list. Thats why numel does not work as you suppose. To receive an array you should enclose the list in braces or parentheses:
names={m.goods.name}
prices1=[m.goods.price1]
Now names is the cell array, containing all the fields name of m, prices1 contains fields price1. In order to find the elements, containing Eggs, we can now use strcmp:
e= strcmp(names,'Eggs')
The number of Eggs fields is the number of ones in e. Lets count them:
eggs_num= sum(e)
And now we can sum up the price1 fields of the elements that we have found:
sum(prices1(e))

Sorting By Excel Headers in MATLAB (High Level I/O)

Alright, so I feel like this should be a pretty simple problem, but I'm already struggling with it. Which is bad since I have a test next week and I barely understand half the stuff we need to know. that, however, is besides the point. What I need to do is write a function that takes in an Excel file and a Header (which will be a string we input). It then finds the Header in the file and sorts it (in alphabetical order if the column consists of characters or ascending if it has numbers).
Input:
Test Case:
scores = sortByHeader(x, 'Opponent');
scores => 'Opponent' 'Tech Points' 'Opponent Points'
'Clemson' [ 30] [ 27]
'Clemson' [ 39] [ 34]
'Duke' [ 49] [ 10]
'Florida State' [ 49] [ 44]
'Georgia' [ 24] [ 30]
'Iowa' [ 14] [ 24]
'Jacksonville State' [ 37] [ 17]
'Miami' [ 17] [ 33]
'Mississippi State' [ 42] [ 31]
'North Carolina' [ 24] [ 7]
'Vanderbilt' [ 56] [ 31]
'Virginia' [ 34] [ 9]
'Virginia Tech' [ 28] [ 23]
'Wake Forest' [ 30] [ 27]
I am mostly having trouble figuring out how to identify the header in the problem. So far I Have:
function[scores] = sortByHeader(File, Name)
[num, txt, raw] = xlsread(File); %// Reads in the file
%// Gives me the dimensions of the file
[r,c] = size(raw);
%// I want to look through all of the columns until I find the header I need
for i = 1:c
%// I'm attempting to search through the file here
if strcmp(raw(1, i), Name)
%// Here's my issue. When it finds the name, I am not sure what to do with it then
Name_Column = 1;
end
%// I tried to mask it, but this doesn't actually work.
raw(Name_Column) = raw;
%// How I plan to sort everything once I find it. Though I believe I need to adjust this slightly to solely account for the 'Name' Column.
scores = sort(raw, 'ascend');
I mostly need tips at this point. I should probably work on figuring this stuff out on my own, but that's easier said than done. Note: The headers will not always be in the same place and there can be any number of rows or columns.
Conveniently, the headers will always be in the first row of the variable 'raw' as you have defined above.
headerMatch = strcmp(raw, Name);
whichColumn = find(headerMatch(1,:));
This will return a logical array headerMatch with a 1 in the location of a match to your string, Name, and whichColumn will return the column number, since we're only looking in the first row.
Then it's a matter of pulling out the column you identified with those commands and sorting it, which is where you struggled before. There are a couple of ways to address cell arrays and it can seem inconsistent, but it comes down to what you want as the output. If you want a cell array that is a sub-section of your current array back, use parenthesis like you use for matrix addressing. If you are trying to get at the values inside the cells that you are addressing, use curly braces. See the difference in how you pull out a cell array of strings or the values to make a vector in the two sort calls below. The sort command is a little different for a cell array of strings vs a vector of numbers so that's why there are two different calls with two different argument formats. Just have to check which one you're dealing with first, then pass to the appropriate sort function.
if ischar(raw{2, whichColumn}) % ischar checks if the first cell we want to sort has numbers or letters in it
sortedColumn = sort(raw(2:end, whichColumn)); % Sort a cell array of strings
else
sortedColumn = sort(vertcat(raw{2:end, whichColumn}), 'ascend'); % Sort a vector of numbers
end
Edit: To return the entirety of the spreadsheet data (without headers) sorted by a given column, specified by the header name, pull out the column index as above (the whichColumn variable). Then use the 'sortrows' command to sort the cell array of spreadsheet data by that column.
sortedMatrix = sortrows(raw(2:end, :), whichColumn);

Changing filtered values in a nested list

I have a nested list, in which each sublist is structured as follows: [[xcor ycor] weight].
Each tick I'd like to update the weight in a sample of these sublists.
I produce the sample (e.g. of size 2) from the nested list total using the Rnd extension (and very helpful answers/comments):
set total [ [[0 1] 1] [[2 3] 2] [[4 5] 3] [[6 7] 4] [[0 1] 1] ]
set sample rnd:weighted-n-of 2 total [ last ? ]
Then I update the weights in the sample (let's say multiplying them by 2) and map them to their respective [xcor ycor]-pair.
let newWeights (map [last ? * 2] sample)
let updatedSample (map list (map [first ?] sample) newWeights)
How can I then replace those entries in total, bearing in mind that it may hold duplicate entries?
This seems to be the perfect job for replace-item, but I don't know how to construct an appropriate index and then pass the respective value from updatedSample.
This is a great problem. The data structure you're using is known as an association list, or alist for short, where the keys are [xcor ycor] and the values are weights. Given your task, it's better to use the keys to look things up rather than indices. Thus, replace-item doesn't really help here. Instead, we can run map on total, using the values from updatedSample if they're there, and defaulting to the values in total. First, we need a convenience function to look things up in the alists. In lisp (a language which influenced NetLogo), this is called assoc. Here it is:
to-report assoc [ key alist ]
foreach alist [ if key = (first ?) [ report ? ] ]
report false
end
Notice that false is returned if alist doesn't contain the key. We want to use the entry returned by this function if it's not false, otherwise use something else. Thus, we need another helper function:
to-report value-or-else [ value default ]
report ifelse-value (value = false) [ default ] [ value ]
end
Finally, we can write a function that does the mapping:
to-report update-alist [ alist updated-entries ]
report map [ value-or-else (assoc first ? updated-entries) ? ] alist
end
Here's it in action:
observer> show update-alist [[[0 1] 1] [[2 3] 2] [[4 5] 3] [[6 7] 4] [[0 1] 1]] [[[0 1] 10] [[4 5] 45]]
observer: [[[0 1] 10] [[2 3] 2] [[4 5] 45] [[6 7] 4] [[0 1] 10]]
You would want to call it like update-alist total updatedSample.

NetLogo : How to do multiple operations on lists (find, get , replace, remove , search elements within lists , ....)

I am new to NetLogo and I was wondering if there is a complete reference to do operations on lists, I have read most of the posts here in addition to Netlogo dictionary but for example if I need a list of pairs of numbers like
[[1 2] [2 2] [2 3] ,,, ]
when I search
member? 3 thislist
Will I have the option to say which element of inner list I am considering for the search ? for instance I will get false if it search first element and true if I search second element.
Can anybody please clarify the use of lists in Netlogo?
map, filter, reduce, foreach, n-values, and sort-by provide customizable operations on lists, using tasks. See http://ccl.northwestern.edu/netlogo/docs/programming.html#tasks.
Here's your example using map:
observer> show member? 3 map first [[1 2] [2 2] [2 3]]
observer: false
observer> show member? 3 map last [[1 2] [2 2] [2 3]]
observer: true
It appears Seth answered your initial question. To answer your follow up question on changing an item, you can use replace-item See: http://ccl.northwestern.edu/netlogo/docs/dictionary.html#listsgroup
or use map. Below is an example replacing the first item with a -99 if the second item is 3:
let aList [[1 2] [2 2] [2 3] [4 4] [5 3]]
set aList map [(list ifelse-value (item 1 ? = 3) [-99][item 0 ?] item 1 ?)] aList