SHARE
TWEET

GraphsLibHelperFunctions.jl

BenjaminLind May 10th, 2014 216 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #####
  2. ### The code below is written by Benjamin Lind under CC: BY-NC-SA 3.0
  3. ### If you use or develop this code, please provide proper attribution.
  4. ### You may contact me at lind.benjamin//at//gmail//d0t//com
  5. ### You may also find me @benjaminlind on Twitter
  6. #####
  7.  
  8. using Graphs
  9.  
  10. #####
  11. ### Convenient helper functions for the Graphs library in the language of Julia
  12. ### These do not call on any other library and are written entirely in Julia
  13. ### For more information on the library, see: graphsjl-docs.readthedocs.org/en/
  14. #####
  15.  
  16. ### To load these functions:
  17. ## download("http://pastebin.com/raw.php?i=hcRJmCPH", "GraphsLibHelperFunctions.jl"); include("GraphsLibHelperFunctions.jl"); rm("GraphsLibHelperFunctions.jl")
  18.  
  19.  
  20. ### el_2_graph converts an edgelist to a GenericGraph type
  21. ## They vary based upon string or integer inputs.
  22. ## They can accept the number of vertices or vertex names are supplied.
  23. ## If the number of vertices or names are not supplied, then the information is inferred from the edgelist
  24.  
  25. function el_2_graph(n::Int, el::Array{Int, 2}; directed::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  26.     # _n_ refers to the number of vertices in the graph
  27.     # _el_ is an integer only edgelist
  28.  
  29.     vertexnames = [el[:,1], el[:,2]]
  30.     vertexnames = unique(vertexnames)
  31.     if (minimum(vertexnames) < 1) | (n < 1)
  32.         error("The number of vertices ('n') and the vertex indices must be greater than or equal to 1.")
  33.     end
  34.     n = ifelse(maximum(vertexnames) > n, maximum(vertexnames), n)
  35.     ne = size(el, 1)
  36.     if vtype == KeyVertex
  37.         vlist = Array(vtype{Int}, n)
  38.         for i = 1:n
  39.             vlist[i] = vtype(i, i)
  40.         end
  41.     elseif vtype == ExVertex
  42.         vlist = Array(vtype, n)
  43.         for i = 1:n
  44.             vlist[i] = vtype(i, string(i))
  45.         end        
  46.     else
  47.         error("'vtype' must be either KeyVertex or ExVertex")
  48.     end
  49.     elist = Array(etype{typeof(vlist[1])}, ne)
  50.     for i = 1:ne
  51.         elist[i] = etype(i, vlist[el[i, 1]], vlist[el[i, 2]])
  52.     end
  53.     return graph(vlist, elist, is_directed = directed)
  54. end
  55.  
  56. function el_2_graph(el::Array{Int, 2}; directed::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  57.     # _el_ is an integer only edgelist
  58.  
  59.     vertexnames = [el[:,1], el[:,2]]
  60.     vertexnames = unique(vertexnames)
  61.     n = maximum(vertexnames)
  62.     return el_2_graph(n, el; directed = directed, vtype = vtype, etype = etype)
  63. end
  64.  
  65. function el_2_graph(v::Array{String, 1}, el::Array{String, 2}; directed::Bool = true, label::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  66.     # _v_ is a list of vertex "names"
  67.     # _el_ is an edgelist of vertex "names"
  68.  
  69.     v = unique(v) #In case of double entries
  70.     vertexnames = [el[:,1], el[:,2]]
  71.     vertexnames = unique(vertexnames)
  72.     for i = 1:length(vertexnames)
  73.         if in(vertexnames[i], v) == false
  74.             vunnamed = vertexnames[i]
  75.             warn("Vertex $vunnamed appears in the edge list 'el' but not in the vertex list 'v'. Including $vunnamed in 'v'.")
  76.             push!(v, vunnamed)
  77.         end
  78.     end
  79.     n = length(v)
  80.     ne = size(el, 1)
  81.     if label
  82.         if vtype == KeyVertex
  83.             vlist = Array(vtype{typeof(v[1])}, n)
  84.         elseif vtype == ExVertex
  85.             vlist = Array(vtype, n)
  86.         else
  87.             error("'vtype' must be either KeyVertex or ExVertex")
  88.         end
  89.         for i = 1:n
  90.             vlist[i] = vtype(i, v[i])
  91.         end
  92.     else
  93.           if vtype == KeyVertex
  94.               vlist = Array(vtype{Int}, n)
  95.               for i = 1:n
  96.                   vlist[i] = vtype(i, i)
  97.               end
  98.           elseif vtype == ExVertex
  99.               vlist = Array(vtype, n)
  100.               for i = 1:n
  101.                   vlist[i] = vtype(i, string(i))
  102.               end  
  103.           else
  104.               error("'vtype' must be either KeyVertex or ExVertex")
  105.           end
  106.     end
  107.     elist = Array(etype{typeof(vlist[1])}, ne)
  108.     for i = 1:ne
  109.         elist[i] = etype(i, vlist[findin([v], [el[i, 1]])[1]], vlist[findin([v], [el[i, 2]])[1]])
  110.     end
  111.     return graph(vlist, elist, is_directed = directed)    
  112. end
  113.  
  114. function el_2_graph(el::Array{String, 2}; directed::Bool = true, label::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  115.     # _el_ is an edgelist of vertex "names"
  116.     v = unique([el[:,1], el[:,2]])
  117.     return el_2_graph(v, el, directed = directed, label = label, vtype = vtype, etype = etype)    
  118. end
  119.  
  120. function el_2_graph(v::Array{String, 1}, el::Array{Int, 2}; directed::Bool = true, label::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  121.     # _v_ is a list of vertex "names"
  122.     # _el_ is an integer only edgelist    
  123.     if any(el .> length(v))
  124.         error("The number of indexes referenced in 'el' exceeds the number of vertices provided.")
  125.     end
  126.     eldim = size(el)
  127.     newel = Array(String, eldim[1], eldim[2])
  128.     for i = 1:eldim[1]
  129.         newel[i,:] = [v[el[i, 1]], v[el[i, 2]]]
  130.     end
  131.  
  132.     return el_2_graph(v, newel, directed = directed, label = label, vtype = vtype, etype = etype)
  133. end
  134.  
  135. function el_2_graph(v::Array{UTF8String, 1}, el::Array{UTF8String, 2}; directed::Bool = true, label::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  136.     v = convert(Array{String, 1}, v)
  137.     el = convert(Array{String, 2}, el)
  138.     return el_2_graph(v, el, directed = directed, label = label, vtype = vtype, etype = etype)
  139. end
  140.  
  141. function el_2_graph(el::Array{UTF8String, 2}; directed::Bool = true, label::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  142.     el = convert(Array{String, 2}, el)
  143.     return el_2_graph(el, directed = directed, label = label, vtype = vtype, etype = etype)
  144. end
  145.  
  146. function el_2_graph(v::Array{UTF8String, 1}, el::Array{Int, 2}; directed::Bool = true, label::Bool = true, vtype::DataType = KeyVertex, etype::DataType = Edge)
  147.     v = convert(Array{String, 1}, v)
  148.     return el_2_graph(v, el, directed = directed, label = label, vtype = vtype, etype = etype)
  149. end
  150.  
  151.  
  152. ### graph_2_el takes a GenericGraph and returns a two-column edgelist.
  153.  
  154. function graph_2_el(g::GenericGraph, label::Bool = true)
  155.     if in(:key, names(g.vertices[1]))
  156.         vtype = KeyVertex
  157.     elseif in(:label, names(g.vertices[1]))
  158.         vtype = ExVertex
  159.     else
  160.         vtype = Int
  161.         label = false
  162.     end
  163.     ne = num_edges(g)
  164.     nv = num_vertices(g)
  165.     alledges = edges(g)
  166.     allsamekeytype = true
  167.     if vtype == KeyVertex
  168.         if nv > 1
  169.             firstkey = typeof(g.vertices[1].key)
  170.             vcounter = 2
  171.             while (vcounter <= nv) & allsamekeytype
  172.                 if typeof(g.vertices[vcounter].key) != firstkey
  173.                     allsamekeytype = false
  174.                 end
  175.                 vcounter += 1
  176.             end
  177.         end
  178.     end
  179.     if label & (vtype == KeyVertex) & allsamekeytype
  180.         el = Array(typeof(g.vertices[1].key), ne, 2)
  181.         for i = 1:num_edges(g)
  182.             el[i, 1] = source(alledges[i], g).key
  183.             el[i, 2] = target(alledges[i], g).key
  184.         end
  185.     elseif label & (vtype == ExVertex)
  186.         el = Array(typeof(g.vertices[1].label), ne, 2)
  187.         for i = 1:num_edges(g)
  188.             el[i, 1] = source(alledges[i], g).label
  189.             el[i, 2] = target(alledges[i], g).label
  190.         end
  191.     else
  192.         el = Array(Int, ne, 2)
  193.         for i = 1:num_edges(g)
  194.             el[i, 1] = source(alledges[i], g).index
  195.             el[i, 2] = target(alledges[i], g).index
  196.         end
  197.     end
  198.     return el
  199. end
  200.  
  201. ### These next four functions convert the vertex and edge types.
  202.  
  203. function keyvertex_2_exvertex(g::GenericGraph)
  204.     if in(:key, names(g.vertices[1])) == false
  205.         error("GenericGraph 'g' must have vertices of type KeyVertex.")
  206.     end
  207.     nv, ne = num_vertices(g), num_edges(g)
  208.     vlist = Array(ExVertex, nv)
  209.     for i = 1:nv
  210.         vlist[i] = ExVertex(g.vertices[i].index, string(g.vertices[i].key))
  211.     end    
  212.     etype = ifelse(in(:attributes, names(g.edges[1])), ExEdge, Edge)        
  213.     elist = Array(etype{typeof(vlist[1])}, ne)
  214.     for i = 1:ne
  215.         elist[i] = etype(i, vlist[g.edges[i].source.index], vlist[g.edges[i].target.index])
  216.     end
  217.     return graph(vlist, elist, is_directed = g.is_directed)
  218. end
  219.  
  220. function exvertex_2_keyvertex(g::GenericGraph)
  221.     if in(:label, names(g.vertices[1])) == false
  222.         error("GenericGraph 'g' must have vertices of type ExVertex.")
  223.     end    
  224.     nv, ne = num_vertices(g), num_edges(g)
  225.     vlist = Array(KeyVertex, nv)
  226.     for i = 1:nv
  227.         vlist[i] = KeyVertex(g.vertices[i].index, g.vertices[i].label)
  228.     end
  229.     etype = ifelse(in(:attributes, names(g.edges[1])), ExEdge, Edge)
  230.     elist = Array(etype{typeof(vlist[1])}, ne)
  231.     for i = 1:ne
  232.         elist[i] = etype(i, vlist[g.edges[i].source.index], vlist[g.edges[i].target.index])
  233.     end
  234.     return graph(vlist, elist, is_directed = g.is_directed)
  235. end
  236.  
  237. function edge_2_exedge(g::GenericGraph)
  238.     vlist = g.vertices
  239.     ne = num_edges(g)
  240.     elist = Array(ExEdge{typeof(vlist[1])}, ne)
  241.     for i = 1:ne
  242.         elist[i] = ExEdge(i, vlist[g.edges[i].source.index], vlist[g.edges[i].target.index])
  243.     end
  244.     return graph(vlist, elist, is_directed = g.is_directed)
  245. end
  246.  
  247. function exedge_2_edge(g::GenericGraph)
  248.     vlist = g.vertices
  249.     ne = num_edges(g)
  250.     elist = Array(Edge{typeof(vlist[1])}, ne)
  251.     for i = 1:ne
  252.         elist[i] = Edge(i, vlist[g.edges[i].source.index], vlist[g.edges[i].target.index])
  253.     end
  254.     return graph(vlist, elist, is_directed = g.is_directed)
  255. end
  256.  
  257. #####
  258. ### These following two functions create subgraphs.
  259. ###     The first creates subgraphs by vertex index.
  260. ###     The second creates subgraphs by edge index.
  261. #####
  262.  
  263. function subgraph_vertices(g::GenericGraph, vind::Array{Int, 1})
  264.     if num_vertices(g) == 0
  265.         error("The number of vertices in 'g' equals zero. Cannot base new graph off of it.")
  266.     end
  267.     newg = deepcopy(g)
  268.     vlist = deepcopy(vertices(newg)[vind])
  269.     for i = 1:length(vlist)
  270.         newvert = vlist[i]
  271.         setfield!(newvert, :index, i)
  272.         vlist[i] = newvert
  273.     end
  274.     oldedges = deepcopy(edges(newg))
  275.     elist = typeof(oldedges[1])[]
  276.     nedges = num_edges(newg)
  277.     ecount = 1
  278.     if nedges > 0
  279.         for i = 1:nedges
  280.             sourceinsubgraph = in(vertex_index(source(oldedges[i])), vind)
  281.             targetinsubgraph = in(vertex_index(target(oldedges[i])), vind)
  282.             if sourceinsubgraph & targetinsubgraph
  283.                 sv = vlist[find(vertex_index(source(oldedges[i])) .== vind)[1]]
  284.                 tv = vlist[find(vertex_index(target(oldedges[i])) .== vind)[1]]
  285.                 newedge = typeof(oldedges[i])(ecount, sv, tv)
  286.                 push!(elist, newedge)
  287.                 ecount += 1
  288.             end
  289.         end
  290.     end
  291.     newg = graph(vlist, elist, is_directed = is_directed(g))
  292.     return newg
  293. end
  294.  
  295. function subgraph_edges(g::GenericGraph, eind::Array{Int, 1})
  296.     ne = num_edges(g)
  297.     if ne == 0
  298.         error("The number of edges in 'g' equals zero. Cannot base new graph off of it.")
  299.     end
  300.     newg = deepcopy(g)
  301.     elist = deepcopy(edges(newg)[eind])
  302.     ne = length(elist)
  303.  
  304.     sources = Array(typeof(vertex_index(source(elist[1]))), ne)
  305.     targets = Array(typeof(vertex_index(target(elist[1]))), ne)
  306.     for i = 1:ne
  307.         sources[i] = vertex_index(source(elist[i]))
  308.         targets[i] = vertex_index(target(elist[i]))
  309.     end    
  310.     vind = unique([sources, targets])
  311.     vlist = deepcopy(vertices(newg)[vind])
  312.     for i = 1:length(vlist)
  313.         newvert = vlist[i]
  314.         setfield!(newvert, :index, i)
  315.         vlist[i] = newvert
  316.     end
  317.     for i = 1:ne
  318.         sv = vlist[find(vertex_index(source(elist[i])) .== vind)[1]]
  319.         tv = vlist[find(vertex_index(target(elist[i])) .== vind)[1]]
  320.         newedge = typeof(elist[i])(i, sv, tv)
  321.         elist[i] = newedge
  322.     end
  323.     newg = graph(vlist, elist, is_directed = is_directed(g))
  324.     return newg    
  325. end
  326.  
  327. #####
  328. ###  Attribute methods
  329. ###      Vertex and edge attributes
  330. ###      Both sets of attributes have set, get, list, and remove functions
  331. ###      The indexes can be specified, though if left empty they default to all vertices or edges
  332. ###  Problems
  333. ###      Setting attvalue as type Array{Any, 1} in the functions produce methods errors; I've left it out
  334. ###      The set and remove functions could/should be made mutable.
  335. #####
  336.  
  337. ### Vertex attribute functions
  338.  
  339. function set_vertex_attribute(g::GenericGraph, attname::String, attvalue, vertexind::Array{Int, 1})
  340.     if in(:label, names(g.vertices[vertexind[1]])) == false
  341.         warn("GenericGraph 'g' has vertices of type ExVertex. Converting them to ExVertex now.")
  342.         g = keyvertex_2_exvertex(g)
  343.     end
  344.     if length(attvalue) != length(vertexind)
  345.         error("Length of 'attvalue' does not equal the length of 'vertexind'.")
  346.     end
  347.     for i = 1:length(vertexind)
  348.         g.vertices[vertexind[i]].attributes[attname] = attvalue[i]
  349.     end
  350.     return g
  351. end
  352.  
  353. function set_vertex_attribute(g::GenericGraph, attname::String, attvalue)
  354.     vertexind = [1:num_vertices(g)]
  355.     return set_vertex_attribute(g, attname, attvalue, vertexind)
  356. end
  357.  
  358. function set_vertex_attribute(g::GenericGraph, attname::String, attvalue, vertexind::Int)
  359.     vertexind = [vertexind]
  360.     attvalue = [attvalue]
  361.     return set_vertex_attribute(g, attname, attvalue, vertexind)
  362. end
  363.  
  364. function set_vertex_attribute(g::GenericGraph, attname::String, attvalue, vertexind::UnitRange{Int})
  365.     vertexind = [vertexind]
  366.     return set_vertex_attribute(g, attname, attvalue, vertexind)
  367. end
  368.  
  369. function get_vertex_attribute(g::GenericGraph, attname::String, vertexind::Array{Int, 1})
  370.     if in(:label, names(g.vertices[vertexind[1]])) == false
  371.         error("Vertices in GenericGraph 'g' are not of type ExVertex.")
  372.     end
  373.     if in(attname, collect(keys(g.vertices[vertexind[1]].attributes))) == false
  374.         error("Attribute '$attname' not found.")
  375.     end
  376.     nind = length(vertexind)
  377.     retvec = Array(typeof(g.vertices[vertexind[1]].attributes[attname]), nind)
  378.     for i = 1:nind
  379.         retvec[i] = g.vertices[vertexind[i]].attributes[attname]
  380.      end
  381.      return retvec
  382. end
  383.  
  384. function get_vertex_attribute(g::GenericGraph, attname::String)
  385.     vertexind = [1:num_vertices(g)]
  386.     return get_vertex_attribute(g, attname, vertexind)
  387. end
  388.  
  389. function get_vertex_attribute(g::GenericGraph, attname::String, vertexind::UnitRange{Int})
  390.     vertexind = [vertexind]
  391.     return get_vertex_attribute(g, attname, vertexind)
  392. end
  393.  
  394. function get_vertex_attribute(g::GenericGraph, attname::String, vertexind::Int)
  395.     vertexind = [vertexind]
  396.     return get_vertex_attribute(g, attname, vertexind)[1]
  397. end
  398.  
  399. function list_vertex_attributes(g::GenericGraph)
  400.     if in(:label, names(g.vertices[1])) == false
  401.         error("Vertices in GenericGraph 'g' are not of type ExVertex.")
  402.     end
  403.     retvec = UTF8String[]
  404.     for i = 1:length(g.vertices)
  405.         attkeys = collect(keys(g.vertices[i].attributes))
  406.         nattkeys = length(attkeys)
  407.         if nattkeys > 0
  408.             for j = 1:nattkeys
  409.                 push!(retvec, attkeys[j])
  410.             end      
  411.         end
  412.      end
  413.      retvec = sort(unique(retvec))
  414.      return retvec
  415. end
  416.  
  417. function remove_vertex_attributes(g::GenericGraph, attname::String, vertexind::Array{Int, 1})
  418.     if in(:label, names(g.vertices[vertexind[1]])) == false
  419.         error("Vertices in GenericGraph 'g' are not of type ExVertex.")
  420.     end
  421.     for i = vertexind
  422.         attkeys = collect(keys(g.vertices[i].attributes))
  423.         if in(attname, attkeys)
  424.             tempvertex = ExVertex(g.vertices[i].index, g.vertices[i].label)
  425.             for j = 1:length(attkeys)
  426.                 if attkeys[j] != attname
  427.                     tempvertex.attributes[attkeys[j]] = g.vertices[i].attributes[attkeys[j]]
  428.                 end
  429.             end
  430.             g.vertices[i] = tempvertex
  431.         else
  432.             warn("Attribute '$attname' is not an attribute at vertex index $i of graph 'g'.")
  433.         end
  434.      end
  435.     return g
  436. end
  437.  
  438. function remove_vertex_attributes(g::GenericGraph, attname::String)
  439.     vertexind = [1:num_vertices(g)]
  440.     return remove_vertex_attributes(g, attname, vertexind)
  441. end
  442.  
  443. function remove_vertex_attributes(g::GenericGraph, attname::String, vertexind::Int)
  444.     vertexind = [vertexind]
  445.     return remove_vertex_attributes(g, attname, vertexind)
  446. end
  447.  
  448. function remove_vertex_attributes(g::GenericGraph, attname::String, vertexind::UnitRange{Int})
  449.     vertexind = [vertexind]
  450.     return remove_vertex_attributes(g, attname, vertexind)
  451. end
  452.  
  453. ### Edge attribute functions
  454.  
  455. function set_edge_attribute(g::GenericGraph, attname::String, attvalue, edgeind::Array{Int, 1})
  456.     if in(:attributes, names(g.edges[edgeind[1]])) == false
  457.         warn("Edges in GenericGraph 'g' are not of type ExEdge. Converting them to ExEdge now.")
  458.         g = edge_2_exedge(g)
  459.     end
  460.     if length(attvalue) != length(edgeind)
  461.         error("Length of 'attvalue' does not equal the length of 'edgeind'.")
  462.     end
  463.     for i = 1:length(edgeind)
  464.         g.edges[edgeind[i]].attributes[attname] = attvalue[i]
  465.     end
  466.     return g
  467. end
  468.  
  469. function set_edge_attribute(g::GenericGraph, attname::String, attvalue)
  470.     edgeind = [1:num_edges(g)]
  471.     return set_edge_attribute(g, attname, attvalue, edgeind)
  472. end
  473.  
  474. function set_edge_attribute(g::GenericGraph, attname::String, attvalue, edgeind::Int)
  475.     attvalue = [attvalue]
  476.     edgeind = [edgeind]
  477.     return set_edge_attribute(g, attname, attvalue, edgeind)
  478. end
  479.  
  480. function set_edge_attribute(g::GenericGraph, attname::String, attvalue, edgeind::UnitRange{Int})
  481.     edgeind = [edgeind]
  482.     return set_edge_attribute(g, attname, attvalue, edgeind)
  483. end
  484.  
  485. function get_edge_attribute(g::GenericGraph, attname::String, edgeind::Array{Int, 1})
  486.     if in(:attributes, names(g.edges[edgeind[1]])) == false
  487.         error("Edges in GenericGraph 'g' are not of type ExEdge.")
  488.     end
  489.     if in(attname, collect(keys(g.edges[edgeind[1]].attributes))) == false
  490.         error("Attribute '$attname' not found.")
  491.     end
  492.     ninds = length(edgeind)
  493.     retvec = Array(typeof(g.edges[edgeind[1]].attributes[attname]), ninds)
  494.     for i = 1:ninds
  495.         retvec[i] = g.edges[edgeind[i]].attributes[attname]
  496.     end
  497.     return retvec
  498. end
  499.  
  500. function get_edge_attribute(g::GenericGraph, attname::String)
  501.     edgeind = [1:num_edges(g)]
  502.     return get_edge_attribute(g, attname, edgeind)
  503. end
  504.  
  505. function get_edge_attribute(g::GenericGraph, attname::String, edgeind::UnitRange{Int})
  506.     edgeind = [edgeind]    
  507.     return get_edge_attribute(g, attname, edgeind)
  508. end
  509.  
  510. function get_edge_attribute(g::GenericGraph, attname::String, edgeind::Int)
  511.     edgeind = [edgeind]
  512.     return get_edge_attribute(g, attname, edgeind)[1]
  513. end
  514.  
  515. function list_edge_attributes(g::GenericGraph)
  516.     if in(:attributes, names(g.edges[1])) == false
  517.         error("Edges in GenericGraph 'g' are not of type ExEdge.")
  518.     end
  519.    retvec = UTF8String[]
  520.    for i = 1:length(g.edges)
  521.        attkeys = collect(keys(g.edges[i].attributes))
  522.        nattkeys = length(attkeys)
  523.        if nattkeys > 0
  524.            for j = 1:nattkeys
  525.                push!(retvec, attkeys[j])
  526.            end      
  527.        end
  528.     end
  529.     retvec = sort(unique(retvec))
  530.     return retvec
  531. end
  532.  
  533. function remove_edge_attributes(g::GenericGraph, attname::String, edgeind::Array{Int, 1})
  534.     if in(:attributes, names(g.edges[edgeind[1]])) == false
  535.         error("Edges in GenericGraph 'g' are not of type ExEdge.")
  536.     end
  537.     for i = edgeind
  538.         attkeys = collect(keys(g.edges[i].attributes))
  539.         if in(attname, attkeys)
  540.             tempedge = ExEdge(g.edges[i].index, g.vertices[g.edges[i].source.index], g.vertices[g.edges[i].target.index])
  541.             for j = 1:length(attkeys)
  542.                 if attkeys[j] != attname
  543.                     tempedge.attributes[attkeys[j]] = g.edges[i].attributes[attkeys[j]]
  544.                 end
  545.             end
  546.             g.edges[i] = tempedge
  547.         else
  548.             warn("Attribute '$attname' is not an attribute at edge index $i of graph 'g'.")
  549.         end
  550.      end
  551.     return g
  552. end
  553.  
  554. function remove_edge_attributes(g::GenericGraph, attname::String)
  555.     edgeind = [1:num_edges(g)]
  556.     return remove_edge_attributes(g, attname, edgeind)
  557. end
  558.  
  559. function remove_edge_attributes(g::GenericGraph, attname::String, edgeind::Int)
  560.     edgeind = [edgeind]
  561.     return remove_edge_attributes(g, attname, edgeind)
  562. end
  563.  
  564. function remove_edge_attributes(g::GenericGraph, attname::String, edgeind::UnitRange{Int})
  565.     edgeind = [edgeind]
  566.     return remove_edge_attributes(g, attname, edgeind)
  567. end
  568.  
  569. #####
  570. ### Loop identification functions
  571. #####
  572.  
  573. function is_loop(g::GenericGraph)
  574.     ne = num_edges(g)
  575.     loopbool = Array(Bool, ne)
  576.     for i = 1:ne
  577.         loopbool[i] = g.edges[i].source.index == g.edges[i].target.index
  578.     end    
  579.     return loopbool
  580. end
  581.  
  582. function is_loop(g::GenericGraph, eind::Int)
  583.     loopbool = g.edges[eind].source.index == g.edges[eind].target.index
  584.     return loopbool
  585. end
  586.  
  587. function is_loop(g::GenericGraph, eind::Array{Int, 1})
  588.     nindlen = length(eind)
  589.     loopbool = Array(Bool, nindlen)
  590.     for i = 1:nindlen
  591.         loopbool[i] = g.edges[eind[i]].source.index == g.edges[eind[i]].target.index
  592.     end
  593.     return loopbool
  594. end
  595.  
  596. function has_loop(g::GenericGraph)
  597.     return any(is_loop(g))
  598. end
  599.  
  600. #####
  601. ### Multiple edge identification function
  602. #####
  603.  
  604. function has_multiple(g::GenericGraph)
  605.     ne = num_edges(g)
  606.     el = Array((Int, Int), ne)
  607.     if is_directed(g)
  608.          for i = 1:ne
  609.             testedge = edges(g)[i]
  610.             sv = vertex_index(source(testedge))
  611.             tv = vertex_index(target(testedge))
  612.             el[i] = (sv, tv)
  613.         end
  614.     else
  615.         for i = 1:ne
  616.             testedge = edges(g)[i]
  617.             sv = vertex_index(source(testedge))
  618.             tv = vertex_index(target(testedge))
  619.             if sv < tv # Ensures consistent ordering
  620.                 el[i] = (sv, tv)
  621.             else
  622.                 el[i] = (tv, sv)
  623.             end
  624.         end
  625.     end
  626.     return length(el) > length(unique(el))
  627. end
  628.  
  629. #####
  630. ### Dyad census
  631. #####
  632.  
  633. function dyad_census(g::GenericGraph) # About 10x slower than the version imported from igraph on the Coleman data.
  634.     nv = num_vertices(g)
  635.     ne = num_edges(g)
  636.     if g.is_directed == false
  637.         npossible = nv * (nv - 1) / 2
  638.         npossible = convert(Int, npossible)
  639.         warn("You are conducting a dyad census on a directed graph. No asymmetric dyads are possible.")
  640.         return (nv, 0, npossible - nobs)
  641.  
  642.     else
  643.         el1 = Array((Int, Int), ne)
  644.         el2 = Array((Int, Int), ne)
  645.         for i = 1:ne
  646.             el1[i] = (g.edges[i].source.index, g.edges[i].target.index)
  647.             el2[i] = (g.edges[i].target.index, g.edges[i].source.index)
  648.         end
  649.         dc = ["Mut" => 0, "Asym" => 0, "Null" => 0]
  650.         isrecip = Array(Bool, ne)
  651.         for i = 1:ne
  652.             if in(el1[i], el2)
  653.                 dc["Mut"] +=1
  654.             end
  655.         end
  656.         dc["Asym"] = ne - dc["Mut"]
  657.         dc["Mut"] = int(dc["Mut"] / 2)
  658.         dc["Null"] = int((nv * (nv - 1) / 2) - (dc["Mut"] + dc["Asym"]))
  659.         return dc
  660.     end
  661. end
  662.  
  663. function reciprocity(g::GenericGraph; ignoreloops::Bool = true, mode::String = "default")
  664.     if g.is_directed == false
  665.         warn("You know that g is undirected, right? Of course its reciprocity will equal 1.0.")
  666.         return(1.0)
  667.     else
  668.         acceptablemodes = ["default", "ratio", "edgewise", "dyadic", "dyadic, non-null", "dyadic.nonnull", "dyadicnonnull", "edgewise.lrr", "edgewise log ratio reciprocity", "edgewiselrr"]
  669.         if !in(mode, acceptablemodes)
  670.             error("mode must be in $acceptablemodes")
  671.         end
  672.         dc = dyad_census(g)
  673.         nv = num_vertices(g)
  674.         ne = num_edges(g)
  675.         if (ignoreloops == false) & (mode != "dyadic")
  676.             warn("Sorry, but loop handling is implemented only in the 'dyadic' mode. Ignoring loops...")
  677.         end
  678.         if in(mode, ["default", "edgewise"]) # 2 * Mut / (Asym + 2 * Mut)
  679.             grecip = 2 * dc["Mut"] / (dc["Asym"] + (2 * dc["Mut"])) # I don't know how to measure it with loops
  680.         elseif in(mode, ["ratio", "dyadic, non-null", "dyadic.nonnull", "dyadicnonnull"]) # Mut / (Asym + Mut)
  681.             grecip = dc["Mut"] / (dc["Mut"] + dc["Asym"])
  682.         elseif in(mode, ["edgewise.lrr", "edgewise log ratio reciprocity", "edgewiselrr"])
  683.             ewr = 2 * dc["Mut"] / (dc["Asym"] + (2 * dc["Mut"]))
  684.             den = ne / (nv * (nv -1))
  685.             grecip = log(ewr / den)
  686.         else #Dyadic
  687.             if ignoreloops
  688.                 grecip = (dc["Mutual"] + dc["Null"]) / (dc["Mutual"] + dc["Asym"] + dc["Null"])
  689.             else #I think I'm doing the loops right here, but not 100%.
  690.                 nloops = sum(is_loop(g))
  691.                 grecip = (dc["Mutual"] + dc["Null"] + nloops) / (dc["Mutual"] + dc["Asym"] + dc["Null"] + nv)
  692.             end
  693.         end        
  694.         return grecip
  695.     end
  696. end
RAW Paste Data
Pastebin PRO Summer Special!
Get 40% OFF on Pastebin PRO accounts!
Top